diff options
author | Roman Artiukhin <bahusdrive@gmail.com> | 2024-01-03 17:30:18 +0200 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2024-01-21 20:08:04 -0500 |
commit | d50470bc7db942105c3bd774ea08a836b842d58c (patch) | |
tree | 5c5daf1d1f6222955ebc4751a1f41bbbd61e215e /lib/rbcodec/metadata | |
parent | fd12225861ec6fe810ebbfb7c669635e60ecbfc8 (diff) | |
download | rockbox-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
Diffstat (limited to 'lib/rbcodec/metadata')
-rw-r--r-- | lib/rbcodec/metadata/aac.c | 50 |
1 files changed, 32 insertions, 18 deletions
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 | ||
50 | static 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 | |||
50 | bool get_aac_metadata(int fd, struct mp3entry *entry) | 68 | bool 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; |