Estoy intentando grabar mi pantalla sin pérdidas (o con una calidad casi sin pérdidas) con aceleración de hardware en un 6700 XT con ffmpeg. Estoy ejecutando Linux Mint con el 5.14.14-051414-generic
kernel.
He intentado:
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
dice que está grabando a 60 fps, pero la grabación está entrecortada y ligeramente descolorida. Supongo que el problema del color se debe al formato de color nv12, pero rgb
aparece rgb8
un error.
También intenté usar 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
Pero me da el error:
[kmsgrab @ 0x558f001c8d80] Using plane 65 to locate framebuffers.
[kmsgrab @ 0x558f001c8d80] Failed to get framebuffer 127: Invalid argument.
pipe:: Invalid argument
El número que sigue Failed to get framebuffer
suele ser 127
o en algún lugar entre 134
y 136
.
Recibí estos comandosaquí.
Respuesta1
Creo que la codificación verdaderamente sin pérdidas solo se puede realizar en software, pero con tasas de bits más altas puede verse bastante bien.
Además, la wiki de ffmpeg dice que VAAPI solo es compatible parcialmente con GPU AMD.
Pero sospecho que actualmente podrías estar usando la GPU integrada de la CPU de todos modos, lo que podría provocar problemas de rendimiento:
Si tiene varios dispositivos utilizables en la misma máquina (por ejemplo, una GPU integrada Intel y una tarjeta gráfica discreta AMD), se pueden usar simultáneamente para decodificar diferentes transmisiones:
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...
¿Has mirado si hay más de un dispositivo hw disponible?
Intentarls /dev/dri/para ver qué dispositivos están disponibles.
No importa si usó el dispositivo correcto o no, el-qp 0La opción probablemente no funcionará según lo previsto, así que inténtelo con los comandos exactos dados y vea si dan mejores resultados:
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
o
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
Solo se cambió la resolución, y si encontró otro dispositivo hardware, puede intentar cambiar esto también.
Me interesaría si puede obtener buena calidad con tasas de bits/tamaño de archivo razonables, así que avíseme si tuvo éxito.
Por cierto, lo siguiente no utiliza aceleración hw, sino codificación sin pérdidas, por lo que puedes probar esta también:https://trac.ffmpeg.org/wiki/Capture/Desktop#lossless-recording
Para acelerar el proceso de codificación, puede utilizar la codificación sin pérdidas y desactivar las opciones avanzadas del codificador, por ejemplo:
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 le dice a x264 que codifique en modo sin pérdidas; -preset ultrafast le recomienda hacerlo rápido. Tenga en cuenta el uso de libx264rgb en lugar de libx264; este último haría una conversión con pérdida de RGB a yuv444p (yuv444p de 8 bits no es suficiente para preservar RGB de 8 bits, se necesita YCbCr de 10 bits). ...
El codificador debe ser lo suficientemente rápido en la mayoría del hardware moderno para grabar sin ninguna caída de fotogramas e incluso dejar suficiente espacio de CPU para otras aplicaciones.
Si va a archivar la grabación o le preocupa el tamaño del archivo, vuelva a codificarla sin pérdidas, pero con un ajuste preestablecido más lento. ...
Respuesta2
TL, DR: Creo que la mayoría de las veces has encontrado errores en ffmpeg y/u otras partes de la pila que ya parecen estar solucionados.
Tu primer comando:
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
A mí me funciona, en Debian Bookworm con ffmpeg 5.1 (solo cambié el tamaño para que coincida con mi monitor), sin problemas de color y 60 fps, en la misma GPU (6700 XT). Entonces, tal vez hubo (en ese momento) un error en algún lugar de su versión de ffmpeg o en los controladores VA-API o algo así.
No utiliza la calidad más alta, -qp 0
puede estar fuera del rango admitido para este codificador y posteriormente ignorarse, aparentemente vuelve a un valor predeterminado:
No quality level set; using default (20).
Valores tan bajos como -qp 1
parecen ser aceptados y pueden aportar suficiente calidad para sus necesidades.
Con respecto a kmsgrab, tenga en cuenta que su uso requiere ejecutarlo como root o tener configurada la capacidad CAP_SYS_ADMIN. Esta bien puede ser la causa de su error y una solución es configurar la capacidad en ffmpeg:
setcap cap_sys_admin=ep /usr/bin/ffmpeg
Esto no es ideal para la seguridad y se romperá cuando se actualice ffmpeg, pero funciona y su línea de comando también funciona bien para mí.
Tenga en cuenta también que el uso de kmsgrab mientras se grababa audio causaba problemas de sincronización de audio/vídeo hasta al menos ffmpeg 5.1:
https://trac.ffmpeg.org/ticket/8377
Si desea usarlo, probablemente desee actualizar a ffmpeg 6, que en mi experiencia solucionó el último problema.
Respuesta3
Esto se preguntó ayer y la respuesta sigue siendo la misma: los códecs de video HW no admiten el cambio del factor de cuantificación, es decir, crf
y más aún, no admiten la codificación sin pérdidas.
Dehttps://trac.ffmpeg.org/wiki/Hardware/VAAPI
Opciones de mapeo de libx264
Actualmente no se admite ningún modo similar a CRF. El único modo de calidad constante es CQP (parámetro de cuantificación constante), que no tiene adaptabilidad al contenido de la escena. Sin embargo, permite diferentes configuraciones de calidad para diferentes tipos de fotogramas, para mejorar la compresión gastando menos bits en fotogramas B sin referencia; consulte las opciones (i|b)_q(factor|offset). El modo CQP no se puede combinar con una tasa de bits máxima o un tamaño de búfer.