From d50470bc7db942105c3bd774ea08a836b842d58c Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Wed, 3 Jan 2024 17:30:18 +0200 Subject: Codecs: aac: Improve ADTS stream detection Captured ADTS streams might start from some garbage data from previous frame. We should check for sync errors even for first frame. Change-Id: I70171298b79713aeedf9fa2e6098a03063487649 --- lib/rbcodec/codecs/libfaad/decoder.c | 6 ++--- lib/rbcodec/metadata/aac.c | 50 +++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/lib/rbcodec/codecs/libfaad/decoder.c b/lib/rbcodec/codecs/libfaad/decoder.c index d68d093b0b..533de50d5b 100644 --- a/lib/rbcodec/codecs/libfaad/decoder.c +++ b/lib/rbcodec/codecs/libfaad/decoder.c @@ -247,6 +247,7 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer, if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL)) return -1; + adts.old_format = hDecoder->config.useOldADTSFormat; hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate); hDecoder->object_type = hDecoder->config.defObjectType; *samplerate = get_sample_rate(hDecoder->sf_index); @@ -277,12 +278,9 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer, bits = bit2byte(faad_get_processed_bits(&ld)); /* Check if an ADTS header is present */ - } else if (faad_showbits(&ld, 12) == 0xfff) { + } else if (adts_frame(&adts, &ld) == 0) { hDecoder->adts_header_present = 1; - adts.old_format = hDecoder->config.useOldADTSFormat; - adts_frame(&adts, &ld); - hDecoder->sf_index = adts.sf_index; hDecoder->object_type = adts.profile + 1; diff --git a/lib/rbcodec/metadata/aac.c b/lib/rbcodec/metadata/aac.c index 372bab716e..c5467f0422 100644 --- a/lib/rbcodec/metadata/aac.c +++ b/lib/rbcodec/metadata/aac.c @@ -47,6 +47,24 @@ static bool check_adts_syncword(int fd) return (syncword & 0xFFF6) == 0xFFF0; } +static bool find_adts_keyword(int fd, struct mp3entry *entry) +{ + /* logic is copied from adts_fixed_header libfaad/syntax.c: + * try to recover from sync errors */ + for (int i = 0; i < 768; ++i) + { + if (-1 == lseek(fd, entry->first_frame_offset + i, SEEK_SET)) + return false; + + if (check_adts_syncword(fd)) + { + return true; + } + } + + return false; +} + bool get_aac_metadata(int fd, struct mp3entry *entry) { unsigned char buf[5]; @@ -65,8 +83,21 @@ bool get_aac_metadata(int fd, struct mp3entry *entry) if (-1 == lseek(fd, entry->first_frame_offset, SEEK_SET)) return false; + if (read(fd, buf, 5) != 5) + return false; + if (!memcmp(buf, "ADIF", 4)) + { + if (-1 == lseek(fd, (buf[4] & 0x80) ? (entry->first_frame_offset + 9) : entry->first_frame_offset, SEEK_SET)) + return false; - if (check_adts_syncword(fd)) + uint32_t bitrate; + read_uint32be(fd, &bitrate); + entry->vbr = (bitrate & 0x10000000) != 0; + entry->bitrate = ((bitrate & 0xFFFFFE0) + 16000) / 32000; + read_uint32be(fd, (uint32_t*)(&(entry->frequency))); + entry->frequency = sample_rates[(entry->frequency >> (entry->vbr ? 23 : 3)) & 0x0F]; + } + else if (find_adts_keyword(fd, entry)) { int frames; int stat_length; @@ -101,23 +132,6 @@ bool get_aac_metadata(int fd, struct mp3entry *entry) } #endif } - else - { - uint32_t bitrate; - if (-1 == lseek(fd, entry->first_frame_offset, SEEK_SET)) - return false; - if (read(fd, buf, 5) != 5) - return false; - if (memcmp(buf, "ADIF", 4)) - return false; - if (-1 == lseek(fd, (buf[4] & 0x80) ? (entry->first_frame_offset + 9) : entry->first_frame_offset, SEEK_SET)) - return false; - read_uint32be(fd, &bitrate); - entry->vbr = (bitrate & 0x10000000) != 0; - entry->bitrate = ((bitrate & 0xFFFFFE0) + 16000) / 32000; - read_uint32be(fd, (uint32_t*)(&(entry->frequency))); - entry->frequency = sample_rates[(entry->frequency >> (entry->vbr ? 23 : 3)) & 0x0F]; - } entry->length = (unsigned long)((entry->filesize * 8LL + (entry->bitrate >> 1)) / entry->bitrate); return true; -- cgit v1.2.3