diff options
author | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-02-02 15:12:55 +0000 |
---|---|---|
committer | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-02-02 15:12:55 +0000 |
commit | 35bcdef1441519bb66a77b675013309ef39e9eec (patch) | |
tree | 62a3ebcfecb0a4a582d5bd1998e29be066e090e0 /apps | |
parent | 0f4dfc4e9d4c2cbae69442e415639476c73478b2 (diff) | |
download | rockbox-35bcdef1441519bb66a77b675013309ef39e9eec.tar.gz rockbox-35bcdef1441519bb66a77b675013309ef39e9eec.zip |
Find a more consistent and resilient way to handle SBR upsampled files. The detection is only done in one place (the metadata parser) and takes into account that the m4a header might already report corrected frame/sample sizes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29188 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/aac.c | 4 | ||||
-rw-r--r-- | apps/metadata.h | 4 | ||||
-rw-r--r-- | apps/metadata/mp4.c | 27 |
3 files changed, 25 insertions, 10 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c index 37e525e61a..0b27eed472 100644 --- a/apps/codecs/aac.c +++ b/apps/codecs/aac.c | |||
@@ -145,8 +145,8 @@ next_track: | |||
145 | } | 145 | } |
146 | 146 | ||
147 | #ifdef SBR_DEC | 147 | #ifdef SBR_DEC |
148 | /* The file uses SBR. */ | 148 | /* Check for need of special handling for seek/resume and elapsed time. */ |
149 | if (decoder->forceUpSampling) { | 149 | if (ci->id3->needs_upsampling_correction) { |
150 | sbr_fac = 2; | 150 | sbr_fac = 2; |
151 | } else { | 151 | } else { |
152 | sbr_fac = 1; | 152 | sbr_fac = 1; |
diff --git a/apps/metadata.h b/apps/metadata.h index f366aea61c..93b9891763 100644 --- a/apps/metadata.h +++ b/apps/metadata.h | |||
@@ -240,6 +240,10 @@ struct mp3entry { | |||
240 | /* Added for ATRAC3 */ | 240 | /* Added for ATRAC3 */ |
241 | unsigned int channels; /* Number of channels in the stream */ | 241 | unsigned int channels; /* Number of channels in the stream */ |
242 | unsigned int extradata_size; /* Size (in bytes) of the codec's extradata from the container */ | 242 | unsigned int extradata_size; /* Size (in bytes) of the codec's extradata from the container */ |
243 | |||
244 | /* Added for AAC HE SBR */ | ||
245 | bool needs_upsampling_correction; /* flag used by aac codec */ | ||
246 | |||
243 | /* these following two fields are used for local buffering */ | 247 | /* these following two fields are used for local buffering */ |
244 | char id3v2buf[ID3V2_BUF_SIZE]; | 248 | char id3v2buf[ID3V2_BUF_SIZE]; |
245 | char id3v1buf[4][92]; | 249 | char id3v1buf[4][92]; |
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c index c9c691f0c4..a3721f0e9a 100644 --- a/apps/metadata/mp4.c +++ b/apps/metadata/mp4.c | |||
@@ -639,7 +639,10 @@ static bool read_mp4_container(int fd, struct mp3entry* id3, | |||
639 | { | 639 | { |
640 | uint32_t entries; | 640 | uint32_t entries; |
641 | unsigned int i; | 641 | unsigned int i; |
642 | 642 | ||
643 | /* Reset to false. */ | ||
644 | id3->needs_upsampling_correction = true; | ||
645 | |||
643 | lseek(fd, 4, SEEK_CUR); | 646 | lseek(fd, 4, SEEK_CUR); |
644 | read_uint32be(fd, &entries); | 647 | read_uint32be(fd, &entries); |
645 | id3->samples = 0; | 648 | id3->samples = 0; |
@@ -651,7 +654,21 @@ static bool read_mp4_container(int fd, struct mp3entry* id3, | |||
651 | 654 | ||
652 | read_uint32be(fd, &n); | 655 | read_uint32be(fd, &n); |
653 | read_uint32be(fd, &l); | 656 | read_uint32be(fd, &l); |
654 | id3->samples += n * l; | 657 | |
658 | /* Some SBR files use upsampling. In this case the number | ||
659 | * of output samples is doubled to a maximum of 2048 | ||
660 | * samples per frame. This means that files which already | ||
661 | * report a frame size of 2048 in their header will not | ||
662 | * need any further special handling. */ | ||
663 | if (SBR_upsampling_used && l<=1024) | ||
664 | { | ||
665 | id3->samples += n * l * 2; | ||
666 | id3->needs_upsampling_correction = true; | ||
667 | } | ||
668 | else | ||
669 | { | ||
670 | id3->samples += n * l; | ||
671 | } | ||
655 | } | 672 | } |
656 | 673 | ||
657 | size = 0; | 674 | size = 0; |
@@ -760,12 +777,6 @@ bool get_mp4_metadata(int fd, struct mp3entry* id3) | |||
760 | logf("Not an ALAC or AAC file"); | 777 | logf("Not an ALAC or AAC file"); |
761 | return false; | 778 | return false; |
762 | } | 779 | } |
763 | |||
764 | /* SBR upsampling will output double amount of samples per frame. */ | ||
765 | if (SBR_upsampling_used) | ||
766 | { | ||
767 | id3->samples *= 2; | ||
768 | } | ||
769 | 780 | ||
770 | id3->length = ((int64_t) id3->samples * 1000) / id3->frequency; | 781 | id3->length = ((int64_t) id3->samples * 1000) / id3->frequency; |
771 | 782 | ||