[FFmpeg-user] Loop filter producing off by one errors?

Peter pdc.cse+ffmpeg at gmail.com
Mon Jun 15 10:12:37 EEST 2020


On Mon, Jun 15, 2020 at 4:25 PM Peter <pdc.cse+ffmpeg at gmail.com> wrote:

>
>
> On Mon, Jun 15, 2020 at 3:20 PM Gyan Doshi <ffmpeg at gyani.pro> wrote:
>
>>
>>
>> On 15-06-2020 07:38 am, Peter wrote:
>> > Hello,
>> >
>> > I'm trying to create a video from a series of PNG frames and then loop
>> > specific frames using the loop filter. It is giving me a bit of trouble.
>> > Ffmpeg is dropping a single frame somewhere and I'm not sure why that
>> is.
>> > Would appreciate it if someone could take a look.
>> >
>> > Essentially I have a concat demuxer input with 32 frames. I would like
>> to
>> > repeat frame #16 104 times. And repeat frame #34 14 times. 32 input
>> frames
>> > + 104 + 14 = 150 frames. At 30fps, my intention is to produce a 5 second
>> > video with exactly 150 frames. But I can only manage to produce 149
>> frames.
>>
>> Can you identify which frame is missing?
>>
>> Gyan
>
>
> I'm pretty sure that the last frame is being dropped. That is, the loop of
> the last frame is missing. Meaning that this section of the filtergraph is
> only producing 13 extra frames.
>
> [layer_1]loop=loop=14:start=32:size=1,
>
> just some extra confirmation:
>
>    - changing "start=32" to "start=31" produces the exact same 149 frame
>    video.
>    - changing "loop=14" to "loop=15" produces a correct 150 frame video
>    (although this seems wrong to me as I would expect a 151 frame video given
>    these parameters)
>
>
>
>

I am even MORE confident that there is some ffmpeg aspect that is affecting
my results that I am not aware of as two different techniques have produced
the exact same unexpected output.


I tried it another way, using split with trim filter to extract specific
frames, then looping them individually, then concat filter to merge the
video streams. This alternative approach still produces a 149 frame file.
The exact same binary file as the above (according to "diff -b").

[0]null[layer_0];
[1]null[layer_1];
[layer_1]split=4[s1][s2][s3][s4];
[s1]trim=start_frame=0:end_frame=15,setpts=expr=PTS-STARTPTS[l1];
[s2]trim=start_frame=15:end_frame=16,setpts=expr=PTS-STARTPTS,loop=loop=104:start=0:size=1[l2];
[s3]trim=start_frame=16:end_frame=31,setpts=expr=PTS-STARTPTS[l3];
[s4]trim=start_frame=31:end_frame=32,setpts=expr=PTS-STARTPTS,loop=loop=14:start=0:size=1[l4];
[l1][l2][l3][l4]concat=n=4,setpts=expr='N/(30*TB)'[layer_1_loopedFrames];
[layer_0]fps=fps=30.000000[layer_0_fps];
[layer_1_loopedFrames]fps=fps=30.000000[layer_1_loopedFrames_fps];
[layer_0_fps][layer_1_loopedFrames_fps]overlay=x=0.0:y=0.0:format=auto[overlay_all]

And, as previously mentioned, if I repeat the last frame one more time than
necessary, it produces a correct 150 frame output.

[0]null[layer_0];
[1]null[layer_1];
[layer_1]split=4[s1][s2][s3][s4];
[s1]trim=start_frame=0:end_frame=15,setpts=expr=PTS-STARTPTS[l1];
[s2]trim=start_frame=15:end_frame=16,setpts=expr=PTS-STARTPTS,loop=loop=104:start=0:size=1[l2];
[s3]trim=start_frame=16:end_frame=31,setpts=expr=PTS-STARTPTS[l3];
[s4]trim=start_frame=31:end_frame=32,setpts=expr=PTS-STARTPTS,loop=loop=15:start=0:size=1[l4];
[l1][l2][l3][l4]concat=n=4,setpts=expr='N/(30*TB)'[layer_1_loopedFrames];
[layer_0]fps=fps=30.000000[layer_0_fps];
[layer_1_loopedFrames]fps=fps=30.000000[layer_1_loopedFrames_fps];
[layer_0_fps][layer_1_loopedFrames_fps]overlay=x=0.0:y=0.0:format=auto[overlay_all]

Notice, the loop of 15 (should be 14) in the [s4]...[l4] filterchain


Different approach, same unexpected/wrong output. Can anyone tell me what
I'm missing here?


More information about the ffmpeg-user mailing list