ffmpeg を使用した 6700 XT でのハードウェア アクセラレーションによるロスレス録画

ffmpeg を使用した 6700 XT でのハードウェア アクセラレーションによるロスレス録画

6700 XT のハードウェア アクセラレーションを使用して、ffmpeg で画面をロスレス (またはロスレスに近い品質) で録画しようとしています。カーネルで Linux Mint を実行しています5.14.14-051414-generic

私はもう試した:

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 2560x1440 -i :0 -r 60 -vf 'hwupload,scale_vaapi=format=nv12' -c:v h264_vaapi -qp 0 output.mp4

ffmpeg60 fps で録画していると表示されますが、録画が途切れ途切れで、色が少しずれています。色の問題はカラー フォーマット nv12 によるものだと思いますが、エラーが発生しますrgbrgb8

kmsgrab も使ってみました:

ffmpeg -device /dev/dri/card0 -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,scale_vaapi=w=2560:h=1440:format=nv12' -c:v h264_vaapi -qp 0 output.mp4

しかし、次のエラーが発生します:

[kmsgrab @ 0x558f001c8d80] Using plane 65 to locate framebuffers.
[kmsgrab @ 0x558f001c8d80] Failed to get framebuffer 127: Invalid argument.
pipe:: Invalid argument

後の数字はFailed to get framebuffer通常127または134からの間のいずれかになります136

私はこれらのコマンドを受け取りましたここ

答え1

本当のロスレス エンコーディングはソフトウェアでしか実行できないと思いますが、ビットレートが高ければ十分に見栄えが良くなるかもしれません。

また、ffmpeg wiki には、VAAPI は AMD GPU に対して部分的にのみサポートされていると記載されています。

しかし、現在 CPU の統合 GPU を使用している可能性があり、パフォーマンスの問題が発生する可能性があります。

同じマシンに複数の使用可能なデバイスがある場合 (たとえば、Intel 統合 GPU と AMD ディスクリート グラフィック カード)、それらを同時に使用して異なるストリームをデコードできます。

ffmpeg -init_hw_device vaapi=intel:/dev/dri/renderD128 -init_hw_device vaapi=amd:/dev/dri/renderD129 -hwaccel vaapi -hwaccel_device intel -i ... -hwaccel vaapi -hwaccel_device amd -i ...

利用可能なハードウェア デバイスが複数あるかどうか確認しましたか?

試すls /dev/dri/利用可能なデバイスを確認します。

適切なデバイスを使用したかどうかに関係なく、-qp 0オプションは意図したとおりに動作しない可能性が高いため、指定されたコマンドを正確に実行して、より良い結果が得られるかどうかを確認してください。

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 1920x1080 -i :0 -vf 'hwupload,scale_vaapi=format=nv12' -c:v h264_vaapi -qp 24 output.mp4

または

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 1920x1080 -i :0 -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp 24 output.mp4

解像度だけを変更し、別のハードウェア デバイスを見つけた場合は、これも変更してみてください。

適切なビットレート/ファイル サイズで良好な品質を実現できるかどうか興味がありますので、成功した場合はお知らせください。

ちなみに、以下はハードウェア アクセラレーションではなくロスレス エンコーディングを使用しているので、これも試してみるとよいでしょう。https://trac.ffmpeg.org/wiki/Capture/Desktop#ロスレス記録

エンコード プロセスを高速化するには、ロスレス エンコードを使用し、高度なエンコーダー オプションを無効にすることができます。例:

ffmpeg -video_size 1920x1080 -framerate 30 -f x11grab -i :0.0 -c:v libx264rgb -crf 0 -preset ultrafast -color_range 2 output.mkv

-crf 0 は x264 にロスレス モードでエンコードするように指示します。-preset ultrafast は高速にエンコードするように指示します。libx264 ではなく libx264rgb を使用することに注意してください。後者は RGB から yuv444p へのロスのある変換を行います (8 ビット yuv444p では 8 ビット RGB を保持するには不十分で、10 ビット YCbCr が必要です)。...

エンコーダーは、ほとんどの最新ハードウェアでフレームドロップなしで録画できるほど高速で、他のアプリケーション用に十分な CPU ヘッドルームも残す必要があります。

録音をアーカイブする場合やファイル サイズが気になる場合は、より遅いプリセットを使用して、再度ロスレスでエンコードします。...

答え2

TL,DR: ffmpeg やスタックの他の部分で、今では修正されていると思われるバグに遭遇したと思います。

最初のコマンド:

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 2560x1440 -i :0 -r 60 -vf 'hwupload,scale_vaapi=format=nv12' -c:v h264_vaapi -qp 0 output.mp4

私の環境では、Debian Bookworm で ffmpeg 5.1 を使って (モニターに合わせてサイズを変更しただけです)、色の問題もなく、同じ GPU (6700 XT) で 60 fps で動作しました。そのため、おそらく (当時は) ffmpeg のバージョンか VA-API ドライバーか何かにバグがあったのでしょう。

最高品質は使用されず、-qp 0このエンコーダーでサポートされている範囲外である可能性があり、その後無視され、デフォルト値に戻るようです。

No quality level set; using default (20).

できるだけ低い値でも-qp 1受け入れられ、ニーズに十分な品質をもたらす可能性があります。


kmsgrab に関しては、これを使用するには、root として実行するか、CAP_SYS_ADMIN 権限を設定する必要があることに注意してください。これがエラーの原因である可能性があり、修正するには、ffmpeg で権限を設定します。

setcap cap_sys_admin=ep /usr/bin/ffmpeg

これはセキュリティ上理想的ではなく、ffmpeg が更新されると機能しなくなりますが、機能し、コマンドラインも問題なく動作します。

また、少なくとも ffmpeg 5.1 までは、オーディオを録音しながら kmsgrab を使用すると、オーディオとビデオの同期の問題が発生することにも注意してください。

https://trac.ffmpeg.org/ticket/8377

これを使用したい場合、おそらく ffmpeg 6 にアップグレードする必要があります。私の経験では、これで最後の問題は解決しました。

答え3

これは昨日も質問されましたが、答えは同じです。HW ビデオ コーデックは量子化係数の変更をサポートしていません。つまり、crfロスレス エンコーディングもサポートしていません。

からhttps://trac.ffmpeg.org/wiki/ハードウェア/VAAPI

libx264 からのマッピング オプション

現在、CRF のようなモードはサポートされていません。唯一の一定品質モードは CQP (一定量子化パラメータ) で、シーン コンテンツへの適応性はありません。ただし、フレーム タイプごとに異なる品質設定が可能で、参照されていない B フレームに費やすビット数を減らすことで圧縮率が向上します ((i|b)_q(factor|offset) オプションを参照)。CQP モードは、最大ビットレートまたはバッファ サイズと組み合わせることはできません。

関連情報