完璧な解決策: 非常に類似したフレームの繰り返しを減らし、(ピーク)可変フレームレートで出力を保存する

完璧な解決策: 非常に類似したフレームの繰り返しを減らし、(ピーク)可変フレームレートで出力を保存する

FFMPEG/libx264に固定フレームレートを指定する代わりに(-r/-framerate)、最大値で可変フレームレートを指定し、libx264が適切と判断したフレームレートを下げることができるようにしたいと思います。ここでの考え方は、拡張された静止フレーム(これはたくさん私のソースビデオで。

予測または双方向 MPEG フレームは圧縮率が非常に高いことはわかっていますが、ソース フレーム レートがトランスコード先のフレーム レートよりも小さい可能性もあります (その結果、ストリームが大きくなる可能性があります)。

答え1

あなたも答えを見つけられなかったことにイライラしていましたが、少なくともVFR(Vではない)を有効にする方法について他の人の質問に答えるつもりでした。BR) FFMPEGからの出力。

その答えは、奇妙な名前の-vsyncオプションです。いくつかの異なるオプションを設定できますが、必要なのは「2」またはですvfr。マニュアルページから引用します。

-vsync パラメータ
ビデオ同期方法。互換性のため、古い値は数値として指定できます。新しく追加された値は常に文字列として指定する必要があります。

  • 0、パススルー

    • 各フレームはタイムスタンプとともにデマルチプレクサーからマルチプレクサーに渡されます。
  • 1、参考文献

    • 要求された一定のフレーム レートを正確に達成するために、フレームは複製され、ドロップされます。
  • 2、vfr

    • 2 つのフレームが同じタイムスタンプを持つことがないように、フレームはタイムスタンプとともに渡されるか、ドロップされます。
  • 落とす

    • パススルーと同じですが、すべてのタイムスタンプを破棄し、マルチプレクサーがフレームレートに基づいて新しいタイムスタンプを生成するようにします。
  • -1、自動

    • muxer の機能に応じて 1 と 2 のいずれかを選択します。これがデフォルトの方法です。

タイムスタンプは、この後、マルチプレクサによってさらに変更される可能性があることに注意してください。たとえば、フォーマットオプションがネガティブなことを避ける有効になっています。

-map を使用すると、どのストリームからタイムスタンプを取得するかを選択できます。ビデオまたはオーディオのいずれかを変更せずに、残りのストリームを変更されていないストリームに同期させることができます。

しかし、私は、誰もが抱いているような「サブ質問」に答えるだけのコメントを投稿するほどの評判を持っていません。しかし、正直あまり楽観的ではないアイデアがいくつかありました...しかし、私が実際に試した最初のものは働いた。 それで。

-vsync 2オプションをオプションと組み合わせるだけで-r $maxfps、もちろん、必要な最大フレームレートに置き換えるだけ$maxfpsです。そして、それは機能します! ソース ファイルからフレームを複製するのではなく、ファイルが最大フレームレートを超える原因となるフレームを削除します。

デフォルトでは、それ-r $maxfps自体では、一定のフレームレートを実現するためにフレームを複製/ドロップするだけであり、それ-vsync 2自体では、PTS 値に実際に影響を与えることなくフレームを直接取り込むことになるようです。

私はこれについて楽観的ではありませんでした-r $maxfps。なぜなら、これによってフレーム レートが一定になることはすでにわかっていたからです。正直なところ、エラーが発生するか、最初または最後に発生したもの、あるいはその他のものに従うだけになるだろうと思っていました。まさに私が望んでいたとおりの動作をしてくれたので、FFMPEG の開発者には非常に満足しています。

これがあなたや、後でこれを知る必要がなくなった他の誰かの役に立つことを願っています。

答え2

可変フレームレートを最大値で指定し、libx264が適切と判断したフレームレートを下げることを許可したいと思います。ここでの考え方は、拡張された静止フレームのようなものがある場合に追加の圧縮を得ることです。

私の理解では、これは比較的不器用な方法で可能かもしれないが、いくつかの複雑で直感に反する理由から望ましくない。

x264 ストリームにはフレームレートがありますが、フレームレートはコーデックの問題というよりもコンテナ レベルの問題です。

パススルー VFR エンコードでは、基本的に、どのフレーム/時間でどのフレーム レートであるかを詳細に記述したテキスト ファイルが存在し、ソースをエンコードする際に、tcfile-in や tcfile-out などの関数がタイムスタンプをエンコードに渡して、レートの場所をマッピングし、ビデオをソースと主観的に一致させます。

