diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2021-06-16 16:46:14 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2021-06-16 16:58:47 -0400 |
commit | fa9ddd5af9e48c892ed3a76c3e78abfea6e78110 (patch) | |
tree | 9b2ce2e5be2296a70df89cf34dcf992ed18499ee | |
parent | 7aade87863329dd486f092a96aef5add1c3cd5a0 (diff) | |
download | rockbox-fa9ddd5af9e48c892ed3a76c3e78abfea6e78110.tar.gz rockbox-fa9ddd5af9e48c892ed3a76c3e78abfea6e78110.zip |
Revert "FS#13299: Simplify VBR frame parsing in the metadata decoder."
This reverts commit 756c0d2ac82515ea8389c69f5f87ca395daca63d.
Change-Id: I5f98972f69e7645239fd9218c9d4eeb9bd2ec7a5
-rw-r--r-- | lib/rbcodec/metadata/mp3data.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/lib/rbcodec/metadata/mp3data.c b/lib/rbcodec/metadata/mp3data.c index 8c800c798a..83605126d6 100644 --- a/lib/rbcodec/metadata/mp3data.c +++ b/lib/rbcodec/metadata/mp3data.c | |||
@@ -212,18 +212,27 @@ static bool headers_have_same_type(unsigned long header1, | |||
212 | return header1 ? (header1 == header2) : true; | 212 | return header1 ? (header1 == header2) : true; |
213 | } | 213 | } |
214 | 214 | ||
215 | /* Helper function to read 4-byte in big endian format. */ | ||
216 | static void read_uint32be_mp3data(int fd, unsigned long *data) | ||
217 | { | ||
218 | #ifdef ROCKBOX_BIG_ENDIAN | ||
219 | (void)read(fd, (char*)data, 4); | ||
220 | #else | ||
221 | (void)read(fd, (char*)data, 4); | ||
222 | *data = betoh32(*data); | ||
223 | #endif | ||
224 | } | ||
225 | |||
215 | static unsigned long __find_next_frame(int fd, long *offset, long max_offset, | 226 | static unsigned long __find_next_frame(int fd, long *offset, long max_offset, |
216 | unsigned long reference_header, | 227 | unsigned long reference_header, |
217 | int(*getfunc)(int fd, unsigned char *c), | 228 | int(*getfunc)(int fd, unsigned char *c), |
218 | bool single_header) | 229 | bool single_header) |
219 | { | 230 | { |
220 | uint32_t header=0; | 231 | unsigned long header=0; |
221 | uint32_t ref_header=0; | ||
222 | long ref_header_pos=0; | ||
223 | unsigned char tmp; | 232 | unsigned char tmp; |
224 | long pos = 0; | 233 | long pos = 0; |
225 | 234 | ||
226 | /* We will search until we find two consecutive MPEG frame headers with | 235 | /* We will search until we find two consecutive MPEG frame headers with |
227 | * the same MPEG version, layer and sampling frequency. The first header | 236 | * the same MPEG version, layer and sampling frequency. The first header |
228 | * of this pair is assumed to be the first valid MPEG frame header of the | 237 | * of this pair is assumed to be the first valid MPEG frame header of the |
229 | * whole stream. */ | 238 | * whole stream. */ |
@@ -234,33 +243,43 @@ static unsigned long __find_next_frame(int fd, long *offset, long max_offset, | |||
234 | return 0; | 243 | return 0; |
235 | header |= tmp; | 244 | header |= tmp; |
236 | pos++; | 245 | pos++; |
237 | 246 | ||
238 | /* Abort if max_offset is reached. Stop parsing. */ | 247 | /* Abort if max_offset is reached. Stop parsing. */ |
239 | if (max_offset > 0 && pos > max_offset) | 248 | if (max_offset > 0 && pos > max_offset) |
240 | return 0; | 249 | return 0; |
241 | 250 | ||
242 | if (is_mp3frameheader(header)) { | 251 | if (is_mp3frameheader(header)) { |
243 | if (single_header) { | 252 | if (single_header) { |
244 | /* We search for one _single_ valid header that has the same | 253 | /* We search for one _single_ valid header that has the same |
245 | * type as the reference_header (if reference_header != 0). | 254 | * type as the reference_header (if reference_header != 0). |
246 | * In this case we are finished. */ | 255 | * In this case we are finished. */ |
247 | if (headers_have_same_type(reference_header, header)) | 256 | if (headers_have_same_type(reference_header, header)) |
248 | break; | 257 | break; |
249 | } else { | 258 | } else { |
250 | /* The current header is valid. Compare it against the last | 259 | /* The current header is valid. Now gather the frame size, |
251 | one we found. NOTE: ref_header MUST come second! */ | 260 | * seek to this byte position and check if there is another |
252 | if (headers_have_same_type(header, ref_header)) { | 261 | * valid MPEG frame header of the same type. */ |
253 | /* Found a match, return the header and offset of the FIRST */ | 262 | struct mp3info info; |
254 | header = ref_header; | 263 | |
255 | lseek(fd, ref_header_pos, SEEK_SET); | 264 | /* Gather frame size from given header and seek to next |
265 | * frame header. */ | ||
266 | mp3headerinfo(&info, header); | ||
267 | lseek(fd, info.frame_size-4, SEEK_CUR); | ||
268 | |||
269 | /* Read possible next frame header and seek back to last frame | ||
270 | * headers byte position. */ | ||
271 | reference_header = 0; | ||
272 | read_uint32be_mp3data(fd, &reference_header); | ||
273 | // | ||
274 | lseek(fd, -info.frame_size, SEEK_CUR); | ||
275 | |||
276 | /* If the current header is of the same type as the previous | ||
277 | * header we are finished. */ | ||
278 | if (headers_have_same_type(header, reference_header)) | ||
256 | break; | 279 | break; |
257 | } | ||
258 | /* Otherwise look for another.. */ | ||
259 | ref_header = header; | ||
260 | ref_header_pos = lseek(fd, 0, SEEK_CUR); | ||
261 | } | 280 | } |
262 | } | 281 | } |
263 | 282 | ||
264 | } while (true); | 283 | } while (true); |
265 | 284 | ||
266 | *offset = pos - 4; | 285 | *offset = pos - 4; |