Opened 4 months ago

Last modified 4 months ago

#7716 new defect

setpts fails to update the EOF timestamp; it needs to be ported to the new filter API

Reported by: mfwitten Owned by:
Priority: normal Component: avfilter
Version: unspecified Keywords: setpts
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

On #ffmpeg (freenode; IRC), Calvin Walton (kepstin) was kind enough to put together the following reproduction of the problem.

You can see that the video stream produced is too long; the setpts filter cuts each frame's PTS in half, but it does not alter the EOF PTS, thereby tricking the fps filter into duplicating the last frame until the duration of the output stream is twice as long as intended:

...
[Parsed_fps_3 @ 0x56530a3af0c0] EOF is at pts 10
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 4
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 5
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 6
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 7
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 8
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 9
[Parsed_fps_3 @ 0x56530a3af0c0] Duplicated frame with pts 4 5 times
...

Besides somehow fixing setpts to manipulate the EOF PTS, it might also be worthwhile to revisit the documentation for fps, especially for its eof_action parameter.

Sincerely,
Michael Witten


$ ffmpeg -v debug -filter_complex testsrc=r=15,trim=end_frame=10,setpts=PTS/2,fps=15 -f null -
ffmpeg version 4.0.3 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 8 (GCC)
  configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --extra-ldflags='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' --extra-cflags=' ' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable-fontconfig --enable-frei0r --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libcdio --enable-libdrm --enable-indev=jack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzvbi --enable-avfilter --enable-avresample --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-libmfx --enable-runtime-cpudetect
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set logging level) with argument 'debug'.
Reading option '-filter_complex' ... matched as option 'filter_complex' (create a complex filtergraph) with argument 'testsrc=r=15,trim=end_frame=10,setpts=PTS/2,fps=15'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'null'.
Reading option '-' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set logging level) with argument debug.
Applying option filter_complex (create a complex filtergraph) with argument testsrc=r=15,trim=end_frame=10,setpts=PTS/2,fps=15.
Successfully parsed a group of options.
[Parsed_testsrc_0 @ 0x56530a3a70c0] Setting 'r' to value '15'
[Parsed_testsrc_0 @ 0x56530a3a70c0] size:320x240 rate:15/1 duration:-1.000000 sar:1/1
[Parsed_trim_1 @ 0x56530a3a8180] Setting 'end_frame' to value '10'
[Parsed_setpts_2 @ 0x56530a3a90c0] Setting 'expr' to value 'PTS/2'
[Parsed_fps_3 @ 0x56530a3a9f40] Setting 'fps' to value '15'
[Parsed_fps_3 @ 0x56530a3a9f40] fps=15/1
[Parsed_fps_3 @ 0x56530a3a9f40] 0 frames in, 0 frames out; 0 frames dropped, 0 frames duplicated.
Parsing a group of options: output url -.
Applying option f (force format) with argument null.
Successfully parsed a group of options.
Opening an output file: -.
Successfully opened the file.
Stream mapping:
  fps -> Stream #0:0 (wrapped_avframe)
Press [q] to stop, [?] for help
cur_dts is invalid (this is harmless if it occurs once at the start per stream)
detected 4 logical cores
[Parsed_testsrc_0 @ 0x56530a3a8f80] Setting 'r' to value '15'
[Parsed_testsrc_0 @ 0x56530a3a8f80] size:320x240 rate:15/1 duration:-1.000000 sar:1/1
[Parsed_trim_1 @ 0x56530a3ad340] Setting 'end_frame' to value '10'
[Parsed_setpts_2 @ 0x56530a3ae2c0] Setting 'expr' to value 'PTS/2'
[Parsed_fps_3 @ 0x56530a3af0c0] Setting 'fps' to value '15'
[Parsed_fps_3 @ 0x56530a3af0c0] fps=15/1
[AVFilterGraph @ 0x56530a3a79c0] query_formats: 5 queried, 4 merged, 0 already done, 0 delayed
[Parsed_trim_1 @ 0x56530a3ad340] TB:0.066667 FRAME_RATE:15.000000 SAMPLE_RATE:nan
Output #0, null, to 'pipe:':
  Metadata:
    encoder         : Lavf58.12.100
    Stream #0:0, 0, 1/15: Video: wrapped_avframe, 1 reference frame, rgb24, 320x240 [SAR 1:1 DAR 4:3], 0/1, q=2-31, 200 kb/s, 15 fps, 15 tbn, 15 tbc (default)
    Metadata:
      encoder         : Lavc58.18.100 wrapped_avframe
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 0, out pts 0
    Last message repeated 1 times
[Parsed_fps_3 @ 0x56530a3af0c0] Set first pts to 0
[Parsed_fps_3 @ 0x56530a3af0c0] Dropping frame with pts 0
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 1, out pts 1
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 0 to pts 0
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 1, out pts 1
[Parsed_fps_3 @ 0x56530a3af0c0] Dropping frame with pts 1
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 2, out pts 2
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 1 to pts 1
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 2, out pts 2
[Parsed_fps_3 @ 0x56530a3af0c0] Dropping frame with pts 2
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 3, out pts 3
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 2 to pts 2
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 3, out pts 3
[Parsed_fps_3 @ 0x56530a3af0c0] Dropping frame with pts 3
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 4, out pts 4
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 3 to pts 3
[Parsed_fps_3 @ 0x56530a3af0c0] Read frame with in pts 4, out pts 4
[Parsed_fps_3 @ 0x56530a3af0c0] Dropping frame with pts 4
[Parsed_fps_3 @ 0x56530a3af0c0] EOF is at pts 10
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 4
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 5
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 6
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 7
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 8
[Parsed_fps_3 @ 0x56530a3af0c0] Writing frame with pts 4 to pts 9
[Parsed_fps_3 @ 0x56530a3af0c0] Duplicated frame with pts 4 5 times
[out_0_0 @ 0x56530a3b0080] EOF on sink link out_0_0:default.
No more output streams to write to, finishing.
frame=   10 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.66 bitrate=N/A speed= 187x    
video:5kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file #0 (pipe:):
  Output stream #0:0 (video): 10 frames encoded; 10 packets muxed (5360 bytes); 
  Total: 10 packets (5360 bytes) muxed
0 frames successfully decoded, 0 decoding errors
[Parsed_fps_3 @ 0x56530a3af0c0] 10 frames in, 10 frames out; 5 frames dropped, 5 frames duplicated.

Change History (2)

comment:1 Changed 4 months ago by cehoyos

  • Analyzed by developer unset
  • Component changed from ffmpeg to avfilter
  • Keywords fps eof pts timestamp activate removed
  • Reproduced by developer unset

Is this issue reproducible with current FFmpeg git head?

comment:2 Changed 4 months ago by mfwitten

I haven't [yet] built or run HEAD, however I suspect it is indeed reproducible:

$ git log -1 --format='%cd %H' origin/master
Mon Feb 4 21:43:30 2019 +0100 4b46d1ee463f6bb2d2be967d418d275a44fe2a9c
$ git log -3 --format='%cd %s' --date=format:%Y origin/master -- libavfilter/setpts.c
2018 avfilter/setpts: add FR shorthand for FRAME_RATE
2017 avfilter: do not use AVFrame accessor
2015 Merge commit '018bdaed37d2f1735dbecfc58309a1a164abadd5'
$ git grep ff_inlink_acknowledge_status origin/master -- libavfilter/setpts.c || echo NOT FOUND
NOT FOUND
Note: See TracTickets for help on using tickets.