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