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

164

在使用FFmpeg编码H.264时,我会大量收到以下类型的警告:

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

它们是什么意思?我在网上或ffmpeg文档中都没有找到明确的解释。


2
请将有关ffmpeg的问题直接发送至http://video.stackexchange.com/beta。请查看ffmpeg标签说明。 - Ondra Žižka
39
@Ondra 甚至还有另一个StackExchange网站?这100多个子网站让我感到困惑,我不确定这是StackExchange前进的积极方向。 - mxmlnkn
1
@mxmlnkn 我同意,它让你渴望更简单的时代... :) - Erik
5
我认为是的。StackOverflow是用于编程的,这不是编程方面的问题。有一个问答网站专门针对视频处理,而这个问题是关于视频处理的。有什么难理解的呢? - Ondra Žižka
也要阅读标签描述。 - Ondra Žižka
6个回答

95

SourceForge上DVDStyler项目的维护人员之一在这里提到:

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


“速率控制失真”与(主要是视频)编码有关,与本警告无关。本警告是关于输出时间戳相对于输入时间戳的差异是否过大。 - Gyan
前几次我收到警告时,我终止了转换,但这个建议让我让它运行,警告在一段时间后停止了,转换成功完成。谢谢。 - IRTFM

62

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


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

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版本中,如果使用PNG图像和-i选项或image2v4l2输入格式时,您必须小心使用-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帧会被编码。其他中间帧将被丢弃。 同时,错误消息消失了,我想这是为了不通过向标准输出打印大量信息来拖慢FFmpeg的速度,详见:

4
只有在使用带有“-i”选项的PNG图像时,您需要使用“-framerate”而不是“-r”,这完全解决了我的问题,谢谢! - pretzlstyle
1
在尝试将wmv转换为mp4时,使用“-r”有效,而使用“-framerate”则无效。 - user1934286
+1 我建议将您的"摘要"置于顶部。此外,由于它解决了我将图像转换为视频并尝试增加输出帧速率和加速输出的问题。我从这个命令 ffmpeg -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4" 开始到这个没有更多警告的命令 ffmpeg -framerate 50 -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4"(请注意添加了 -framerate 50 - el-teedee

52

源代码来看,输入流中的呈现时间(pts)与输出流中的呈现时间相差超过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;
    }

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


有什么我们可以做来“修复”这个问题,或者明确地设置输出pts吗? - Baodad
1
我不记得关于这个问题的细节,但如果你所说的“修复”是指消除警告,那么基于上述代码,你可以研究一下选项format_video_sync = VSYNC_DROPformat_video_sync = VSYNC_PASSTHROUGH,看看哪一个在你的使用情况下是可行的。 - Erik
谢谢。我发现使用“-r”开关显式地设置帧速率可以“修复”这些警告。 - Baodad
1
仅从个人经验来看:我曾经遇到“过去的持续时间”消息垃圾邮件问题,并通过使用-r 25强制输入帧速率来解决该问题,但随后我开始发现音频严重不同步。删除-r选项并使用“-async 1 -vsync 1”以防止音频不同步已经解决了音频问题,但是“过去的持续时间”垃圾邮件似乎也消失了。 - Jason Lang
1
在 v4.1 及更高版本中,日志级别已升级,因此它不会出现在默认日志级别中。 - Gyan

32

我使用特定编码器将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个警告消息,也少了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完成的。


3
谢谢您!经过数天的问题困扰,"-async 1 -vsync 1" 对我非常有用。 - Offek
2
感谢 @larryy 的分析,非常有帮助。 - deepelement
1
谢谢您提供这么详细的答案。您能否也解释一下这些同步标志实际上是做什么用的? - Fritz
即使我在转换我用手机拍摄的视频到另一种格式时使用了-async 1 -vsync选项,并且指定或不指定输入速率,我仍然收到这些警告。您有任何想法吗?在这种情况下可能与什么问题有关? - Vesnog

0

实际上应该使用以下命令:

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

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


0
根据FFmpeg问题#4700 - 过去的持续时间0.999992太大,这只是一个警告。
使用-loglevel选项停止它:
ffmpeg -loglevel quiet -i input_file.xyz ....

可能的级别是数字或:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接