diff options
Diffstat (limited to 'lib/rbcodec/metadata/mp3data.c')
-rw-r--r-- | lib/rbcodec/metadata/mp3data.c | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/lib/rbcodec/metadata/mp3data.c b/lib/rbcodec/metadata/mp3data.c index 83605126d6..8c800c798a 100644 --- a/lib/rbcodec/metadata/mp3data.c +++ b/lib/rbcodec/metadata/mp3data.c | |||
@@ -212,27 +212,18 @@ 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 | |||
226 | static unsigned long __find_next_frame(int fd, long *offset, long max_offset, | 215 | static unsigned long __find_next_frame(int fd, long *offset, long max_offset, |
227 | unsigned long reference_header, | 216 | unsigned long reference_header, |
228 | int(*getfunc)(int fd, unsigned char *c), | 217 | int(*getfunc)(int fd, unsigned char *c), |
229 | bool single_header) | 218 | bool single_header) |
230 | { | 219 | { |
231 | unsigned long header=0; | 220 | uint32_t header=0; |
221 | uint32_t ref_header=0; | ||
222 | long ref_header_pos=0; | ||
232 | unsigned char tmp; | 223 | unsigned char tmp; |
233 | long pos = 0; | 224 | long pos = 0; |
234 | 225 | ||
235 | /* We will search until we find two consecutive MPEG frame headers with | 226 | /* We will search until we find two consecutive MPEG frame headers with |
236 | * the same MPEG version, layer and sampling frequency. The first header | 227 | * the same MPEG version, layer and sampling frequency. The first header |
237 | * of this pair is assumed to be the first valid MPEG frame header of the | 228 | * of this pair is assumed to be the first valid MPEG frame header of the |
238 | * whole stream. */ | 229 | * whole stream. */ |
@@ -243,43 +234,33 @@ static unsigned long __find_next_frame(int fd, long *offset, long max_offset, | |||
243 | return 0; | 234 | return 0; |
244 | header |= tmp; | 235 | header |= tmp; |
245 | pos++; | 236 | pos++; |
246 | 237 | ||
247 | /* Abort if max_offset is reached. Stop parsing. */ | 238 | /* Abort if max_offset is reached. Stop parsing. */ |
248 | if (max_offset > 0 && pos > max_offset) | 239 | if (max_offset > 0 && pos > max_offset) |
249 | return 0; | 240 | return 0; |
250 | 241 | ||
251 | if (is_mp3frameheader(header)) { | 242 | if (is_mp3frameheader(header)) { |
252 | if (single_header) { | 243 | if (single_header) { |
253 | /* We search for one _single_ valid header that has the same | 244 | /* We search for one _single_ valid header that has the same |
254 | * type as the reference_header (if reference_header != 0). | 245 | * type as the reference_header (if reference_header != 0). |
255 | * In this case we are finished. */ | 246 | * In this case we are finished. */ |
256 | if (headers_have_same_type(reference_header, header)) | 247 | if (headers_have_same_type(reference_header, header)) |
257 | break; | 248 | break; |
258 | } else { | 249 | } else { |
259 | /* The current header is valid. Now gather the frame size, | 250 | /* The current header is valid. Compare it against the last |
260 | * seek to this byte position and check if there is another | 251 | one we found. NOTE: ref_header MUST come second! */ |
261 | * valid MPEG frame header of the same type. */ | 252 | if (headers_have_same_type(header, ref_header)) { |
262 | struct mp3info info; | 253 | /* Found a match, return the header and offset of the FIRST */ |
263 | 254 | header = ref_header; | |
264 | /* Gather frame size from given header and seek to next | 255 | lseek(fd, ref_header_pos, SEEK_SET); |
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)) | ||
279 | break; | 256 | break; |
257 | } | ||
258 | /* Otherwise look for another.. */ | ||
259 | ref_header = header; | ||
260 | ref_header_pos = lseek(fd, 0, SEEK_CUR); | ||
280 | } | 261 | } |
281 | } | 262 | } |
282 | 263 | ||
283 | } while (true); | 264 | } while (true); |
284 | 265 | ||
285 | *offset = pos - 4; | 266 | *offset = pos - 4; |