mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Initial ADTS (AAC+) support.
This commit is contained in:
parent
465c68d839
commit
3772b2160c
90
softhddev.c
90
softhddev.c
@ -348,8 +348,8 @@ static int Ac3Check(const uint8_t * data, int size)
|
||||
frmsizcod = data[4] & 0x3F; // invalid is checked by fast
|
||||
frame_size = Ac3FrameSizeTable[frmsizcod][fscod] * 2;
|
||||
|
||||
if (frame_size + 2 > size) {
|
||||
return -frame_size - 2;
|
||||
if (frame_size + 5 > size) {
|
||||
return -frame_size - 5;
|
||||
}
|
||||
// check if after this frame a new AC-3 frame starts
|
||||
if (FastAc3Check(data + frame_size)) {
|
||||
@ -359,6 +359,71 @@ static int Ac3Check(const uint8_t * data, int size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// Fast check for ADTS Audio Data Transport Stream.
|
||||
///
|
||||
/// 7/9 bytes 0xFFFxxxxxxxxxxx(xxxx) ADTS audio
|
||||
///
|
||||
static inline int FastAdtsCheck(const uint8_t * p)
|
||||
{
|
||||
if (p[0] != 0xFF) { // 12bit sync
|
||||
return 0;
|
||||
}
|
||||
if ((p[1] & 0xF6) != 0xF0) { // sync + layer must be 0
|
||||
return 0;
|
||||
}
|
||||
if ((p[2] & 0x3C) == 0x3C) { // sampling frequency index != 15
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
///
|
||||
/// Check for ADTS Audio Data Transport Stream.
|
||||
///
|
||||
/// 0xFFF already checked.
|
||||
///
|
||||
/// @param data incomplete PES packet
|
||||
/// @param size number of bytes
|
||||
///
|
||||
/// @retval <0 possible ADTS audio, but need more data
|
||||
/// @retval 0 no valid ADTS audio
|
||||
/// @retval >0 valid AC-3 audio
|
||||
///
|
||||
/// AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP
|
||||
/// (QQQQQQQQ QQQQQQQ)
|
||||
///
|
||||
/// o A*12 syncword 0xFFF
|
||||
/// o B*1 MPEG Version: 0 for MPEG-4, 1 for MPEG-2
|
||||
/// o C*2 layer: always 0
|
||||
/// o ..
|
||||
/// o F*4 sampling frequency index (15 is invalid)
|
||||
/// o ..
|
||||
/// o M*13 frame length
|
||||
///
|
||||
static int AdtsCheck(const uint8_t * data, int size)
|
||||
{
|
||||
int frame_size;
|
||||
|
||||
if (size < 6) {
|
||||
return -6;
|
||||
}
|
||||
|
||||
frame_size = (data[3] & 0x03) << 11;
|
||||
frame_size |= (data[4] & 0xFF) << 3;
|
||||
frame_size |= (data[5] & 0xE0) >> 5;
|
||||
|
||||
if (frame_size + 3 > size) {
|
||||
return -frame_size - 3;
|
||||
}
|
||||
// check if after this frame a new ADTS frame starts
|
||||
if (FastAdtsCheck(data + frame_size)) {
|
||||
return frame_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_TS_AUDIO
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -541,11 +606,13 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
|
||||
unsigned codec_id;
|
||||
|
||||
// 4 bytes 0xFFExxxxx Mpeg audio
|
||||
// 3 bytes 0x56Exxx AAC LATM audio
|
||||
// 5 bytes 0x0B77xxxxxx AC3 audio
|
||||
// 3 bytes 0x56Exxx AAC LATM audio
|
||||
// 7/9 bytes 0xFFFxxxxxxxxxxx ADTS audio
|
||||
// PCM audio can't be found
|
||||
// FIXME: simple+faster detection, if codec already known
|
||||
r = 0;
|
||||
if (FastMpegCheck(q)) {
|
||||
if (!r && FastMpegCheck(q)) {
|
||||
r = MpegCheck(q, n);
|
||||
codec_id = CODEC_ID_MP2;
|
||||
}
|
||||
@ -557,6 +624,10 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
|
||||
r = LatmCheck(q, n);
|
||||
codec_id = CODEC_ID_AAC_LATM;
|
||||
}
|
||||
if (!r && FastAdtsCheck(q)) {
|
||||
r = AdtsCheck(q, n);
|
||||
codec_id = CODEC_ID_AAC;
|
||||
}
|
||||
if (r < 0) { // need more bytes
|
||||
break;
|
||||
}
|
||||
@ -1042,6 +1113,10 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (id != 0xbd && !r && FastAdtsCheck(p)) {
|
||||
r = AdtsCheck(p, n);
|
||||
codec_id = CODEC_ID_AAC;
|
||||
}
|
||||
if (r < 0) { // need more bytes
|
||||
break;
|
||||
}
|
||||
@ -1857,6 +1932,7 @@ int SetPlayMode(int play_mode)
|
||||
NewVideoStream = 1;
|
||||
// tell hw decoder we are closing stream
|
||||
VideoSetClosing(MyHwDecoder);
|
||||
VideoResetStart(MyHwDecoder);
|
||||
#ifdef DEBUG
|
||||
VideoSwitch = GetMsTicks();
|
||||
#endif
|
||||
@ -1926,16 +2002,20 @@ void Clear(void)
|
||||
int i;
|
||||
|
||||
VideoResetPacket(); // terminate work
|
||||
VideoSetClosing(MyHwDecoder);
|
||||
VideoResetStart(MyHwDecoder);
|
||||
VideoClearBuffers = 1;
|
||||
AudioFlushBuffers();
|
||||
//NewAudioStream = 1;
|
||||
// FIXME: audio avcodec_flush_buffers, video is done by VideoClearBuffers
|
||||
|
||||
// wait for empty buffers
|
||||
// FIXME: without softstart sync VideoDecode isn't called.
|
||||
for (i = 0; VideoClearBuffers && i < 20; ++i) {
|
||||
usleep(1 * 1000);
|
||||
}
|
||||
Debug(3, "[softhddev]%s: buffers %d\n", __FUNCTION__, VideoGetBuffers());
|
||||
Debug(3, "[softhddev]%s: %dms buffers %d\n", __FUNCTION__, i,
|
||||
VideoGetBuffers());
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user