summaryrefslogtreecommitdiff
path: root/apps/metadata/mp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/metadata/mp4.c')
-rw-r--r--apps/metadata/mp4.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index 26ab7cc30a..1ef3701e30 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 */
@@ -117,17 +120,11 @@ static unsigned int read_mp4_tag_string(int fd, int size_left, char** buffer,
117 120
118 if (bytes_read) 121 if (bytes_read)
119 { 122 {
120 /* Do not overwrite already available metadata. Especially when reading 123 (*buffer)[bytes_read] = 0;
121 * tags with e.g. multiple genres / artists. This way only the first 124 *dest = *buffer;
122 * of multiple entries is used, all following are dropped. */ 125 length = strlen(*buffer) + 1;
123 if (*dest == NULL) 126 *buffer_left -= length;
124 { 127 *buffer += length;
125 (*buffer)[bytes_read] = 0;
126 *dest = *buffer;
127 length = strlen(*buffer) + 1;
128 *buffer_left -= length;
129 *buffer += length;
130 }
131 } 128 }
132 else 129 else
133 { 130 {
@@ -346,6 +343,11 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
346 * decoding (parts of) the file. 343 * decoding (parts of) the file.
347 */ 344 */
348 id3->frequency *= 2; 345 id3->frequency *= 2;
346
347 /* Set this to true to be able to calculate the correct runtime
348 * and bitrate. */
349 SBR_upsampling_used = true;
350
349 sbr = true; 351 sbr = true;
350 } 352 }
351 } 353 }
@@ -638,7 +640,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
638 unsigned int i; 640 unsigned int i;
639 641
640 /* Reset to false. */ 642 /* Reset to false. */
641 id3->needs_upsampling_correction = false; 643 id3->needs_upsampling_correction = true;
642 644
643 lseek(fd, 4, SEEK_CUR); 645 lseek(fd, 4, SEEK_CUR);
644 read_uint32be(fd, &entries); 646 read_uint32be(fd, &entries);
@@ -652,12 +654,12 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
652 read_uint32be(fd, &n); 654 read_uint32be(fd, &n);
653 read_uint32be(fd, &l); 655 read_uint32be(fd, &l);
654 656
655 /* Some AAC file use HE profile. In this case the number 657 /* Some SBR files use upsampling. In this case the number
656 * of output samples is doubled to a maximum of 2048 658 * of output samples is doubled to a maximum of 2048
657 * samples per frame. This means that files which already 659 * samples per frame. This means that files which already
658 * report a frame size of 2048 in their header will not 660 * report a frame size of 2048 in their header will not
659 * need any further special handling. */ 661 * need any further special handling. */
660 if (id3->codectype==AFMT_MP4_AAC_HE && l<=1024) 662 if (SBR_upsampling_used && l<=1024)
661 { 663 {
662 id3->samples += n * l * 2; 664 id3->samples += n * l * 2;
663 id3->needs_upsampling_correction = true; 665 id3->needs_upsampling_correction = true;
@@ -772,6 +774,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
772 774
773bool get_mp4_metadata(int fd, struct mp3entry* id3) 775bool get_mp4_metadata(int fd, struct mp3entry* id3)
774{ 776{
777 SBR_upsampling_used = false;
775 id3->codectype = AFMT_UNKNOWN; 778 id3->codectype = AFMT_UNKNOWN;
776 id3->filesize = 0; 779 id3->filesize = 0;
777 errno = 0; 780 errno = 0;