diff options
-rw-r--r-- | apps/codecs/libm4a/demux.c | 140 | ||||
-rw-r--r-- | apps/codecs/libm4a/m4a.h | 2 |
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 | ||
82 | static 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 | |||
90 | static 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 */ |
99 | static void read_chunk_hdlr(qtmovie_t *qtmovie, size_t chunk_len) | 83 | static 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 | ||
348 | static void read_chunk_stts(qtmovie_t *qtmovie, size_t chunk_len) | 339 | static 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 | ||
383 | static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len) | 382 | static 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 | ||
427 | static void read_chunk_stsc(qtmovie_t *qtmovie, size_t chunk_len) | 442 | static 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 | ||
461 | static void read_chunk_stco(qtmovie_t *qtmovie, size_t chunk_len) | 484 | static 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 | ||
491 | static bool read_chunk_stbl(qtmovie_t *qtmovie, size_t chunk_len) | 522 | static 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 */ | ||
681 | static 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 */ | ||
690 | static 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 */ |
699 | static bool read_chunk_moov(qtmovie_t *qtmovie, size_t chunk_len) | 718 | static 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; |