Opened 7 weeks ago

Last modified 7 weeks ago

#6128 new defect

Using the concat demuxer with images and specified duration directives produces wrong duration

Reported by: mulvya Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

The FFmpeg wiki entry on Slideshow has a section at wiki:Slideshow#Concatdemuxer on using the concat demuxer to create a video from a series of images with custom duration assigned to each image. However, FFmpeg does not produce a video of the requested total duration.

How to reproduce:

  1. Create still images:
    ffmpeg -f lavfi -i color -vframes 1 black.png
    
    ffmpeg -f lavfi -i color=white -vframes 1 white.png
    
  1. Create concat list as shown in Wiki
    file black.png
    duration 6
    file white.png
    duration 2
    
  1. Run the concat
    ffmpeg -f concat -i list.txt result.mp4
    
    ffmpeg version N-83410-gb1e2192007 Copyright (c) 2000-2017 the FFmpeg developers
      built with gcc 6.3.0 (Rev1, Built by MSYS2 project)
      configuration:  --enable-avisynth --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-cuda --enable-cuvid --enable-schannel --enable-sdl2 --enable-decklink --enable-fontconfig --enable-frei0r --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmfx --enable-libmodplug --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libwavpack --enable-libwebp --enable-libxavs --enable-libxvid --enable-libzimg --enable-openssl --enable-libsnappy --enable-gpl --enable-opencl --enable-opengl --enable-libcdio --enable-libfdk-aac --enable-libkvazaar --enable-librubberband --enable-libssh --enable-libtesseract --enable-libzvbi --enable-chromaprint --enable-libopenh264 --enable-libopenmpt --enable-netcdf --disable-w32threads --enable-version3 --enable-nonfree --enable-filter=frei0r --disable-debug
      libavutil      55. 46.100 / 55. 46.100
      libavcodec     57. 75.100 / 57. 75.100
      libavformat    57. 66.101 / 57. 66.101
      libavdevice    57.  2.100 / 57.  2.100
      libavfilter     6. 72.100 /  6. 72.100
      libswscale      4.  3.101 /  4.  3.101
      libswresample   2.  4.100 /  2.  4.100
      libpostproc    54.  2.100 / 54.  2.100
    Input #0, concat, from 'list.txt':
      Duration: 00:00:08.00, start: 0.000000, bitrate: 0 kb/s
        Stream #0:0: Video: png, rgb24(pc), 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
    No pixel format specified, yuv444p for H.264 encoding chosen.
    Use -pix_fmt yuv420p for compatibility with outdated media players.
    [libx264 @ 000000000041c1a0] using SAR=1/1
    [libx264 @ 000000000041c1a0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 LZCNT BMI2
    [libx264 @ 000000000041c1a0] profile High 4:4:4 Predictive, level 1.3, 4:4:4 8-bit
    [libx264 @ 000000000041c1a0] 264 - core 148 r2762 90a61ec - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=4 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to 'result.mp4':
      Metadata:
        encoder         : Lavf57.66.101
        Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv444p, 320x240 [SAR 1:1 DAR 4:3], q=-1--1, 25 fps, 12800 tbn, 25 tbc
        Metadata:
          encoder         : Lavc57.75.100 libx264
        Side data:
          cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
    Stream mapping:
      Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
    Press [q] to stop, [?] for help
    frame=  151 fps=0.0 q=-1.0 Lsize=       6kB time=00:00:05.92 bitrate=   8.0kbits/s dup=149 drop=0 speed=82.1x
    video:3kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 81.122292%
    [libx264 @ 000000000041c1a0] frame I:2     Avg QP: 9.00  size:    53
    [libx264 @ 000000000041c1a0] frame P:38    Avg QP: 9.29  size:    23
    [libx264 @ 000000000041c1a0] frame B:111   Avg QP:12.67  size:    15
    [libx264 @ 000000000041c1a0] consecutive B-frames:  2.0%  0.0%  0.0% 98.0%
    [libx264 @ 000000000041c1a0] mb I  I16..4:  0.3% 99.7%  0.0%
    [libx264 @ 000000000041c1a0] mb P  I16..4:  0.0%  0.0%  0.0%  P16..4:  0.0%  0.0%  0.0%  0.0%  0.0%    skip:100.0%
    [libx264 @ 000000000041c1a0] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.0%  0.0%  0.0%  direct: 0.0%  skip:100.0%
    [libx264 @ 000000000041c1a0] 8x8 transform intra:99.7%
    [libx264 @ 000000000041c1a0] coded y,u,v intra: 0.0% 0.0% 0.0% inter: 0.0% 0.0% 0.0%
    [libx264 @ 000000000041c1a0] i16 v,h,dc,p:  0%  0% 100%  0%
    [libx264 @ 000000000041c1a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu:  0%  0% 100%  0%  0%  0%  0%  0%  0%
    [libx264 @ 000000000041c1a0] Weighted P-Frames: Y:0.0% UV:0.0%
    [libx264 @ 000000000041c1a0] kb/s:3.43
    
  1. Check output duration
    ffprobe result.mp4 -show_entries format=duration -v 0
    
    [FORMAT]
    duration=6.040000
    [/FORMAT]
    

Trying to work around this, by duplicating the last image entry (with or without duration directive) also produces unexpected output.

  1. Updated list
    file black.png
    duration 6
    file white.png
    duration 2
    file white.png
    duration 1
    
  1. Concat
    ffmpeg -f concat -i list2.txt result2.mp4
    
    ffmpeg version N-83410-gb1e2192007 Copyright (c) 2000-2017 the FFmpeg developers
      built with gcc 6.3.0 (Rev1, Built by MSYS2 project)
      configuration:  --enable-avisynth --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-cuda --enable-cuvid --enable-schannel --enable-sdl2 --enable-decklink --enable-fontconfig --enable-frei0r --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmfx --enable-libmodplug --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libwavpack --enable-libwebp --enable-libxavs --enable-libxvid --enable-libzimg --enable-openssl --enable-libsnappy --enable-gpl --enable-opencl --enable-opengl --enable-libcdio --enable-libfdk-aac --enable-libkvazaar --enable-librubberband --enable-libssh --enable-libtesseract --enable-libzvbi --enable-chromaprint --enable-libopenh264 --enable-libopenmpt --enable-netcdf --disable-w32threads --enable-version3 --enable-nonfree --enable-filter=frei0r --disable-debug
      libavutil      55. 46.100 / 55. 46.100
      libavcodec     57. 75.100 / 57. 75.100
      libavformat    57. 66.101 / 57. 66.101
      libavdevice    57.  2.100 / 57.  2.100
      libavfilter     6. 72.100 /  6. 72.100
      libswscale      4.  3.101 /  4.  3.101
      libswresample   2.  4.100 /  2.  4.100
      libpostproc    54.  2.100 / 54.  2.100
    Input #0, concat, from 'list2.txt':
      Duration: 00:00:09.00, start: 0.000000, bitrate: 0 kb/s
        Stream #0:0: Video: png, rgb24(pc), 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
    No pixel format specified, yuv444p for H.264 encoding chosen.
    Use -pix_fmt yuv420p for compatibility with outdated media players.
    [libx264 @ 00000000006dc1a0] using SAR=1/1
    [libx264 @ 00000000006dc1a0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 LZCNT BMI2
    [libx264 @ 00000000006dc1a0] profile High 4:4:4 Predictive, level 1.3, 4:4:4 8-bit
    [libx264 @ 00000000006dc1a0] 264 - core 148 r2762 90a61ec - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=4 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to 'result2.mp4':
      Metadata:
        encoder         : Lavf57.66.101
        Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv444p, 320x240 [SAR 1:1 DAR 4:3], q=-1--1, 25 fps, 12800 tbn, 25 tbc
        Metadata:
          encoder         : Lavc57.75.100 libx264
        Side data:
          cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
    Stream mapping:
      Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
    Press [q] to stop, [?] for help
    frame=  249 fps=0.0 q=-1.0 Lsize=       9kB time=00:00:09.84 bitrate=   7.1kbits/s dup=246 drop=0 speed=88.8x
    video:5kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 78.030922%
    [libx264 @ 00000000006dc1a0] frame I:2     Avg QP: 7.50  size:    54
    [libx264 @ 00000000006dc1a0] frame P:62    Avg QP: 9.23  size:    23
    [libx264 @ 00000000006dc1a0] frame B:185   Avg QP:12.67  size:    15
    [libx264 @ 00000000006dc1a0] consecutive B-frames:  0.8%  0.0%  1.2% 98.0%
    [libx264 @ 00000000006dc1a0] mb I  I16..4:  0.3% 99.7%  0.0%
    [libx264 @ 00000000006dc1a0] mb P  I16..4:  0.0%  0.0%  0.0%  P16..4:  0.0%  0.0%  0.0%  0.0%  0.0%    skip:100.0%
    [libx264 @ 00000000006dc1a0] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.0%  0.0%  0.0%  direct: 0.0%  skip:100.0%
    [libx264 @ 00000000006dc1a0] 8x8 transform intra:99.7%
    [libx264 @ 00000000006dc1a0] coded y,u,v intra: 0.0% 0.0% 0.0% inter: 0.0% 0.0% 0.0%
    [libx264 @ 00000000006dc1a0] i16 v,h,dc,p:  0%  0% 100%  0%
    [libx264 @ 00000000006dc1a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu:  0%  0% 100%  0%  0%  0%  0%  0%  0%
    [libx264 @ 00000000006dc1a0] Weighted P-Frames: Y:0.0% UV:0.0%
    [libx264 @ 00000000006dc1a0] kb/s:3.40
    
  1. Check duration
    ffprobe result2.mp4 -show_entries format=duration -v 0
    
    [FORMAT]
    duration=9.960000
    [/FORMAT]
    

This time, the duration is greater (9.96 sec) than it should be (9 sec)

Behaviour originally reported at http://video.stackexchange.com/q/20588/1871

Personally, I believe all the direction durative does is it alters the offset applied to the starting timestamp of successive files in the concat list and not enforce a duration per se. So, that explains to me the issue with the first concat run, but not the second.

Change History (6)

comment:1 Changed 7 weeks ago by Cigaes

ffmpeg does not preserve the duration of the last frame, this is known issue and already reported in several tickets here.

comment:2 Changed 7 weeks ago by mulvya

Ok, but then shouldn't the 2nd concat produce a duration of 8.04s. In any case, how should the wiki section be corrected?

comment:3 Changed 7 weeks ago by Cigaes

The incorrect duration in the second case goes away with Matroska output; it seems an artifact of the MP4 format or muxer. It is unrelated to concat, as it produces the same result when converting from the correct Matroska file obtained earlier.

To get things working, you need to have the duration of the last image be a single frame for your chosen frame rate. Since you did not specify anything, that means 25 FPS, so the last segment need to be duration 0.04.

comment:4 follow-up: Changed 7 weeks ago by mulvya

Does not work with MP4. Works without duration for MKV. Remuxing MKV to MP4 collapses video to n frames where n is number of entries. Producing MKV with -vsync cfr produces same result as MP4 (9.96 sec). Producing MP4 with -vsync vfr produces same result (8.04 sec) as MKV with no vsync option applied.

Last edited 7 weeks ago by mulvya (previous) (diff)

comment:5 in reply to: ↑ 4 Changed 7 weeks ago by cehoyos

Replying to mulvya:

Producing MP4 with -vsync vfr produces same result (8.04 sec) as MKV with no vsync option applied.

But no valid output file.

comment:6 Changed 7 weeks ago by mulvya

MP4 plays fine in Potplayer and ffplay. Duration is shown as 8 and black turns to white at 6s. ffplay with autoexit exits at 8s. Does not play in VLC, though.

Last edited 7 weeks ago by mulvya (previous) (diff)
Note: See TracTickets for help on using tickets.