summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-01-31 21:54:50 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-01-31 21:54:50 +0000
commit411023c6be52e82a9c1e3c0b91cb772d44146569 (patch)
tree41ca277516a15197357803cbceb0ca92f057d588
parent02dce4500dd8f60a0a911aacd367a1cff8e15da6 (diff)
downloadrockbox-411023c6be52e82a9c1e3c0b91cb772d44146569.tar.gz
rockbox-411023c6be52e82a9c1e3c0b91cb772d44146569.zip
Rework m4a seek/resume code. Seek/resume does now also work properly with files having sample_to_chunk of 1 or 2.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29178 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libm4a/m4a.c128
-rw-r--r--apps/codecs/libm4a/m4a.h22
2 files changed, 69 insertions, 81 deletions
diff --git a/apps/codecs/libm4a/m4a.c b/apps/codecs/libm4a/m4a.c
index 62b15c0fcf..0825132b85 100644
--- a/apps/codecs/libm4a/m4a.c
+++ b/apps/codecs/libm4a/m4a.c
@@ -267,57 +267,44 @@ unsigned int alac_seek(demux_res_t* demux_res, stream_t* stream,
267 uint32_t sound_sample_loc, uint32_t* sound_samples_done, 267 uint32_t sound_sample_loc, uint32_t* sound_samples_done,
268 int* current_sample) 268 int* current_sample)
269{ 269{
270 uint32_t i; 270 uint32_t i = 0;
271 uint32_t j; 271 uint32_t tmp_var, tmp_cnt, tmp_dur;
272 uint32_t new_sample; 272 uint32_t new_sample = 0; /* Holds the amount of chunks/frames. */
273 uint32_t new_sound_sample; 273 uint32_t new_sound_sample = 0; /* Sums up total amount of samples. */
274 uint32_t new_pos; 274 uint32_t new_pos; /* Holds the desired chunk/frame index. */
275 275
276 /* First check we have the appropriate metadata - we should always 276 /* First check we have the appropriate metadata - we should always
277 * have it. 277 * have it.
278 */ 278 */
279 279 if (!demux_res->num_time_to_samples || !demux_res->num_sample_byte_sizes)
280 if ((demux_res->num_time_to_samples==0) ||
281 (demux_res->num_sample_byte_sizes==0))
282 { 280 {
283 return 0; 281 return 0;
284 } 282 }
285 283
286 /* Find the destination block from time_to_sample array */ 284 /* Find the destination block from time_to_sample array */
287 285 time_to_sample_t *tab = demux_res->time_to_sample;
288 i = 0; 286 while (i < demux_res->num_time_to_samples)
289 new_sample = 0;
290 new_sound_sample = 0;
291
292 while ((i < demux_res->num_time_to_samples) &&
293 (new_sound_sample < sound_sample_loc))
294 { 287 {
295 j = (sound_sample_loc - new_sound_sample) / 288 tmp_cnt = tab[i].sample_count;
296 demux_res->time_to_sample[i].sample_duration; 289 tmp_dur = tab[i].sample_duration;
297 290 tmp_var = tmp_cnt * tmp_dur;
298 if (j <= demux_res->time_to_sample[i].sample_count) 291 if (sound_sample_loc <= new_sound_sample + tmp_var)
299 { 292 {
300 new_sample += j; 293 tmp_var = (sound_sample_loc - new_sound_sample);
301 new_sound_sample += j * 294 new_sample += tmp_var / tmp_dur;
302 demux_res->time_to_sample[i].sample_duration; 295 new_sound_sample += tmp_var;
303 break; 296 break;
304 }
305 else
306 {
307 new_sound_sample += (demux_res->time_to_sample[i].sample_duration
308 * demux_res->time_to_sample[i].sample_count);
309 new_sample += demux_res->time_to_sample[i].sample_count;
310 i++;
311 } 297 }
298 new_sample += tmp_cnt;
299 new_sound_sample += tmp_var;
300 ++i;
312 } 301 }
313 302
314 /* We know the new block, now calculate the file position. */ 303 /* We know the new block, now calculate the file position. */
315
316 new_pos = get_sample_offset(demux_res, new_sample); 304 new_pos = get_sample_offset(demux_res, new_sample);
317 305
318 /* We know the new file position, so let's try to seek to it */ 306 /* We know the new file position, so let's try to seek to it */
319 307 if (stream->ci->seek_buffer(new_pos))
320 if (stream->ci->seek_buffer(new_pos))
321 { 308 {
322 *sound_samples_done = new_sound_sample; 309 *sound_samples_done = new_sound_sample;
323 *current_sample = new_sample; 310 *current_sample = new_sample;
@@ -352,74 +339,69 @@ unsigned int alac_seek_raw(demux_res_t* demux_res, stream_t* stream,
352 uint32_t file_loc, uint32_t* sound_samples_done, 339 uint32_t file_loc, uint32_t* sound_samples_done,
353 int* current_sample) 340 int* current_sample)
354{ 341{
355 uint32_t chunk_sample = 0; 342 uint32_t chunk_sample = 0; /* Holds the chunk/frame index. */
356 uint32_t total_samples = 0; 343 uint32_t total_samples = 0; /* Sums up total amount of chunks/frames. */
357 uint32_t new_sound_sample = 0; 344 uint32_t new_sound_sample = 0; /* Sums up total amount of samples. */
358 uint32_t new_pos; 345 uint32_t new_pos;
359 uint32_t chunk; 346 uint32_t chunk;
360 uint32_t i; 347 uint32_t i, tmp_dur, tmp_cnt;
361 348
362 if (!demux_res->num_chunk_offsets || 349 /* There is no metadata available to perform raw seek. */
363 !demux_res->num_sample_to_chunks) 350 if (!demux_res->num_chunk_offsets || !demux_res->num_sample_to_chunks)
364 { 351 {
365 return 0; 352 return 0;
366 } 353 }
367 354
368 /* Locate the chunk containing file_loc. */ 355 /* Locate the chunk containing file_loc. */
369 356 chunk = 0;
370 for (i = 0; i < demux_res->num_chunk_offsets && 357 while (chunk < demux_res->num_chunk_offsets)
371 file_loc > demux_res->chunk_offset[i]; i++)
372 { 358 {
359 if (file_loc < demux_res->chunk_offset[chunk++])
360 {
361 break;
362 }
373 } 363 }
374 364 new_pos = demux_res->chunk_offset[chunk-1];
375 chunk = i + 1;
376 new_pos = demux_res->chunk_offset[chunk - 1];
377 365
378 /* Get the first sample of the chunk. */ 366 /* Get the first sample of the chunk. */
379 367 i = 1;
380 for (i = 1; i < demux_res->num_sample_to_chunks && 368 sample_to_chunk_t *tab1 = demux_res->sample_to_chunk;
381 chunk > demux_res->sample_to_chunk[i - 1].first_chunk; i++) 369 while (i < demux_res->num_sample_to_chunks)
382 { 370 {
383 chunk_sample += demux_res->sample_to_chunk[i - 1].num_samples * 371 if (chunk <= tab1[i].first_chunk)
384 (demux_res->sample_to_chunk[i].first_chunk - 372 {
385 demux_res->sample_to_chunk[i - 1].first_chunk); 373 break;
374 }
375 chunk_sample += tab1[i-1].num_samples * (tab1[i].first_chunk - tab1[i-1].first_chunk);
376 ++i;
386 } 377 }
378 chunk_sample += (chunk - tab1[i-1].first_chunk) * tab1[i-1].num_samples;
387 379
388 chunk_sample += (chunk - demux_res->sample_to_chunk[i - 1].first_chunk) *
389 demux_res->sample_to_chunk[i - 1].num_samples;
390
391 /* Get the position within the chunk. */ 380 /* Get the position within the chunk. */
392 381 while (chunk_sample < demux_res->num_sample_byte_sizes &&
393 for (; chunk_sample < demux_res->num_sample_byte_sizes; chunk_sample++) 382 file_loc >= new_pos + demux_res->sample_byte_size[chunk_sample])
394 { 383 {
395 if (file_loc < new_pos + demux_res->sample_byte_size[chunk_sample]) 384 new_pos += demux_res->sample_byte_size[chunk_sample++];
396 {
397 break;
398 }
399
400 new_pos += demux_res->sample_byte_size[chunk_sample];
401 } 385 }
402 386
403 /* Get sound sample offset. */ 387 /* Get sound sample offset. */
404 388 i = 0;
405 for (i = 0; i < demux_res->num_time_to_samples; i++) 389 time_to_sample_t *tab2 = demux_res->time_to_sample;
390 while (i < demux_res->num_time_to_samples)
406 { 391 {
407 if (chunk_sample < 392 tmp_dur = tab2[i].sample_duration;
408 total_samples + demux_res->time_to_sample[i].sample_count) 393 tmp_cnt = tab2[i].sample_count;
394 total_samples += tmp_cnt;
395 new_sound_sample += tmp_cnt * tmp_dur;
396 if (chunk_sample <= total_samples)
409 { 397 {
398 new_sound_sample += (chunk_sample - total_samples) * tmp_dur;
410 break; 399 break;
411 } 400 }
412 401 ++i;
413 total_samples += demux_res->time_to_sample[i].sample_count;
414 new_sound_sample += demux_res->time_to_sample[i].sample_count
415 * demux_res->time_to_sample[i].sample_duration;
416 } 402 }
417
418 new_sound_sample += (chunk_sample - total_samples)
419 * demux_res->time_to_sample[i].sample_duration;
420 403
421 /* Go to the new file position. */ 404 /* Go to the new file position. */
422
423 if (stream->ci->seek_buffer(new_pos)) 405 if (stream->ci->seek_buffer(new_pos))
424 { 406 {
425 *sound_samples_done = new_sound_sample; 407 *sound_samples_done = new_sound_sample;
diff --git a/apps/codecs/libm4a/m4a.h b/apps/codecs/libm4a/m4a.h
index 066f54b722..2b361e8784 100644
--- a/apps/codecs/libm4a/m4a.h
+++ b/apps/codecs/libm4a/m4a.h
@@ -45,6 +45,18 @@ typedef struct {
45 45
46typedef uint32_t fourcc_t; 46typedef uint32_t fourcc_t;
47 47
48typedef struct
49{
50 uint32_t first_chunk;
51 uint32_t num_samples;
52} sample_to_chunk_t;
53
54typedef struct
55{
56 uint32_t sample_count;
57 uint32_t sample_duration;
58} time_to_sample_t;
59
48typedef struct 60typedef struct
49{ 61{
50 uint16_t num_channels; 62 uint16_t num_channels;
@@ -53,19 +65,13 @@ typedef struct
53 fourcc_t format; 65 fourcc_t format;
54 void *buf; 66 void *buf;
55 67
56 struct { 68 sample_to_chunk_t *sample_to_chunk;
57 uint32_t first_chunk;
58 uint32_t num_samples;
59 } *sample_to_chunk;
60 uint32_t num_sample_to_chunks; 69 uint32_t num_sample_to_chunks;
61 70
62 uint32_t *chunk_offset; 71 uint32_t *chunk_offset;
63 uint32_t num_chunk_offsets; 72 uint32_t num_chunk_offsets;
64 73
65 struct { 74 time_to_sample_t *time_to_sample;
66 uint32_t sample_count;
67 uint32_t sample_duration;
68 } *time_to_sample;
69 uint32_t num_time_to_samples; 75 uint32_t num_time_to_samples;
70 76
71 uint16_t *sample_byte_size; 77 uint16_t *sample_byte_size;