summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Artiukhin <bahusdrive@gmail.com>2024-01-03 17:30:18 +0200
committerSolomon Peachy <pizza@shaftnet.org>2024-01-21 20:08:04 -0500
commitd50470bc7db942105c3bd774ea08a836b842d58c (patch)
tree5c5daf1d1f6222955ebc4751a1f41bbbd61e215e
parentfd12225861ec6fe810ebbfb7c669635e60ecbfc8 (diff)
downloadrockbox-d50470bc7db942105c3bd774ea08a836b842d58c.tar.gz
rockbox-d50470bc7db942105c3bd774ea08a836b842d58c.zip
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
-rw-r--r--lib/rbcodec/codecs/libfaad/decoder.c6
-rw-r--r--lib/rbcodec/metadata/aac.c50
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,
247 if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL)) 247 if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL))
248 return -1; 248 return -1;
249 249
250 adts.old_format = hDecoder->config.useOldADTSFormat;
250 hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate); 251 hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate);
251 hDecoder->object_type = hDecoder->config.defObjectType; 252 hDecoder->object_type = hDecoder->config.defObjectType;
252 *samplerate = get_sample_rate(hDecoder->sf_index); 253 *samplerate = get_sample_rate(hDecoder->sf_index);
@@ -277,12 +278,9 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
277 bits = bit2byte(faad_get_processed_bits(&ld)); 278 bits = bit2byte(faad_get_processed_bits(&ld));
278 279
279 /* Check if an ADTS header is present */ 280 /* Check if an ADTS header is present */
280 } else if (faad_showbits(&ld, 12) == 0xfff) { 281 } else if (adts_frame(&adts, &ld) == 0) {
281 hDecoder->adts_header_present = 1; 282 hDecoder->adts_header_present = 1;
282 283
283 adts.old_format = hDecoder->config.useOldADTSFormat;
284 adts_frame(&adts, &ld);
285
286 hDecoder->sf_index = adts.sf_index; 284 hDecoder->sf_index = adts.sf_index;
287 hDecoder->object_type = adts.profile + 1; 285 hDecoder->object_type = adts.profile + 1;
288 286
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)
47 return (syncword & 0xFFF6) == 0xFFF0; 47 return (syncword & 0xFFF6) == 0xFFF0;
48} 48}
49 49
50static bool find_adts_keyword(int fd, struct mp3entry *entry)
51{
52 /* logic is copied from adts_fixed_header libfaad/syntax.c:
53 * try to recover from sync errors */
54 for (int i = 0; i < 768; ++i)
55 {
56 if (-1 == lseek(fd, entry->first_frame_offset + i, SEEK_SET))
57 return false;
58
59 if (check_adts_syncword(fd))
60 {
61 return true;
62 }
63 }
64
65 return false;
66}
67
50bool get_aac_metadata(int fd, struct mp3entry *entry) 68bool get_aac_metadata(int fd, struct mp3entry *entry)
51{ 69{
52 unsigned char buf[5]; 70 unsigned char buf[5];
@@ -65,8 +83,21 @@ bool get_aac_metadata(int fd, struct mp3entry *entry)
65 83
66 if (-1 == lseek(fd, entry->first_frame_offset, SEEK_SET)) 84 if (-1 == lseek(fd, entry->first_frame_offset, SEEK_SET))
67 return false; 85 return false;
86 if (read(fd, buf, 5) != 5)
87 return false;
88 if (!memcmp(buf, "ADIF", 4))
89 {
90 if (-1 == lseek(fd, (buf[4] & 0x80) ? (entry->first_frame_offset + 9) : entry->first_frame_offset, SEEK_SET))
91 return false;
68 92
69 if (check_adts_syncword(fd)) 93 uint32_t bitrate;
94 read_uint32be(fd, &bitrate);
95 entry->vbr = (bitrate & 0x10000000) != 0;
96 entry->bitrate = ((bitrate & 0xFFFFFE0) + 16000) / 32000;
97 read_uint32be(fd, (uint32_t*)(&(entry->frequency)));
98 entry->frequency = sample_rates[(entry->frequency >> (entry->vbr ? 23 : 3)) & 0x0F];
99 }
100 else if (find_adts_keyword(fd, entry))
70 { 101 {
71 int frames; 102 int frames;
72 int stat_length; 103 int stat_length;
@@ -101,23 +132,6 @@ bool get_aac_metadata(int fd, struct mp3entry *entry)
101 } 132 }
102#endif 133#endif
103 } 134 }
104 else
105 {
106 uint32_t bitrate;
107 if (-1 == lseek(fd, entry->first_frame_offset, SEEK_SET))
108 return false;
109 if (read(fd, buf, 5) != 5)
110 return false;
111 if (memcmp(buf, "ADIF", 4))
112 return false;
113 if (-1 == lseek(fd, (buf[4] & 0x80) ? (entry->first_frame_offset + 9) : entry->first_frame_offset, SEEK_SET))
114 return false;
115 read_uint32be(fd, &bitrate);
116 entry->vbr = (bitrate & 0x10000000) != 0;
117 entry->bitrate = ((bitrate & 0xFFFFFE0) + 16000) / 32000;
118 read_uint32be(fd, (uint32_t*)(&(entry->frequency)));
119 entry->frequency = sample_rates[(entry->frequency >> (entry->vbr ? 23 : 3)) & 0x0F];
120 }
121 entry->length = (unsigned long)((entry->filesize * 8LL + (entry->bitrate >> 1)) / entry->bitrate); 135 entry->length = (unsigned long)((entry->filesize * 8LL + (entry->bitrate >> 1)) / entry->bitrate);
122 136
123 return true; 137 return true;