“过去持续时间 X.XXX 太长”是什么意思?

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

Past duration 0.603386 too large
Past duration 0.614372 too large
Past duration 0.606377 too large

他们是什么意思? 我没有发现任何明确的在线或在 ffmpeg 文档。

100198 次浏览

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

来源摘要:

    delta0 = sync_ipts - ost->sync_opts;
delta  = delta0 + duration;

...

        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;
}

这只是一个快速的一瞥,所以请随意深入挖掘。

SourceForge 上 DVDStyler 项目的一位维护人员说:

2015年1月15日之后的 FFMpeg 版本经常显示这个警告 增加了警告可能的速率控制失真,否则 不会造成任何伤害。

当尝试将高帧速源编码为低帧速输出时,会出现此警告消息,这意味着需要删除帧。


我之所以犯这个错误,是因为我想把一系列图像转换成视频:

ffmpeg -i %05d.png -r 24 -c:v libx264 -crf 5 out.mkv

问题似乎是,如果没有给出帧速率的输入,那么假设帧速率为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

这也可以在编码的帧总数上看到。我有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%

如果设置输入帧速率而不是输出帧速率,则错误消息将消失。然后输出帧速率将被自动选择为输入帧速率。此外,在较新的 ffmpeg 版本中,您必须小心,因为当使用带有 -i选项或 image2v4l2输入格式的 PNG 图像时,您必须使用 -framerate而不是 -r,请参阅 -r选项的文档

ffmpeg -framerate 24 -i %05d.png -c:v libx264 -crf 5 out.mkv

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

ffmpeg -framerate 25 -i %05d.png -r 10 -c:v libx264 -crf 5 out.mkv

在这种情况下,只有161/400帧将被编码。其他帧中间将被删除。 此外,错误消息也消失了,我猜想为了不通过向 stdout 发送垃圾邮件来降低 ffmpeg 的速度,请参见:

我收到了数以千计的这种特殊编码的警告。我把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

最初的 ffmpeg 调用是这样的:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower \
-crf 17 -c:a copy -y output.mkv

根据这里的建议,我首先将 -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

在 MediaInfo 的一个详细转储中,我发现的唯一不同之处是删除了原始调用中的这一行,但在第二个调用中没有发现:

Delay relative to video                  : -33ms

然而,我检查了文件开头和结尾附近的 A/V 同步,两个文件之间没有明显的同步差异。他们的运行时间也是相同的,但这只是测量到最接近的秒,在 VLC。所以我像这样使用 ffmpeg 检查了帧数:

ffmpeg -i output.mkv -map 0:v:0 -c copy -f null -

并在输出的末尾查找“ 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

然而,另一个文件随后产生了一堆这样的警告,即使有同步标志,但添加回的速率标志“修复”它(只产生了两个,而不是数千个警告)。所以有时候第二个调用会在第三个不起作用的时候起作用。对于我的直接目的,我将解决第二个调用,并希望它能解决大多数这些问题。

这些都是在 ffmpeg 4.0版本中完成的。

根据 < a href = “ https://trac.FFmpeg.org/Tick/4700”rel = “ nofollow noReferrer”> FFmpeg 问题 # 4700- 过去持续时间0.999992太大 这只是个警告。

使用 -loglevel选项停止它:

ffmpeg -loglevel quiet -i input_file.xyz ....

可能的水平是数字或:

"quiet"
"panic"
"fatal"
"error"
"warning"
"info"
"verbose"
"debug"
"trace"

命令实际上应该是:

ffmpeg -loglevel quiet -i input_file.xyz ...

“ static”参数没有“-”前缀,因为它不是一个选项,而是“-loglevel”选项的值。