Opened 3 years ago
Closed 3 years ago
#9028 closed defect (fixed)
mp4 durations include edit list delay
Reported by: | j0sh | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | avformat |
Version: | git-master | Keywords: | mov edts |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
When clipping and transmuxing to mp4 (eg, -ss <seek> -i <in>
), the duration of the resulting clip includes the edit list delay (start time offset from the beginning of the clip). This does not match the actual track duration.
Generated the source (also attached):
ffmpeg -f lavfi -i testsrc=duration=20:rate=30 -an -c:v libx264 -g 60 test-timecode.mp4
Now try to trim it. This should attempt to cut in the middle of the second GOP, with one extra second of "delay".
ffmpeg -ss 3 -i test-timecode.mp4 -t 5 -c copy out.mp4
Note that the reported time is mostly correct: time=00:00:04.96
`
ffmpeg -ss 3 -i test-timecode.mp4 -t 5 -c copy out.mp4
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
built with clang version 7.1.0 (tags/RELEASE_710/final)
configuration: --disable-static --prefix=/nix/store/dwplnqraah2ygx9kwl1yklddvwj5x5rw-ffmpeg-full-4.3.1 --target_os=darwin --arch=x86_64 --enable-gpl --enable-version3 --disable-nonfree --enable-shared --enable-pic --cc=clang --disable-small --enable-runtime-cpudetect --disable-lto --enable-gray --enable-swscale-alpha --enable-hardcoded-tables --enable-safe-bitstream-reader --enable-pthreads --disable-w32threads --disable-os2threads --enable-network --enable-pixelutils --enable-ffmpeg --enable-ffplay --enable-ffprobe --enable-avcodec --enable-avdevice --enable-avfilter --enable-avformat --enable-avresample --enable-avutil --enable-postproc --enable-swresample --enable-swscale --enable-doc --disable-htmlpages --enable-manpages --disable-podpages --disable-txtpages --enable-bzlib --enable-libcelt --enable-libdav1d --disable-libfdk-aac --disable-libflite --enable-fontconfig --enable-libfreetype --disable-frei0r --enable-libfribidi --disable-libgme --enable-gnutls --enable-libgsm --enable-ladspa --enable-libmp3lame --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --disable-libdc1394 --enable-iconv --disable-libjack --disable-libmfx --disable-libmodplug --enable-libmysofa --enable-libopus --enable-librsvg --enable-libsrt --enable-libssh --enable-libtheora --disable-libv4l2 --disable-vaapi --enable-vdpau --enable-libvorbis --enable-libvmaf --enable-libvpx --enable-libwebp --enable-xlib --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-lzma --disable-nvenc --disable-openal --enable-libopencore-amrnb --disable-opengl --enable-libopenjpeg --disable-openssl --disable-libpulse --enable-librtmp --enable-sdl2 --enable-libsoxr --enable-libspeex --disable-libvidstab --enable-libvo-amrwbenc --enable-libwavpack --enable-libx264 --disable-libx265 --disable-libxavs --enable-libxvid --enable-libzmq --enable-zlib --disable-debug --enable-optimizations --disable-extra-warnings --disable-stripping
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test-timecode.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.45.100
Duration: 00:00:20.00, start: 0.000000, bitrate: 48 kb/s
Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 44 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
File 'out.mp4' already exists. Overwrite? [y/N] y
Output #0, mp4, to 'out.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.45.100
Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 320x240 [SAR 1:1 DAR 4:3], q=2-31, 44 kb/s, 30 fps, 30 tbr, 15360 tbn, 15360 tbc (default)
Metadata:
handler_name : VideoHandler
Stream mapping:
Press [q] to stop, ? for help
frame= 182 fps=0.0 q=-1.0 Lsize= 40kB time=00:00:04.96 bitrate= 65.5kbits/s speed=4.94e+03x
video:37kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 8.035690%
`
Results from ffprobe. The top-level duration is incorrect (because it includes the extra 1s of delay at the beginning), but the stream duration is correct.
`
$ ffprobe -show_streams -show_format out.mp4 2>&1 | grep duration=
duration=5.166992 # stream duration - correct
duration=6.167000 # top level duration - incorrect
`
Attachments (4)
Change History (9)
by , 3 years ago
Attachment: | test-timecode.mp4 added |
---|
by , 3 years ago
Attachment: | test-timecode.2.mp4 added |
---|
by , 3 years ago
Attachment: | gop-600.mp4 added |
---|
follow-up: 5 comment:1 by , 3 years ago
Additional samples for testing this patch - https://patchwork.ffmpeg.org/project/ffmpeg/patch/20201219231319.56995-1-martin@martin.st/
These are 40 second clips with a 600-frame (20 second @ 30fps) GOP, so we're creating an edit list mid-GOP:
Sample 1 (mp4)
Attached as gop-600.mp4 : Works nicely. Command to generate the sample:
ffmpeg -f lavfi -i testsrc=duration=40:size=640x480:rate=30 -an -c:v libx264 -g 600 -movflags faststart gop-600.mp4 -y
Clip the sample via:
ffmpeg -ss 17.316666999999999 -i gop-600.mp4 -t 5 -c copy -movflags +faststart -y cut-mp4-600.mp4
Inspect the result: ffprobe cut-mp4-600.mp4
should yield something like: Duration: 00:00:05.12, start: 0.000000, bitrate: 573 kb/s
. All good.
Sample 2 (mpegts) - this does not seem to be quite correct.
As gop-600.ts. Command to generate the sample:
ffmpeg -f lavfi -i testsrc=duration=40:size=640x480:rate=30 -an -c:v libx264 -g 600 gop-600.ts -y
Cut with: ffmpeg -ss 17.316666999999999 -i gop-600.ts -t 5 -c copy -movflags +faststart -y cut-ts-600.mp4
The output duration seems okay, but playback starts at the beginning of the *next* GOP at the 20-second mark, while the clip should start at 17 seconds. The difference from the expected value seems to be exactly the probed start_time value:
ffprobe cut-ts-600.mp4
yields Duration: 00:00:05.12, start: 2.683000, bitrate: 79 kb/s
Specifically - since playback begins at 20s, and the probed start time is 2.683, so 20-2.683 = 17.317 which should have been the position of the initial cut.
comment:2 by , 3 years ago
Component: | undetermined → avformat |
---|---|
Keywords: | mov edts added |
Version: | unspecified → git-master |
comment:4 by , 3 years ago
Status: | new → open |
---|
Okay, so gop-600.mp4 is indeed fixed, but cut-ts-600.mp4 is VFR.
ffmpeg -i cut-ts-600.mp4 -vf vfrdet -an -f null -
[Parsed_vfrdet_0 @ 0000023d9ae4ed40] VFR:0.014085 (1/70) min: 3000 max: 6000 avg: 6000
And BTW, cut-mp4-600.mp4 is also VFR...
comment:5 by , 3 years ago
Resolution: | → fixed |
---|---|
Status: | open → closed |
The issue with cutting a mpegts source as described in [1] has more to do with mpegts itself being non-seekable, than anything to do with mp4.
I can confirm that c2424b1f35a1c6c06f1f9fe5f77a7157ed84e1cd fixes the original report.
[1] https://trac.ffmpeg.org/ticket/9028?replyto=1#comment:1
40s timecode with 20-second GOP (mp4)