summaryrefslogtreecommitdiff
path: root/apps/metadata/mp4.c
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-02 09:38:24 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-02 09:38:24 +0000
commit4343399473929fd5e746ceee23350d5c6cb264cf (patch)
treeeb2f2306ada36dd7fdb755cfb03a800e45efe0c3 /apps/metadata/mp4.c
parent0a93396cdeab4eb96c7e21531a2d9e2dfde15a2b (diff)
downloadrockbox-4343399473929fd5e746ceee23350d5c6cb264cf.tar.gz
rockbox-4343399473929fd5e746ceee23350d5c6cb264cf.zip
Recognize AAC-HE SBR with upsampling and correct duration, bitrate, seek and resume behaviour for such files. When SBR upsampling is used the decoder outputs the double amount of samples per frame. As the seek and resume functions do not know about this fact a special handling is introduced. Fixes issues reported in FS#11916.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29186 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/metadata/mp4.c')
-rw-r--r--apps/metadata/mp4.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index a59b3f9819..c9c691f0c4 100644
--- a/apps/metadata/mp4.c
+++ b/apps/metadata/mp4.c
@@ -73,6 +73,9 @@
73#define MP4_udta FOURCC('u', 'd', 't', 'a') 73#define MP4_udta FOURCC('u', 'd', 't', 'a')
74#define MP4_extra FOURCC('-', '-', '-', '-') 74#define MP4_extra FOURCC('-', '-', '-', '-')
75 75
76/* Used to correct id3->samples, if SBR upsampling was detected in esds atom. */
77static bool SBR_upsampling_used = false;
78
76/* Read the tag data from an MP4 file, storing up to buffer_size bytes in 79/* Read the tag data from an MP4 file, storing up to buffer_size bytes in
77 * buffer. 80 * buffer.
78 */ 81 */
@@ -272,7 +275,6 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
272 275
273 if (type == 5) 276 if (type == 5)
274 { 277 {
275 DEBUGF("MP4: SBR\n");
276 unsigned int old_index = index; 278 unsigned int old_index = index;
277 279
278 sbr = true; 280 sbr = true;
@@ -342,6 +344,12 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
342 * decoding (parts of) the file. 344 * decoding (parts of) the file.
343 */ 345 */
344 id3->frequency *= 2; 346 id3->frequency *= 2;
347
348 /* Set this to true to be able to calculate the correct runtime
349 * and bitrate. */
350 SBR_upsampling_used = true;
351
352 sbr = true;
345 } 353 }
346 } 354 }
347 355
@@ -665,6 +673,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
665 { 673 {
666 uint32_t subsize; 674 uint32_t subsize;
667 uint32_t subtype; 675 uint32_t subtype;
676 bool sbr_used;
668 677
669 /* Get frequency from the decoder info tag, if possible. */ 678 /* Get frequency from the decoder info tag, if possible. */
670 lseek(fd, 2, SEEK_CUR); 679 lseek(fd, 2, SEEK_CUR);
@@ -676,7 +685,14 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
676 685
677 if (subtype == MP4_esds) 686 if (subtype == MP4_esds)
678 { 687 {
679 read_mp4_esds(fd, id3, &size); 688 sbr_used = read_mp4_esds(fd, id3, &size);
689 if (sbr_used)
690 {
691 if (SBR_upsampling_used)
692 DEBUGF("MP4: AAC-HE, SBR upsampling\n");
693 else
694 DEBUGF("MP4: AAC-HE, SBR\n");
695 }
680 } 696 }
681 } 697 }
682 } 698 }
@@ -730,6 +746,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
730 746
731bool get_mp4_metadata(int fd, struct mp3entry* id3) 747bool get_mp4_metadata(int fd, struct mp3entry* id3)
732{ 748{
749 SBR_upsampling_used = false;
733 id3->codectype = AFMT_UNKNOWN; 750 id3->codectype = AFMT_UNKNOWN;
734 id3->filesize = 0; 751 id3->filesize = 0;
735 errno = 0; 752 errno = 0;
@@ -743,6 +760,12 @@ bool get_mp4_metadata(int fd, struct mp3entry* id3)
743 logf("Not an ALAC or AAC file"); 760 logf("Not an ALAC or AAC file");
744 return false; 761 return false;
745 } 762 }
763
764 /* SBR upsampling will output double amount of samples per frame. */
765 if (SBR_upsampling_used)
766 {
767 id3->samples *= 2;
768 }
746 769
747 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency; 770 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
748 771