我正在嘗試使用 ffmpeg 在 6700 XT 上透過硬體加速無損(或接近無損品質)錄製螢幕。我正在使用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
ffmpeg
據說它以 60 fps 的速度錄製,但錄製的內容不連貫,而且顏色略有偏差。我假設顏色問題來自顏色格式 nv12,但是rgb
orrgb8
給了錯誤。
我也嘗試過使用 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 jaccel_device intel -i ... -hwaccel vaapi -hwaccel_device amamd -
您是否查看過是否有多個可用的硬體設備?
嘗試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 建議它做得這麼快。注意使用 libx264rgb 而不是 libx264;後者會進行從 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 上工作(我只更改了大小以匹配我的顯示器),沒有顏色問題和 60 fps,在相同的 GPU (6700 XT) 上。所以也許(當時)您的 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 的模式。唯一的恆定品質模式是 CQP(恆定量化參數),它對場景內容沒有適應性。然而,它確實允許對不同的幀類型進行不同的品質設置,透過在未引用的 B 幀上花費更少的位元來提高壓縮 - 請參閱 (i|b)_q(factor|offset) 選項。 CQP 模式不能與最大位元速率或緩衝區大小結合使用。