Аппаратное ускорение записи без потерь на 6700 XT с использованием ffmpeg

Аппаратное ускорение записи без потерь на 6700 XT с использованием ffmpeg

Я пытаюсь записать свой экран без потерь (или с почти без потерь качества) с аппаратным ускорением на 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

ffmpegговорит, что записывает на 60 кадров в секунду, но запись прерывистая и слегка искажена по цвету. Я предполагаю, что проблема с цветом из-за цветового формата nv12, но rgbor rgb8выдает ошибку.

Я также пробовал использовать 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 говорится, что VAAPI поддерживается только частично для графических процессоров AMD.

Но я подозреваю, что в настоящее время вы в любом случае используете встроенный графический процессор ЦП, что может привести к проблемам с производительностью:

Если на одном компьютере имеется несколько используемых устройств (например, интегрированный графический процессор Intel и дискретная видеокарта 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#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). ...

Кодер должен быть достаточно быстрым на большинстве современных аппаратных средств, чтобы записывать без потери кадров и даже оставлять достаточно ресурсов ЦП для других приложений.

Если вы собираетесь архивировать запись или беспокоитесь о размере файла, перекодируйте ее без потерь еще раз, но с более медленной предустановкой. ...

решение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 (я только изменил размер, чтобы он соответствовал моему монитору), без проблем с цветом и 60 кадров в секунду, на том же 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, но это работает, и ваша командная строка у меня тоже работает нормально.

Обратите внимание, что использование kmsgrab при одновременной записи звука приводило к проблемам синхронизации аудио/видео до версии ffmpeg как минимум 5.1:

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

Если вы хотите его использовать, вам, вероятно, следует обновиться до ffmpeg 6, которая, по моему опыту, исправила последнюю проблему.

решение3

Этот вопрос был задан вчера, и ответ остался прежним: аппаратные видеокодеки не поддерживают изменение коэффициента квантования, т.е. crfи тем более не поддерживают кодирование без потерь.

Отhttps://trac.ffmpeg.org/wiki/Оборудование/VAAPI

Параметры отображения из libx264

В настоящее время не поддерживается режим типа CRF. Единственный режим постоянного качества — CQP (постоянный параметр квантования), который не имеет адаптивности к содержимому сцены. Однако он допускает различные настройки качества для разных типов кадров, чтобы улучшить сжатие, тратя меньше бит на нереферентные B-кадры — см. параметры (i|b)_q(factor|offset). Режим CQP нельзя комбинировать с максимальным битрейтом или размером буфера.

Связанный контент