低フレームレートのアイデアは論理的ですが、いくつかの理由でうまくいきません。x264 はいくつかの機能で VFR を認識しますが、ファイル サイズを小さくするために動きに応じてフレームレートを変更する分析機能 (多くのビットレート制御に類似した方法) はないと思います。

ソースも問題です。VFR ソースはデフォルトでフレームの可変性を保持しますが、CFR ファイルを可変ビットレートでエンコードすると (特にテレシネが必要な場合には良いアイデアです)、同じ CFR が生成されるようです。

つまり、おそらく手動でビットレートを書き直す必要があるでしょう(つまり、遅いシーンのタイムスタンプをファイルに多重化します)、またはavisynth 用の dup、dedup、exactDedup などのフレーム デシメーション アルゴリズム動画の動きが極端に少ない場合、一部のフレーム (半分でも?) が破棄されます。問題は、これらのアルゴリズムが高度ではなく、最良のエンコードに寄与するものに関して「実際の」映像で適切な選択を行えないことです。

また、I フレームや B フレームなどを含むフレームを削除すると、時間の経過とともに利用可能な詳細の量が減少し、動きが「階段状」に見え、他の基本的なビデオ パラメータに干渉して、エイリアシングなどのアーティファクトが発生する可能性があります。

また、量子化器の動作方法により、x264 は動きの少ないシーンでは実際にビットレートを不釣り合いにさらに下げます。 同一の画像のスライドショーがない限り、動き (粒子やその他のアーティファクトのみ) があり、ビットレートを大幅に変更しない限りは目に見えない品質の低下が発生します。

そして最後に、希望どおりのことをするための選択肢があまりない理由は、x264 が時間的圧縮 (部分的なフレームの変更の記録) のみを使用してビットレートを管理するのに非常に優れているためです。フレームレートを 1/2 にしてもファイル サイズは半分にはなりません。動きが少ない場合やアニメーションの場合は、10% が現実的な増加と考えられます。

つまり、静止シーンのビットレートを下げてもファイル サイズはほとんど変わりませんが、品質や同期に関するさまざまな問題が発生し、ビデオ編集ソフトウェアとの互換性も失われます。

デシメータを試してみたい場合は、レベルオプション、それぞれが最大解像度とフレームレートを指定します。残念ながら、プロファイルを使用して、必要なフレームレートを得るには、おそらく非常に低い解像度で作業する必要があります。レートを完全に手動で編集するか、高すぎると思われるフレームレートを修正する必要があります。いずれにしても、tcfile が保存されるエンコード プロセス後に変更が加えられた場合、サウンドを新しいフレームレートと同期させるには、調整が必要になります。

重要なのは、多くのビットレート設定を最適化することに時間を費やすと、ファイル サイズ管理の面ではるかに多くの成果が得られ、ビデオの品質が向上し、メリットがほとんどないまま複雑になるよりも良いということです。放送やメディア標準を目指しているのでない限り、元の FPS を維持するのがおそらく最善の策です。プレーヤーはさまざまなビットレートに対応できるように適切に設計されており (NLE とは異なります)、ビデオのフレーム数が多いほど、フレーム間の動きの変化が小さくなるため、再生がスムーズになり、ファイル サイズも小さくなる可能性があります。

以下に、エンコードのこのわかりにくい側面を解決するのに役立つ標準情報とフォーラムのディスカッションへのリンクのコレクションを示します。

-AviSynth デシメーション ツール

-fps および -r スイッチ
-x264 一般 (tcfile、fps)
-タイムコードファイル規格
-レベルとプロフィール
-簡潔でわかりやすい CFR/VFR 設定の概要 (「フレームレート」セクション)

doom9、videohelp、その他の理論的な議論
1 2 3 4 5 6 7

答え3

完璧な解決策: 非常に類似したフレームの繰り返しを減らし、(ピーク)可変フレームレートで出力を保存する

  • 長い静止シーンを含むコンテンツの場合、重複フレームを削除すると、フレームレートが動的に大幅に低下し、コーデックとそのフレーム内圧縮で達成できるよりも大きなファイルサイズの削減が実現します。
  • 私の例では:
    • 60 FPS で 100% オリジナルのメザニン ファイル サイズ
    • 60 FPS 一定フレームレートで 15% CR28
    • 60 FPS のピーク フレーム レートで 6% CR28 (ほぼ 3 倍!)

