Changes between Initial Version and Version 2 of Ticket #10458


Ignore:
Timestamp:
Jul 11, 2023, 11:48:45 AM (3 years ago)
Author:
John Regan
Comment:

Discovered this isn't limited to just AAC - I think it may apply to any codec that relies on the mp4 file to signal the last sample's duration (tested with the native aac encoder, libmp3lame, and libopus). I've updated the bug title and description accordingly.

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #10458

    • Property Cc John Regan added
    • Property Summary MPEG4 AAC decoding: end padding not trimmed → MPEG4 demuxing: last sample's duration ignored
  • Ticket #10458 – Description

    initial v2  
    1 It seems like ffmpeg is properly removing the front padding from m4a files, but doesn't account for the end padding added to round frames up to 1024 samples.
     1It seems like ffmpeg is properly removing the front padding from audio in mp4 files, but doesn't account for the end padding added to audio frames to round up to the frame length.
     2
     3This is signaled by the mp4 file listing a different duration for the final sample - either via the Decoding Time to Sample Box box, or for fragmented mp4s, the sample duration in the track fragment run box.
    24
    35How to reproduce:
    … …  
    2022}}}
    2123
    22 Using boxdumper from l-smash, I can verify that ffmpeg correctly added an edit list box:
     24Using boxdumper from l-smash, I can verify that ffmpeg correctly added an edit list box that lists total media duration, as well as the samples to trim from the beginning of the audio (the encoder delay):
    2325
    2426{{{
    … …  
    3840}}}
    3941
    40 Additionally, there's a media header box with a duration set to 97024 - and subtracting the 1024 from the edit list box yields 96000:
    41 
    42 {{{
    43 [mdhd: Media Header Box]
    44     position = 889 
    45     size = 32
    46     version = 0
    47     flags = 0x000000
    48     creation_time = UTC 1904/01/01, 00:00:00
    49     modification_time = UTC 1904/01/01, 00:00:00
    50     timescale = 48000
    51     duration = 97024 (00:00:02.021)
    52     language = und 
    53     pre_defined = 0x0000
    54 }}}
    55 
    56 and the Decoding Time to Sample Box also adds up to 97024 - 94 samples at 1024 frames and 1 sample at 768 frames.
     42The Decoding Time to Sample Box specifies the final sample is 768 frames. Doing the math: (94 samples * 1024 frames) + 768 = 97024 frames. Subtract the 1024 frames from the previous Edit List Box and you should have 96000 samples.
    5743
    5844{{{
    … …  
    7157}}}
    7258
     59I think the issue may be the MP4 demuxer not signaling the final decoded packet's duration. This occurs if I use other codecs as well, for example mp3:
     60
     61{{{
     62
     63# using the same source.wav as above that's 96000 samples:
     64% ffmpeg -i source.wav -c:a libmp3lame encoded-in-mp3.mp4
     65% ffmpeg -i encoded-in-mp3.mp4 decoded-from-mp3.wav
     66% soxi -s decoded-from-mp3.wav
     6796815
     68
     69}}}
     70
     71Here's the edts box and stts from encoded-in-mp3.mp4:
     72
     73{{{
     74[edts: Edit Box]
     75    position = 32900
     76    size = 36
     77    [elst: Edit List Box]
     78        position = 32908
     79        size = 28
     80        version = 0
     81        flags = 0x000000
     82        entry_count = 1
     83        entry[0]
     84            segment_duration = 2000
     85            media_time = 1105
     86            media_rate = 1.000000
     87
     88[stts: Decoding Time to Sample Box]
     89    position = 33205
     90    size = 32
     91    version = 0
     92    flags = 0x000000
     93    entry_count = 2
     94    entry[0]
     95        sample_count = 84
     96        sample_delta = 1152
     97    entry[1]
     98        sample_count = 1
     99        sample_delta = 337
     100}}}
     101
     102So again doing some math: (84 samples * 1152 frames) + 337 frames = 97105 frames. Subtract the 1105 frames from the edit list - 96000 frames.
     103
     104Another example with opus:
     105
     106{{{
     107% ffmpeg -i source.wav -c:a libopus encoded-in-opus.mp4
     108% ffmpeg -i encoded-in-opus.mp4 decoded-from-opus.wav
     109% soxi -s decoded-from-opus.wav
     11096648
     111}}}
     112
     113Same issue with a fragmented mp4 - which doesn't have the Decoding Time to Sample Box and instead relies on either the Track Fragment Header Box or the Track Fragment Run Box for sample duration signaling.
     114
     115This does not seem to apply to codecs that carry their own duration signaling, like FLAC in mp4.
     116
    73117ffmpeg version info:
    74118{{{