Index: apps/metadata/mp4.c =================================================================== --- apps/metadata/mp4.c (revision 29173) +++ apps/metadata/mp4.c (working copy) @@ -309,6 +309,7 @@ if (sbr) { + DEBUGF("MP4: SBR\n"); unsigned int old_index = index; /* 1 bit read so far */ @@ -596,7 +597,8 @@ break; case MP4_ilst: - if (handler == MP4_mdir) + /* We need at least a size of 8 to read the next atom. */ + if (handler == MP4_mdir && size>8) { rc = read_mp4_tags(fd, id3, size); size = 0; @@ -677,7 +679,7 @@ { read_mp4_esds(fd, id3, &size); } - } + } } break; @@ -752,8 +754,8 @@ } id3->bitrate = ((int64_t) id3->filesize * 8) / id3->length; - DEBUGF("MP4 bitrate %d, frequency %ld Hz, length %ld ms\n", - id3->bitrate, id3->frequency, id3->length); + DEBUGF("MP4 bitrate %d, frequency %ld Hz, length %ld ms, size %ld bytes\n", + id3->bitrate, id3->frequency, id3->length, id3->filesize); } else { Index: apps/codecs/aac.c =================================================================== --- apps/codecs/aac.c (revision 29173) +++ apps/codecs/aac.c (working copy) @@ -59,6 +59,7 @@ NeAACDecHandle decoder; int err; uint32_t s = 0; + uint32_t sbr_fac = 1; unsigned char c = 0; void *ret; @@ -142,6 +143,18 @@ decoder->fb_intermed[0] = &gb_fb_intermed[0][0]; decoder->fb_intermed[1] = &gb_fb_intermed[1][0]; } + + /* The file uses SBR. */ + if (decoder->forceUpSampling) + { + ci->id3->length *= 2; + ci->id3->bitrate /= 2; + sbr_fac = 2; + } + else + { + sbr_fac = 1; + } ci->id3->frequency = s; @@ -174,9 +187,14 @@ /* Deal with any pending seek requests */ if (ci->seek_time) { + /* Seek to the desired position. Important: When seeking in SBR + * upsampling files the seek_time must be divided by 2 when calling + * alac_seek and the resulting sound_samples_done must be expanded + * by a factor 2 afterwards. This is done via using sbr_fac. */ if (alac_seek(&demux_res, &input_stream, - ((ci->seek_time-1)/10)*(ci->id3->frequency/100), + ((ci->seek_time-1)/10/sbr_fac)*(ci->id3->frequency/100), &sound_samples_done, (int*) &i)) { + sound_samples_done *= sbr_fac; elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); ci->set_elapsed(elapsed_time); @@ -234,6 +252,10 @@ /* Output the audio */ ci->yield(); + /* Ensure correct sample_duration is used. For SBR upsampling files + * sample_duration is only half the size of real output frame size. */ + sample_duration *= sbr_fac; + framelength = (frame_info.samples >> 1) - lead_trim; if (i == demux_res.num_sample_byte_sizes - 1 && framelength > 0) @@ -266,7 +288,7 @@ { /* frame_info.samples can be 0 for the first frame */ lead_trim -= (i > 0 || frame_info.samples) - ? (frame_info.samples >> 1) : sample_duration; + ? (frame_info.samples >> 1) : (uint32_t)framelength; if (lead_trim < 0 || ci->id3->lead_trim == 0) { @@ -275,7 +297,7 @@ } /* Update the elapsed-time indicator */ - sound_samples_done += sample_duration; + sound_samples_done += framelength; elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); ci->set_elapsed(elapsed_time); i++;