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

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

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

私は試した:

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

ffmpeg60fpsで録画すると言いますが、録画が不均一で色も若干異なります。色の問題はカラーフォーマットnv12で発生すると仮定しますが、rgbORrgb8でエラーが発生します。

私も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 am

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

努力する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#lossless-recording

エンコードプロセスを高速化するには、ロスレスエンコーディングを使用し、次の高度なエンコーダオプションを無効にできます。

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

私はffmpeg 5.1(モニターに合わせてサイズだけを変更します)を使ってDebian Bookwormを使っています。したがって、(当時)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

昨日、誰かがこの質問をしましたが、答えはまだ同じです。ハードウェアビデオコーデックは量子化要素の変更、すなわちcrfそれ以上をサポートしないので、ロスレスエンコーディングをサポートしない。

~からhttps://trac.ffmpeg.org/wiki/Hardware/VAAPI

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

CRFに似たモードは現在サポートされていません。唯一の一定の品質モードは、シーンコンテンツに適応できないConstant Quantization Parameter(CQP)です。しかしながら、様々なフレームタイプに対して様々な品質設定を可能にし、参照されないBフレームに少ないビットを使用して圧縮を改善する。 (i|b)_q(factor|offset) オプションを参照してください。 CQP モードは、最大ビットレートまたはバッファサイズでは使用できません。

関連情報