"过去的持续时间X.XXX太大"是什么意思?

Eri*_*rik 127 ffmpeg

使用ffmpeg编码H.264时,我会得到以下类型的警告:

Past duration 0.603386 too large
Past duration 0.614372 too large
Past duration 0.606377 too large
Run Code Online (Sandbox Code Playgroud)

他们的意思是什么?我没有在网上或ffmpeg文档中找到任何明确的内容.

Jos*_*vis 86

SourceForge上的DVDStyler项目的维护者之一说了这个:

2015年1月15日之后的FFMpeg版本经常显示此警告.它已被添加以警告可能的速率控制失真,否则它不会造成任何伤害.


mxm*_*nkn 55

尝试将高帧速率源编码为低帧速率输出时出现此警告消息,这意味着需要丢弃帧.


我有这个错误,因为我想将一系列图像转换为视频:

ffmpeg -i %05d.png -r 24 -c:v libx264 -crf 5 out.mkv
Run Code Online (Sandbox Code Playgroud)

问题似乎是,如果没有为输入提供帧速率,则假设帧速率为25 fps:

Input #0, image2, from 'frames/%04d.bmp':
  Duration: 00:00:15.96, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: bmp, bgra, 920x650, 25 fps, 25 tbr, 25 tbn, 25 tbc
Run Code Online (Sandbox Code Playgroud)

这也可以在编码的帧总数上看到.我有400张图片,但上面的命令只编码384:

frame=  384 fps= 68 q=-1.0 Lsize=   10931kB time=00:00:15.91 bitrate=5626.1kbits/s dup=0 drop=15    
video:10928kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.033807%
Run Code Online (Sandbox Code Playgroud)

如果输出帧速率,则通过设置输入帧速率来消除错误消息.然后输出帧速率将自动选择为输入帧速率.此外,在新的ffmpeg版本,你必须小心,因为使用与PNG图像时-i选择或更确切地说,image2v4l2输入格式,你必须使用-framerate,而不是-r,请参阅该文档-r的选项.

ffmpeg -framerate 24 -i %05d.png -c:v libx264 -crf 5 out.mkv
Run Code Online (Sandbox Code Playgroud)

也可以分别指定输入和输出的帧速率:

ffmpeg -framerate 25 -i %05d.png -r 10 -c:v libx264 -crf 5 out.mkv
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只会编码161/400帧.其他帧临时将被删除.此外,错误消息消失,我想为了不通过垃圾邮件到stdout减慢ffmpeg,请参阅:

  • "因为只有在使用带-i选项的PNG图像时,你必须使用-framerate而不是-r" - 这完全解决了我的问题,谢谢! (2认同)

Eri*_*rik 47

查看源代码,似乎输入流中的显示时间(pts)与输出流中的显示时间(pts)之间的差异超过设置为0.6的固定限制.

来自消息来源的片段:

    delta0 = sync_ipts - ost->sync_opts;
    delta  = delta0 + duration;
Run Code Online (Sandbox Code Playgroud)

...

        if (delta0 < 0 &&
        delta > 0 &&
        format_video_sync != VSYNC_PASSTHROUGH &&
        format_video_sync != VSYNC_DROP) {
        double cor = FFMIN(-delta0, duration);
        if (delta0 < -0.6) {
            av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
        } else
            av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
        sync_ipts += cor;
        duration -= cor;
        delta0 += cor;
    }
Run Code Online (Sandbox Code Playgroud)

这只是一瞥,所以请随意深入挖掘.


lar*_*ryy 18

我通过特定的编码获得了数千个这样的警告.我正在将1080p视频缩小到480p.在一个编辑点,由于源激光盘中的缺陷导致一些狡猾的视频,这些消息开始出现,然后出现,我认为,此后每一帧都出现.他们一直在继续,就像这个简短的摘录:

Past duration 0.901115 too large=  535031kB time=00:54:15.06 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 31 times
Past duration 0.901115 too large=  535031kB time=00:54:15.62 bitrate=1346.3kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 34 times
Past duration 0.901115 too large=  535031kB time=00:54:16.21 bitrate=1346.0kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 36 times
Past duration 0.901115 too large=  535338kB time=00:54:16.83 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 39 times
Run Code Online (Sandbox Code Playgroud)

原始的ffmpeg调用是这样的:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv
Run Code Online (Sandbox Code Playgroud)

根据这里的建议,我首先在输入中添加了-framerate 60000/1001.这并没有改善任何事情.我保留-framerate并将-r 60000/1001添加到输出中.这仍然没有改善任何事情.保留两个我最后添加-async 1 -vsync 1.这导致我收到一个警告,就是这样.那个调用是:

ffmpeg -i input.mp4 -framerate 60000/1001 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -r 60000/1001 -async 1 -vsync 1
Run Code Online (Sandbox Code Playgroud)

我在MediaInfo的详细转储中找到的唯一区别是删除了原始调用中找到的这一行,但没有删除第二行:

Delay relative to video                  : -33ms
Run Code Online (Sandbox Code Playgroud)

但是,我检查了文件开头附近和接近结尾的A/V同步,并且两个文件之间的同步没有明显区别.它们的运行时间也相同,但在VLC中仅测量到最接近的秒数.所以我使用ffmpeg检查了帧数,如下所示:

ffmpeg -i output.mkv -map 0:v:0 -c copy -f null -
Run Code Online (Sandbox Code Playgroud)

并在输出结束附近寻找"frame =#".

事实证明,源视频长375226帧,原始调用产生375195帧,第二次调用产生375200帧.因此第二次调用,警告消息少得多,也减少了5帧.

后续测试显示-framerate和-r是不必要的,只使用两个同步标志就足够了.这产生了与上面第二次调用相同的结果,所以我发现解决问题的第三个也是最简单的调用是这样的:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -async 1 -vsync 1
Run Code Online (Sandbox Code Playgroud)

而另一个文件随后产生了一堆这些警告,即使使用同步标志,但添加了速率标志"固定"它(仅生成两个而不是数千个警告).因此,有时第二次调用在第三次调用时不起作用.为了我的直接目的,我将决定第二次调用,并希望它解决了大部分这些问题.

这都是ffmpeg 4.0版.

  • 这次真是万分感谢!经过几天的问题,`-async 1 -vsync 1` 为我修复了它。 (3认同)
  • 感谢您的分析@larryy 非常有帮助 (2认同)