web-dev-qa-db-ja.com

「過去の期間X.XXXが大きすぎます」とはどういう意味ですか?

Ffmpegを使用してH.264をエンコードすると、次のような種類の警告がまとめて表示されます。

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

彼らはどういう意味ですか?私はオンラインでもffmpegのドキュメントでも明確なものを見つけることができませんでした。

124
Erik

私は特定のエンコードでこれらの警告の数千を得ていました。私は1080pビデオを480pに縮小していました。ソースのlaserdiscに欠陥があるために厄介なビデオがあった編集点では、これらのメッセージが現れ始めて、それから私はそれ以降のすべてのフレームのために現れました。この短い抜粋のように、彼らは続けました:

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からの詳細なダンプで見つけた唯一の違いは、最初の呼び出しで見つかったこの行の削除ですが、2番目の行では見つかりませんでした。

Delay relative to video                  : -33ms

ただし、ファイルの先頭付近と末尾付近でA/V同期を確認したところ、2つのファイル間に同期の違いは見られませんでした。それらの実行時間も同じでしたが、それはVLCで、最も近い秒にのみ測定されました。だから私はそのようにffmpegを使用してフレームカウントをチェックしました:

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

そして出力の終わり近くで "frame =#"を探します。

ソースビデオの長さは375226フレーム、最初の呼び出しでは375195フレーム、そして2回目の呼び出しでは375200でした。したがって、2回目の呼び出しでは、警告メッセージも大幅に少なくなり、5フレーム少なくなりました。

その後のテストで、-framerateと-rは不要であり、2つの同期フラグを使用するだけで十分であることがわかりました。これは上記の2番目の呼び出しと同じ結果を生成したので、問題を解決するために私が見つけた3番目で最も単純な呼び出しはこれです:

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

さらに別のファイルでは、同期フラグを付けてもこれらの警告の束が続いて生成されましたが、レートフラグを追加することでそれを「修正」しました(数千の警告の代わりに2つのみ)。そのため、3回目の呼び出しではうまくいかないときに2回目の呼び出しがうまくいくことがあります。私の当面の目的のために私は2回目の呼び出しに落ち着くつもりであり、それがこれらの問題の大部分を解決することを願っています。

これはすべてffmpegバージョン4.0のものでした。

15
larryy

SourceForgeのDVDStylerプロジェクトのメンテナの1人は、これについて this と述べています。

2015年1月15日以降のFFMpegバージョンでは、多くの場合この警告が表示されます。それは可能なレート制御歪みについて警告するために追加されました、さもなければそれは害を引き起こしません。

85
Josh Davis

この警告メッセージは、高フレームレートのソースを低フレームレートの出力にエンコードしようとしたときに表示されます。つまり、フレームをドロップする必要があります。


一連の画像をビデオに変換したいため、このエラーが発生しました。

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オプションや、むしろimage2またはv4l2入力フォーマットで使うときは、-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を遅くしないために推測します、参照:

52
mxmlnkn

ソースコード を見ると、入力ストリームの表示時間(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;
    }

これはほんの一見ですので、もっと深く掘り下げてください。

47
Erik

FFmpeg issue#4700 - 過去の期間0.999992が大きすぎます これは単なる警告です。つかいます:

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

それを止めるために。

ネッド

2
Ned