summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rbcodec/metadata/mp3data.c55
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. */
216static 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
226static unsigned long __find_next_frame(int fd, long *offset, long max_offset, 215static 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;