vdr-plugin-softhddevice-drm-gles 1.4.0
codec_audio.cpp
Go to the documentation of this file.
1
25#include <stdint.h>
26#include <stdlib.h>
27#include <stddef.h>
28
29extern "C" {
30#include <libavcodec/avcodec.h>
31}
32
33#include "misc.h"
34
35#include "audio.h"
36#include "codec_audio.h"
37#include "logger.h"
38
39/*****************************************************************************
40 * cAudioDecoder class
41 ****************************************************************************/
42
49{
50 m_pAudio = audio;
51
52 int mask = m_pAudio->GetPassthrough();
53
54 if (!(m_pFrame = av_frame_alloc()))
55 LOGFATAL("audiocodec: %s: can't allocate audio decoder frame buffer", __FUNCTION__);
56
57 m_pAudioCtx = NULL;
59
61 LOGDEBUG2(L_CODEC, "audiocodec: %s: Set passthrough mask %d", __FUNCTION__, m_passthroughMask);
62}
63
68{
69 Close();
70
71 av_frame_free(&m_pFrame);
72}
73
81void cAudioDecoder::Open(AVCodecID codecId, AVCodecParameters *par, AVRational timebase)
82{
83 const AVCodec *codec;
84
85 m_codecId = codecId;
86
87 // FIXME: errors shouldn't be fatal, maybe just disable audio
88 if (codecId == AV_CODEC_ID_AC3) {
89 if (!(codec = avcodec_find_decoder_by_name("ac3_fixed"))) {
90 LOGFATAL("audiocodec: %s: codec ac3_fixed ID %#06x not found", __FUNCTION__, codecId);
91 }
92 } else if (codecId == AV_CODEC_ID_AAC) {
93 if (!(codec = avcodec_find_decoder_by_name("aac_fixed"))) {
94 LOGFATAL("audiocodec: %s: codec aac_fixed ID %#06x not found", __FUNCTION__, codecId);
95 }
96 } else {
97 if (!(codec = avcodec_find_decoder(codecId))) {
98 LOGFATAL("audiocodec: %s: codec %s ID %#06x not found", __FUNCTION__,
99 avcodec_get_name(codecId), codecId);
100 }
101 }
102
103 if (!(m_pAudioCtx = avcodec_alloc_context3(codec)))
104 LOGFATAL("audiocodec: %s: can't allocate audio codec context", __FUNCTION__);
105
106 m_pAudioCtx->pkt_timebase = timebase;
107
108 if (par && ((avcodec_parameters_to_context(m_pAudioCtx, par)) < 0))
109 LOGERROR("audiocodec: %s: insert parameters to context failed!", __FUNCTION__);
110
111 if (avcodec_open2(m_pAudioCtx, m_pAudioCtx->codec, NULL) < 0)
112 LOGFATAL("audiocodec: %s: can't open audio codec", __FUNCTION__);
113
114 LOGDEBUG2(L_CODEC, "audiocodec: %s: Codec %s found, passthrough mask %d", __FUNCTION__, m_pAudioCtx->codec->long_name, m_passthroughMask);
115
121}
122
127{
128 LOGDEBUG2(L_CODEC, "audiocodec: %s", __FUNCTION__);
129 if (m_pAudioCtx)
130 avcodec_free_context(&m_pAudioCtx);
131
132 m_codecId = AV_CODEC_ID_NONE;
134}
135
151int cAudioDecoder::DecodePassthrough(const AVPacket * avpkt, AVFrame *frame)
152{
153 m_pAudio->SetTimebase(&m_pAudioCtx->pkt_timebase);
154
155/* TODO: PCM passthrough, just forward the data?
156 // PCM passthrough
157 if (m_passthroughMask & CODEC_PCM && m_pAudioCtx->codec_id == AV_CODEC_ID_PCM) {
158 m_pAudio->EnqueueSpdif(m_pAudioCtx, avpkt->data, avpkt->size, frame);
159 return 1;
160 }
161*/
162
163 // AC3 passthrough
164 if (m_passthroughMask & CODEC_AC3 && m_pAudioCtx->codec_id == AV_CODEC_ID_AC3) {
165 uint16_t *spdif = m_spdifOutput;
166 int spdifSize = AC3_FRAME_SIZE * 4; // frames * channels * (samplesize / 8)
167
168 if (spdifSize < avpkt->size + 8) {
169 LOGERROR("audiocodec: %s: too much data for spdif buffer!", __FUNCTION__);
170 return -1;
171 }
172
173 // build SPDIF header and append AC3 audio data to it
174 int bitstreamMode = avpkt->data[5] & 0x07;
175 spdif[0] = htole16(IEC61937_PREAMBLE1);
176 spdif[1] = htole16(IEC61937_PREAMBLE2);
177 spdif[2] = htole16(IEC61937_AC3 | bitstreamMode << 8);
178 spdif[3] = htole16(avpkt->size * 8);
179 // TODO: take endian into accout
180 swab(avpkt->data, spdif + 4, avpkt->size);
181 memset(spdif + 4 + avpkt->size / 2, 0, spdifSize - 8 - avpkt->size);
182
183 m_pAudio->Enqueue(spdif, spdifSize, frame);
184 return 1;
185 }
186
187 // EAC3 passthrough
188 if (m_passthroughMask & CODEC_EAC3 && m_pAudioCtx->codec_id == AV_CODEC_ID_EAC3) {
189 uint16_t *spdif = m_spdifOutput;
190 int spdifSize = EAC3_FRAME_SIZE * 4; // frames * channels * (samplesize / 8)
191 int repeat = 1;
192
193 // spdifSize is smaller, if we don't have 192000
194 if (m_currentHwSampleRate == 48000) {
195 spdifSize /= 4;
196 }
197
198 if (spdifSize < m_spdifIndex + avpkt->size + 8) {
199 LOGERROR("audiocodec: %s: too much data for spdif buffer!", __FUNCTION__);
200 return -1;
201 }
202
203 // check if we need to pack multiple packets
204 int fscod = (avpkt->data[4] >> 6) & 0x3;
205 if (fscod != 0x3) {
206 int fscod2 = (avpkt->data[4] >> 4) & 0x3;
207 static const uint8_t eac3_repeat[4] = { 6, 3, 2, 1 };
208 repeat = eac3_repeat[fscod2];
209 }
210
211// LOGDEBUG2(L_CODEC, "audiocodec: %s: E-AC3: set repeat to %d (fscod = %d) avpkt->size %d (spdifSize %d)",
212// __FUNCTION__, repeat, fscod2, avpkt->size, spdifSize);
213
214 // pack upto repeat EAC-3 pakets into one IEC 61937 burst
215 // TODO: take endian into accout
216 swab(avpkt->data, spdif + 4 + m_spdifIndex, avpkt->size);
217 m_spdifIndex += avpkt->size;
218
219 if (++m_spdifRepeatCount < repeat)
220 return 1;
221
222 // build SPDIF header and append E-AC3 audio data to it
223 spdif[0] = htole16(IEC61937_PREAMBLE1);
224 spdif[1] = htole16(IEC61937_PREAMBLE2);
225 spdif[2] = htole16(IEC61937_EAC3);
226 spdif[3] = htole16(m_spdifIndex * 8);
227 memset(spdif + 4 + m_spdifIndex / 2, 0, spdifSize - 8 - m_spdifIndex);
228
229 m_pAudio->Enqueue(spdif, spdifSize, frame);
230 m_spdifIndex = 0;
232 return 1;
233 }
234
235 // DTS passthrough
236 if (m_passthroughMask & CODEC_DTS && m_pAudioCtx->codec_id == AV_CODEC_ID_DTS) {
237 uint16_t *spdif = m_spdifOutput;
238
239 uint8_t nbs;
240 int bsid;
241 int burstSz;
242
243 nbs = (uint8_t)((avpkt->data[4] & 0x01) << 6) |
244 ((avpkt->data[5] >> 2) & 0x3f);
245 switch(nbs) {
246 case 0x07:
247 bsid = 0x0a; // MPEG-2 layer 3 is used when?
248 burstSz = 1024;
249 break;
250 case 0x0f:
251 bsid = IEC61937_DTS1;
252 burstSz = DTS1_FRAME_SIZE * 4; // frames * channels * (samplesize / 8)
253 break;
254 case 0x1f:
255 bsid = IEC61937_DTS2;
256 burstSz = DTS2_FRAME_SIZE * 4; // frames * channels * (samplesize / 8)
257 break;
258 case 0x3f:
259 bsid = IEC61937_DTS3;
260 burstSz = DTS3_FRAME_SIZE * 4; // frames * channels * (samplesize / 8)
261 break;
262 default:
263 bsid = IEC61937_NULL;
264 if (nbs < 5)
265 nbs = 127;
266 burstSz = (nbs + 1) * 32 * 2 + 2;
267 break;
268 }
269
270 // build SPDIF header and append DTS audio data to it
271 if (burstSz < avpkt->size + 8) {
272 LOGERROR("audiocodec: %s: too much data for spdif buffer!", __FUNCTION__);
273 return -1;
274 }
275 spdif[0] = htole16(IEC61937_PREAMBLE1);
276 spdif[1] = htole16(IEC61937_PREAMBLE2);
277 spdif[2] = htole16(bsid);
278 spdif[3] = htole16(avpkt->size * 8);
279 spdif[4] = htole16(DTS_PREAMBLE_16BE_1);
280 spdif[5] = htole16(DTS_PREAMBLE_16BE_2);
281 // TODO: take endian into accout
282 swab(avpkt->data, spdif + 4, avpkt->size);
283 memset(spdif + 4 + avpkt->size, 0, burstSz - 8 - avpkt->size);
284
285 m_pAudio->Enqueue(spdif, burstSz, frame);
286 return 1;
287 }
288
289 return 0;
290}
291
301{
302 int isPassthrough = 0;
303 int err;
304
305 LOGDEBUG2(L_SOUND, "audiocodec: %s: format change %s %dHz *%d channels%s%s%s%s%s%d", __FUNCTION__,
306 av_get_sample_fmt_name(m_pAudioCtx->sample_fmt), m_pAudioCtx->sample_rate, m_pAudioCtx->ch_layout.nb_channels,
307 m_passthroughMask & CODEC_PCM ? " PCM" : "",
308 m_passthroughMask & CODEC_AC3 ? " AC3" : "",
309 m_passthroughMask & CODEC_EAC3 ? " EAC3" : "",
310 m_passthroughMask & CODEC_DTS ? " DTS" : "",
311 m_passthroughMask ? " passthrough mask " : "",
313
314 m_currentSampleRate = m_pAudioCtx->sample_rate;
315 m_currentHwSampleRate = m_pAudioCtx->sample_rate;
316 m_currentNumChannels = m_pAudioCtx->ch_layout.nb_channels;
317 m_currentHwNumChannels = m_pAudioCtx->ch_layout.nb_channels;
319
320 if ((m_currentPassthrough & CODEC_AC3 && m_pAudioCtx->codec_id == AV_CODEC_ID_AC3) ||
321 (m_currentPassthrough & CODEC_EAC3 && m_pAudioCtx->codec_id == AV_CODEC_ID_EAC3) ||
322 (m_currentPassthrough & CODEC_DTS && m_pAudioCtx->codec_id == AV_CODEC_ID_DTS)) {
323
324 // E-AC3 over HDMI: some receivers need HBR
325 if (m_pAudioCtx->codec_id == AV_CODEC_ID_EAC3)
327
329 m_spdifIndex = 0;
331 isPassthrough = 1;
332 }
333
335 // E-AC3 over HDMI: try without HBR
337
338 if (m_pAudioCtx->codec_id != AV_CODEC_ID_EAC3 ||
340
343 LOGERROR("audiocodec: %s: format change update error", __FUNCTION__);
344 return err;
345 }
346 }
347 return 0;
348}
349
355void cAudioDecoder::Decode(const AVPacket * avpkt)
356{
357 int retSend, retRec;
358 AVFrame *frame;
359
360 // decoded frame is also needed for passthrough to set the PTS
361 frame = m_pFrame;
362 av_frame_unref(frame);
363
364 do {
365 retSend = avcodec_send_packet(m_pAudioCtx, avpkt);
366 if (retSend < 0)
367 LOGERROR("audiocodec: %s: avcodec_send_packet error: %s", __FUNCTION__, av_err2str(retSend));
368
369 retRec = avcodec_receive_frame(m_pAudioCtx, frame);
370
371 if (retRec < 0) {
372 if (retRec != AVERROR(EAGAIN))
373 LOGERROR("audiocodec: %s: avcodec_receive_frame error: %s", __FUNCTION__, av_err2str(retRec));
374 } else {
375 if (m_lastPts == AV_NOPTS_VALUE && avpkt->pts == AV_NOPTS_VALUE) {
376 // the first AVPacket has no valid PTS, if its PES packet has been truncated while searching for the sync word
377 av_frame_unref(frame);
378 continue;
379 }
380
381 // update audio clock and remeber last PTS or guess the next PTS
382 if (frame->pts != AV_NOPTS_VALUE) {
383 m_lastPts = frame->pts;
384 } else if (m_lastPts != AV_NOPTS_VALUE) {
385 frame->pts = m_lastPts +
386 (int64_t)(frame->nb_samples / av_q2d(m_pAudioCtx->pkt_timebase) / frame->sample_rate);
387 m_lastPts = frame->pts;
388 }
389
391 m_currentNumChannels != m_pAudioCtx->ch_layout.nb_channels ||
392 m_currentSampleRate != m_pAudioCtx->sample_rate) {
393 UpdateFormat();
394 }
395
397 LOGERROR("audiocodec: %s: unsupported format!", __FUNCTION__);
398 av_frame_unref(frame);
399 return;
400 }
401
402 if (DecodePassthrough(avpkt, frame)) {
403 av_frame_unref(frame);
404 return;
405 }
406
407 m_pAudio->Filter(frame, m_pAudioCtx);
408 }
409
410 } while (retSend == AVERROR(EAGAIN));
411}
412
417{
418 LOGDEBUG2(L_CODEC, "audiocodec: %s", __FUNCTION__);
419 if (m_pAudioCtx)
420 avcodec_flush_buffers(m_pAudioCtx);
421
423 m_codecId = AV_CODEC_ID_NONE;
424}
425
432{
433 LOGDEBUG2(L_CODEC, "audiocodec: %s: %d", __FUNCTION__, mask);
435}
Audio and alsa module header file.
int DecodePassthrough(const AVPacket *, AVFrame *)
Passthrough audio data.
uint16_t m_spdifOutput[MAX_FRAME_SIZE *2]
SPDIF output buffer.
Definition: codec_audio.h:97
int UpdateFormat(void)
Handle audio format changes.
AVCodecContext * m_pAudioCtx
ffmpeg audio codec context
Definition: codec_audio.h:87
virtual ~cAudioDecoder(void)
Audio decoder class destructor.
Definition: codec_audio.cpp:67
int m_currentHwSampleRate
current hw sample rate
Definition: codec_audio.h:95
void FlushBuffers(void)
Flush the audio decoder.
int m_currentHwNumChannels
current number of hw channels
Definition: codec_audio.h:96
void Decode(const AVPacket *)
Decode an audio packet.
AVFrame * m_pFrame
decoded ffmpeg audio frame
Definition: codec_audio.h:89
int m_spdifIndex
index into SPDIF output buffer
Definition: codec_audio.h:98
int m_passthroughMask
passthrough mask to be set
Definition: codec_audio.h:91
AVCodecID m_codecId
current codec id
Definition: codec_audio.h:88
int m_currentPassthrough
current passthrough mask
Definition: codec_audio.h:92
cAudioDecoder(cSoftHdAudio *)
Audio decoder class constructor.
Definition: codec_audio.cpp:48
int m_spdifRepeatCount
SPDIF repeat counter.
Definition: codec_audio.h:99
int64_t m_lastPts
last seen PTS
Definition: codec_audio.h:90
int m_currentSampleRate
current sample rate
Definition: codec_audio.h:93
cSoftHdAudio * m_pAudio
audio module
Definition: codec_audio.h:86
void SetPassthrough(int)
Set audio pass-through mask.
int m_currentNumChannels
current number of channels
Definition: codec_audio.h:94
void Open(AVCodecID, AVCodecParameters *=nullptr, AVRational={ .num=1,.den=90000 })
Open and initiate the audio decoder.
Definition: codec_audio.cpp:81
void Close(void)
Close the audio decoder.
cSoftHdAudio - Audio class
Definition: audio.h:45
void Filter(AVFrame *, AVCodecContext *)
Send audio frame to filter and enqueue it.
Definition: audio.cpp:771
int Setup(AVCodecContext *, int, int, int)
Setup alsa.
Definition: audio.cpp:682
void Enqueue(uint16_t *, int, AVFrame *)
Send audio data to ringbuffer.
Definition: audio.cpp:657
int GetPassthrough(void) const
Definition: audio.h:64
void SetTimebase(AVRational *timebase)
Definition: audio.h:78
Audio decoder header file.
#define IEC61937_PREAMBLE2
Definition: codec_audio.h:53
#define CODEC_PCM
bits used for the passthrough mask
Definition: codec_audio.h:31
#define CODEC_EAC3
E-AC-3 bit mask.
Definition: codec_audio.h:34
@ IEC61937_DTS3
DTS type III (2048 samples)
Definition: codec_audio.h:47
@ IEC61937_DTS2
DTS type II (1024 samples)
Definition: codec_audio.h:46
@ IEC61937_AC3
AC-3 data.
Definition: codec_audio.h:43
@ IEC61937_NULL
no data
Definition: codec_audio.h:42
@ IEC61937_EAC3
E-AC-3 data.
Definition: codec_audio.h:44
@ IEC61937_DTS1
DTS type I (512 samples)
Definition: codec_audio.h:45
#define DTS_PREAMBLE_16BE_1
Definition: codec_audio.h:54
#define DTS_PREAMBLE_16BE_2
Definition: codec_audio.h:55
#define AC3_FRAME_SIZE
Definition: codec_audio.h:63
#define DTS2_FRAME_SIZE
Definition: codec_audio.h:61
#define EAC3_FRAME_SIZE
Definition: codec_audio.h:64
#define DTS3_FRAME_SIZE
Definition: codec_audio.h:62
#define IEC61937_PREAMBLE1
Definition: codec_audio.h:52
#define CODEC_AC3
AC-3 bit mask.
Definition: codec_audio.h:33
#define DTS1_FRAME_SIZE
Codec frame sizes.
Definition: codec_audio.h:60
#define CODEC_DTS
DTS bit mask.
Definition: codec_audio.h:35
Logger class header file.
#define LOGDEBUG2
Definition: logger.h:50
#define LOGERROR
Definition: logger.h:46
#define L_SOUND
Definition: logger.h:60
#define L_CODEC
Definition: logger.h:63
#define LOGFATAL
Logger macros.
Definition: logger.h:45
Misc function header file.
#define AV_NOPTS_VALUE
Definition: misc.h:35