オリジナルあり

ffmpeg -i screen-recording.mov -movflags faststart -c:v libx264 -vf mpdecimate -vsync vfr -r 120 -preset veryslow -crf 24 screen-recording-vfr.mp4

すでに圧縮されたビデオを再エンコードせずにダイナミックフレームレートにトランスコードする

ffmpeg -i video-export-old.mp4 -vf mpdecimate -vsync vfr video-export-mpdecimated-without-reencoding.mp4

詳細に

オリジナルあり

ffmpeg -i screen-recording.mov -movflags faststart -c:v libx264 -vf mpdecimate -vsync vfr -r 120 -preset veryslow -crf 24 "screen-recording-vfr.mp4"

-i video-mezzanine.mov   Original or your high quality rendered export as the input file.
-movflags faststart      Streaming ready by putting the moov atom to the file start.
-c:v libx264             H-264 codec
-vf mpdecimate           Drop frames not differing greatly from previous frame to reduce frame rate.
-vsync vfr               Output as variable frame rate (vfr)! Necessary sister option to 'mpdecimate'.
                         - To maintain the playback speed while benefitting from the file size reduction.
-r 30                    If you specify -r then in this combo it serves as the peak framerate!
                         I recommend to omit this option:
                         - Then the peak framerate IS the peak/constant rate of the source.
                         - Which preserves dynamic scenes fully and compresses long still sequences.
                         - So the best of both aspects.
                         - State a peak FPS if loosing FPS in dynamic scenes
                           is acceptable for the reduction in file size.
-crf 24                  - Constant Rate Factor (constant quality at variable bitrate)
-preset veryslow         - Quality effort put into the encoding
screen-recording-vfr.mp4 - Output file

すでにエクスポートしたビデオを再エンコードせずにダイナミックフレームレートに変換する

ffmpeg -i video-export-old.mp4 -vf mpdecimate -vsync vfr video-export-mpdecimated.mp4

  • これはロスレス操作です。ロスレスの再エンコードは行われず、再パック/再参照のみが行われます。

  • 重複するフレームを可能な限り削除します。

例:

  • トランジションなしの静止画像 3 枚のみのスライドショー * 各 5 秒間 * 50 FPS = 750 フレーム

  • ffmpeg実際に 1/5 (=0.2) FPS で 3 フレームに削減されます。mediainfo で確認済みです。

分析と学習

  • 静止画シーンが長い動画では、フレーム数とファイルサイズが大幅に削減されます。
  • どちらのシナリオでも
    • 同じCFRでメザニンファイルからエンコードすると、視覚的な品質が維持されます。
      • ただし、固定フレームレートから可変フレームレートへのファイル サイズの削減は 15% から 6% です。
    • 再エンコードせずにフレームレートを下げると、ファイルサイズの削減効果は小さくなりますが、それでも次のようになります。
      • ファイルサイズが削減されます(15%から10%)
screen-recording.mov
- Frame rate mode: Variable
- Frame rate: 58.628 FPS
- Minimum frame rate: 30.000 FPS
- Maximum frame rate: 60.000 FPS
- Frame count: 732                100 %
- Size: 1675084 bytes             100 %

screen-recording CR24 fps 60.mp4
- Frame rate mode: Constant
- Frame rate: 60.000 FPS
- Frame count: 750                102 %
- Size: 255863 bytes               15 %

screen-recording CR24 mpdecimated vfr.mp4
- Frame rate mode: Variable
- Frame rate: 17.398 FPS
- Minimum frame rate: 1.132 FPS
- Maximum frame rate: 60.000 FPS
- Frame count: 214                 29 %
- Size: 101860 bytes                6 %


screen-recording CR24 mpdecimated fps 30 max.mp4
- Frame rate mode: Variable
- Frame rate: 11.078 FPS
- Minimum frame rate: 1.154 FPS
- Maximum frame rate: 30.000 FPS
- Frame count: 137                 17 %
- Size: 94382 bytes                 5.6

screen-recording CR24 mpdecimated vfr without re-encoding faststart.mp4
- Frame rate mode: Variable
- Frame rate: 19.974 FPS
- Minimum frame rate: 1.132 FPS
- Maximum frame rate: 60.000 FPS  
- Frame count: 247                 33 % 
- Size: 165 KB (164947 bytes)      10 %


関連情報