summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2006-11-08 19:54:08 +0000
committerMagnus Holmgren <magnushol@gmail.com>2006-11-08 19:54:08 +0000
commit38ec5edf26a0044a300ca7d72f7a1afe9575ce0e (patch)
tree2a4d895840384556e641a08300239db3afd2594c
parentd7e55278f38b843e77541439209fcf6c0e6f3662 (diff)
downloadrockbox-38ec5edf26a0044a300ca7d72f7a1afe9575ce0e.tar.gz
rockbox-38ec5edf26a0044a300ca7d72f7a1afe9575ce0e.zip
Improve support for long MP4 files. Twice as long files can now play, and for those that still are too long, exit with a codec failure rather than freeze Rockbox.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11471 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libm4a/demux.c140
-rw-r--r--apps/codecs/libm4a/m4a.h2
2 files changed, 78 insertions, 64 deletions
diff --git a/apps/codecs/libm4a/demux.c b/apps/codecs/libm4a/demux.c
index 44261fdef6..21e415d9ca 100644
--- a/apps/codecs/libm4a/demux.c
+++ b/apps/codecs/libm4a/demux.c
@@ -79,22 +79,6 @@ static void read_chunk_ftyp(qtmovie_t *qtmovie, size_t chunk_len)
79 } 79 }
80} 80}
81 81
82static void read_chunk_tkhd(qtmovie_t *qtmovie, size_t chunk_len)
83{
84 /* don't need anything from here atm, skip */
85 size_t size_remaining = chunk_len - 8;
86
87 stream_skip(qtmovie->stream, size_remaining);
88}
89
90static void read_chunk_mdhd(qtmovie_t *qtmovie, size_t chunk_len)
91{
92 /* don't need anything from here atm, skip */
93 size_t size_remaining = chunk_len - 8;
94
95 stream_skip(qtmovie->stream, size_remaining);
96}
97
98/* media handler inside mdia */ 82/* media handler inside mdia */
99static void read_chunk_hdlr(qtmovie_t *qtmovie, size_t chunk_len) 83static void read_chunk_hdlr(qtmovie_t *qtmovie, size_t chunk_len)
100{ 84{
@@ -284,6 +268,13 @@ static bool read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len)
284 /* 12 = audio format atom, 8 = padding */ 268 /* 12 = audio format atom, 8 = padding */
285 qtmovie->res->codecdata_len = entry_remaining + 12 + 8; 269 qtmovie->res->codecdata_len = entry_remaining + 12 + 8;
286 qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len); 270 qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len);
271
272 if (!qtmovie->res->codecdata)
273 {
274 DEBUGF("stsd too large\n");
275 return false;
276 }
277
287 memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len); 278 memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len);
288 /* audio format atom */ 279 /* audio format atom */
289 ((unsigned int*)qtmovie->res->codecdata)[0] = 0x0c000000; 280 ((unsigned int*)qtmovie->res->codecdata)[0] = 0x0c000000;
@@ -345,7 +336,7 @@ static bool read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len)
345 return true; 336 return true;
346} 337}
347 338
348static void read_chunk_stts(qtmovie_t *qtmovie, size_t chunk_len) 339static bool read_chunk_stts(qtmovie_t *qtmovie, size_t chunk_len)
349{ 340{
350 unsigned int i; 341 unsigned int i;
351 uint32_t numentries; 342 uint32_t numentries;
@@ -366,6 +357,12 @@ static void read_chunk_stts(qtmovie_t *qtmovie, size_t chunk_len)
366 qtmovie->res->num_time_to_samples = numentries; 357 qtmovie->res->num_time_to_samples = numentries;
367 qtmovie->res->time_to_sample = malloc(numentries * sizeof(*qtmovie->res->time_to_sample)); 358 qtmovie->res->time_to_sample = malloc(numentries * sizeof(*qtmovie->res->time_to_sample));
368 359
360 if (!qtmovie->res->time_to_sample)
361 {
362 DEBUGF("stts too large\n");
363 return false;
364 }
365
369 for (i = 0; i < numentries; i++) 366 for (i = 0; i < numentries; i++)
370 { 367 {
371 qtmovie->res->time_to_sample[i].sample_count = stream_read_uint32(qtmovie->stream); 368 qtmovie->res->time_to_sample[i].sample_count = stream_read_uint32(qtmovie->stream);
@@ -378,9 +375,11 @@ static void read_chunk_stts(qtmovie_t *qtmovie, size_t chunk_len)
378 DEBUGF("ehm, size remianing?\n"); 375 DEBUGF("ehm, size remianing?\n");
379 stream_skip(qtmovie->stream, size_remaining); 376 stream_skip(qtmovie->stream, size_remaining);
380 } 377 }
378
379 return true;
381} 380}
382 381
383static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len) 382static bool read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len)
384{ 383{
385 unsigned int i; 384 unsigned int i;
386 uint32_t numentries; 385 uint32_t numentries;
@@ -401,7 +400,7 @@ static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len)
401 DEBUGF("i was expecting variable samples sizes\n"); 400 DEBUGF("i was expecting variable samples sizes\n");
402 stream_read_uint32(qtmovie->stream); 401 stream_read_uint32(qtmovie->stream);
403 size_remaining -= 4; 402 size_remaining -= 4;
404 return; 403 return true;
405 } 404 }
406 size_remaining -= 4; 405 size_remaining -= 4;
407 406
@@ -411,9 +410,23 @@ static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len)
411 qtmovie->res->num_sample_byte_sizes = numentries; 410 qtmovie->res->num_sample_byte_sizes = numentries;
412 qtmovie->res->sample_byte_size = malloc(numentries * sizeof(*qtmovie->res->sample_byte_size)); 411 qtmovie->res->sample_byte_size = malloc(numentries * sizeof(*qtmovie->res->sample_byte_size));
413 412
413 if (!qtmovie->res->sample_byte_size)
414 {
415 DEBUGF("stsz too large\n");
416 return false;
417 }
418
414 for (i = 0; i < numentries; i++) 419 for (i = 0; i < numentries; i++)
415 { 420 {
416 qtmovie->res->sample_byte_size[i] = stream_read_uint32(qtmovie->stream); 421 uint32_t v = stream_read_uint32(qtmovie->stream);
422
423 if (v > 0x0000ffff)
424 {
425 DEBUGF("stsz[%d] > 65 kB (%d)\n", i, v);
426 return false;
427 }
428
429 qtmovie->res->sample_byte_size[i] = v;
417 size_remaining -= 4; 430 size_remaining -= 4;
418 } 431 }
419 432
@@ -422,9 +435,11 @@ static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len)
422 DEBUGF("ehm, size remianing?\n"); 435 DEBUGF("ehm, size remianing?\n");
423 stream_skip(qtmovie->stream, size_remaining); 436 stream_skip(qtmovie->stream, size_remaining);
424 } 437 }
438
439 return true;
425} 440}
426 441
427static void read_chunk_stsc(qtmovie_t *qtmovie, size_t chunk_len) 442static bool read_chunk_stsc(qtmovie_t *qtmovie, size_t chunk_len)
428{ 443{
429 unsigned int i; 444 unsigned int i;
430 uint32_t numentries; 445 uint32_t numentries;
@@ -441,6 +456,12 @@ static void read_chunk_stsc(qtmovie_t *qtmovie, size_t chunk_len)
441 qtmovie->res->sample_to_chunk = malloc(numentries * 456 qtmovie->res->sample_to_chunk = malloc(numentries *
442 sizeof(*qtmovie->res->sample_to_chunk)); 457 sizeof(*qtmovie->res->sample_to_chunk));
443 458
459 if (!qtmovie->res->sample_to_chunk)
460 {
461 DEBUGF("stsc too large\n");
462 return false;
463 }
464
444 for (i = 0; i < numentries; i++) 465 for (i = 0; i < numentries; i++)
445 { 466 {
446 qtmovie->res->sample_to_chunk[i].first_chunk = 467 qtmovie->res->sample_to_chunk[i].first_chunk =
@@ -456,9 +477,11 @@ static void read_chunk_stsc(qtmovie_t *qtmovie, size_t chunk_len)
456 DEBUGF("ehm, size remianing?\n"); 477 DEBUGF("ehm, size remianing?\n");
457 stream_skip(qtmovie->stream, size_remaining); 478 stream_skip(qtmovie->stream, size_remaining);
458 } 479 }
480
481 return true;
459} 482}
460 483
461static void read_chunk_stco(qtmovie_t *qtmovie, size_t chunk_len) 484static bool read_chunk_stco(qtmovie_t *qtmovie, size_t chunk_len)
462{ 485{
463 unsigned int i; 486 unsigned int i;
464 uint32_t numentries; 487 uint32_t numentries;
@@ -475,6 +498,12 @@ static void read_chunk_stco(qtmovie_t *qtmovie, size_t chunk_len)
475 qtmovie->res->chunk_offset = malloc(numentries * 498 qtmovie->res->chunk_offset = malloc(numentries *
476 sizeof(*qtmovie->res->chunk_offset)); 499 sizeof(*qtmovie->res->chunk_offset));
477 500
501 if (!qtmovie->res->chunk_offset)
502 {
503 DEBUGF("stco too large\n");
504 return false;
505 }
506
478 for (i = 0; i < numentries; i++) 507 for (i = 0; i < numentries; i++)
479 { 508 {
480 qtmovie->res->chunk_offset[i] = stream_read_uint32(qtmovie->stream); 509 qtmovie->res->chunk_offset[i] = stream_read_uint32(qtmovie->stream);
@@ -486,6 +515,8 @@ static void read_chunk_stco(qtmovie_t *qtmovie, size_t chunk_len)
486 DEBUGF("ehm, size remianing?\n"); 515 DEBUGF("ehm, size remianing?\n");
487 stream_skip(qtmovie->stream, size_remaining); 516 stream_skip(qtmovie->stream, size_remaining);
488 } 517 }
518
519 return true;
489} 520}
490 521
491static bool read_chunk_stbl(qtmovie_t *qtmovie, size_t chunk_len) 522static bool read_chunk_stbl(qtmovie_t *qtmovie, size_t chunk_len)
@@ -514,16 +545,28 @@ static bool read_chunk_stbl(qtmovie_t *qtmovie, size_t chunk_len)
514 } 545 }
515 break; 546 break;
516 case MAKEFOURCC('s','t','t','s'): 547 case MAKEFOURCC('s','t','t','s'):
517 read_chunk_stts(qtmovie, sub_chunk_len); 548 if (!read_chunk_stts(qtmovie, sub_chunk_len))
549 {
550 return false;
551 }
518 break; 552 break;
519 case MAKEFOURCC('s','t','s','z'): 553 case MAKEFOURCC('s','t','s','z'):
520 read_chunk_stsz(qtmovie, sub_chunk_len); 554 if (!read_chunk_stsz(qtmovie, sub_chunk_len))
555 {
556 return false;
557 }
521 break; 558 break;
522 case MAKEFOURCC('s','t','s','c'): 559 case MAKEFOURCC('s','t','s','c'):
523 read_chunk_stsc(qtmovie, sub_chunk_len); 560 if (!read_chunk_stsc(qtmovie, sub_chunk_len))
561 {
562 return false;
563 }
524 break; 564 break;
525 case MAKEFOURCC('s','t','c','o'): 565 case MAKEFOURCC('s','t','c','o'):
526 read_chunk_stco(qtmovie, sub_chunk_len); 566 if (!read_chunk_stco(qtmovie, sub_chunk_len))
567 {
568 return false;
569 }
527 break; 570 break;
528 default: 571 default:
529 DEBUGF("(stbl) unknown chunk id: %c%c%c%c\n", 572 DEBUGF("(stbl) unknown chunk id: %c%c%c%c\n",
@@ -613,9 +656,6 @@ static bool read_chunk_mdia(qtmovie_t *qtmovie, size_t chunk_len)
613 656
614 switch (sub_chunk_id) 657 switch (sub_chunk_id)
615 { 658 {
616 case MAKEFOURCC('m','d','h','d'):
617 read_chunk_mdhd(qtmovie, sub_chunk_len);
618 break;
619 case MAKEFOURCC('h','d','l','r'): 659 case MAKEFOURCC('h','d','l','r'):
620 read_chunk_hdlr(qtmovie, sub_chunk_len); 660 read_chunk_hdlr(qtmovie, sub_chunk_len);
621 break; 661 break;
@@ -625,10 +665,10 @@ static bool read_chunk_mdia(qtmovie_t *qtmovie, size_t chunk_len)
625 } 665 }
626 break; 666 break;
627 default: 667 default:
628 DEBUGF("(mdia) unknown chunk id: %c%c%c%c\n", 668 /*DEBUGF("(mdia) unknown chunk id: %c%c%c%c\n",
629 SPLITFOURCC(sub_chunk_id)); 669 SPLITFOURCC(sub_chunk_id));*/
630 stream_skip(qtmovie->stream, sub_chunk_len - 8); 670 stream_skip(qtmovie->stream, sub_chunk_len - 8);
631 return false; 671 break;
632 } 672 }
633 673
634 size_remaining -= sub_chunk_len; 674 size_remaining -= sub_chunk_len;
@@ -657,17 +697,14 @@ static bool read_chunk_trak(qtmovie_t *qtmovie, size_t chunk_len)
657 697
658 switch (sub_chunk_id) 698 switch (sub_chunk_id)
659 { 699 {
660 case MAKEFOURCC('t','k','h','d'):
661 read_chunk_tkhd(qtmovie, sub_chunk_len);
662 break;
663 case MAKEFOURCC('m','d','i','a'): 700 case MAKEFOURCC('m','d','i','a'):
664 if (!read_chunk_mdia(qtmovie, sub_chunk_len)) { 701 if (!read_chunk_mdia(qtmovie, sub_chunk_len)) {
665 return false; 702 return false;
666 } 703 }
667 break; 704 break;
668 default: 705 default:
669 DEBUGF("(trak) unknown chunk id: %c%c%c%c\n", 706 /*DEBUGF("(trak) unknown chunk id: %c%c%c%c\n",
670 SPLITFOURCC(sub_chunk_id)); 707 SPLITFOURCC(sub_chunk_id));*/
671 stream_skip(qtmovie->stream, sub_chunk_len - 8); 708 stream_skip(qtmovie->stream, sub_chunk_len - 8);
672 break; 709 break;
673 } 710 }
@@ -677,24 +714,6 @@ static bool read_chunk_trak(qtmovie_t *qtmovie, size_t chunk_len)
677 return true; 714 return true;
678} 715}
679 716
680/* 'mvhd' movie header atom */
681static void read_chunk_mvhd(qtmovie_t *qtmovie, size_t chunk_len)
682{
683 /* don't need anything from here atm, skip */
684 size_t size_remaining = chunk_len - 8;
685
686 stream_skip(qtmovie->stream, size_remaining);
687}
688
689/* 'udta' user data.. contains tag info */
690static void read_chunk_udta(qtmovie_t *qtmovie, size_t chunk_len)
691{
692 /* don't need anything from here atm, skip */
693 size_t size_remaining = chunk_len - 8;
694
695 stream_skip(qtmovie->stream, size_remaining);
696}
697
698/* 'moov' movie atom - contains other atoms */ 717/* 'moov' movie atom - contains other atoms */
699static bool read_chunk_moov(qtmovie_t *qtmovie, size_t chunk_len) 718static bool read_chunk_moov(qtmovie_t *qtmovie, size_t chunk_len)
700{ 719{
@@ -716,21 +735,16 @@ static bool read_chunk_moov(qtmovie_t *qtmovie, size_t chunk_len)
716 735
717 switch (sub_chunk_id) 736 switch (sub_chunk_id)
718 { 737 {
719 case MAKEFOURCC('m','v','h','d'):
720 read_chunk_mvhd(qtmovie, sub_chunk_len);
721 break;
722 case MAKEFOURCC('t','r','a','k'): 738 case MAKEFOURCC('t','r','a','k'):
723 if (!read_chunk_trak(qtmovie, sub_chunk_len)) { 739 if (!read_chunk_trak(qtmovie, sub_chunk_len)) {
724 return false; 740 return false;
725 } 741 }
726 break; 742 break;
727 case MAKEFOURCC('u','d','t','a'):
728 read_chunk_udta(qtmovie, sub_chunk_len);
729 break;
730 default: 743 default:
731 DEBUGF("(moov) unknown chunk id: %c%c%c%c\n", 744 /*DEBUGF("(moov) unknown chunk id: %c%c%c%c\n",
732 SPLITFOURCC(sub_chunk_id)); 745 SPLITFOURCC(sub_chunk_id));*/
733 stream_skip(qtmovie->stream, sub_chunk_len - 8); 746 stream_skip(qtmovie->stream, sub_chunk_len - 8);
747 break;
734 } 748 }
735 749
736 size_remaining -= sub_chunk_len; 750 size_remaining -= sub_chunk_len;
diff --git a/apps/codecs/libm4a/m4a.h b/apps/codecs/libm4a/m4a.h
index 17f54c0146..401cff3b7a 100644
--- a/apps/codecs/libm4a/m4a.h
+++ b/apps/codecs/libm4a/m4a.h
@@ -53,7 +53,7 @@ typedef struct
53 } *time_to_sample; 53 } *time_to_sample;
54 uint32_t num_time_to_samples; 54 uint32_t num_time_to_samples;
55 55
56 uint32_t *sample_byte_size; 56 uint16_t *sample_byte_size;
57 uint32_t num_sample_byte_sizes; 57 uint32_t num_sample_byte_sizes;
58 58
59 uint32_t codecdata_len; 59 uint32_t codecdata_len;