Saltar al contenido

¿Cómo se consigue que FFMPEG codifique con vaapi?

Ya no tienes que indagar más por otras webs ya que has llegado al espacio justo, poseemos la respuesta que necesitas hallar pero sin problemas.

Solución:

A partir de hoy, FFmpeg y libav han implementado codificación acelerada por hardware a través de VAAPI en plataformas compatibles y SKU de hardware, y he escrito un artículo sobre el mismo que le permitirá configurar, implementar y usar tanto ffmpeg como libav para lograr el mismo efecto.

Y en la misma nota, agregué referencias a los límites de la superficie del hardware para que sepa qué plataformas de hardware admiten códecs de video específicos para usar con la codificación VAAPI.

A continuación, se muestra un ejemplo de compilación de FFmpeg que se carga a través del sistema de módulos de entorno, paso a paso:

Como ejemplo, la construcción de un FFmpeg habilitado para VAAPI con soporte para decodificación y aceleración de hardware de codificación VP8 / 9 en un banco de pruebas de validación Skylake:

Plataforma de compilación: Ubuntu 16.04LTS.

Lo primero es lo primero:

Primero construya la cadena de dependencia.

  1. cmrt:

Este es el C para Media Runtime GPU Kernel Manager para la familia de gráficos Intel G45 y HD. es un requisito previo para crear el paquete de controladores híbridos intel.

git clone https://github.com/01org/cmrt
cd cmrt
./autogen.sh
./configure
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
sudo ldconfig -vvvv
  1. controlador-intel-híbrido:

Este paquete proporciona soporte para los códecs VPx del proyecto WebM. La aceleración de GPU se proporciona a través de núcleos de medios ejecutados en GPU Intel GEN. El controlador híbrido proporciona la decodificación de entropía unida a la CPU (por ejemplo, CPBAC) y administra los parámetros y búferes del kernel de medios GEN GPU.

Es un requisito previo para construir libva con la configuración deseada para que podamos acceder a las capacidades de decodificación híbrida de la serie VPX en configuraciones de hardware compatibles.

git clone https://github.com/01org/intel-hybrid-driver
cd intel-hybrid-driver
./autogen.sh
./configure
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
sudo ldconfig -vvv
  1. Intel-vaapi-driver:

Este paquete proporciona el controlador de modo de usuario VA-API (Video Acceleration API) para las SKU de la familia Intel GEN Graphics. El back-end del controlador de video actual proporciona un puente a las GPU GEN a través del empaquetado de búferes y comandos que se enviarán al controlador i915 para ejercitar la funcionalidad de hardware y sombreado para la decodificación, codificación y procesamiento de video. También proporciona un contenedor para el controlador híbrido intel cuando se llama para manejar tareas de decodificación híbrida VP8 / 9 en hardware compatible (debe configurarse con el --enable-hybrid-codec opción).

git clone https://github.com/01org/intel-vaapi-driver
cd intel-vaapi-driver
./autogen.sh
./configure --enable-hybrid-codec
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
sudo ldconfig -vvvv
  1. libva:

Libva es una implementación para VA-API (Video Acceleration API)

VA-API es una biblioteca de código abierto y una especificación de API, que proporciona acceso a las capacidades de aceleración de hardware de gráficos para el procesamiento de video. Consiste en una biblioteca principal y backends de aceleración específicos del controlador para cada proveedor de hardware compatible.

git clone https://github.com/01org/libva
cd libva
./autogen.sh
./configure
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
sudo ldconfig -vvvv

Cuando termine, pruebe el conjunto de características compatibles con VAAPI ejecutando vainfo:

vainfo

La salida en mi banco de pruebas actual es:

libva info: VA-API version 0.40.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_40
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.40 (libva 1.7.3)
vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.3.pre1 (glk-alpha-58-g5a984ae)
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Simple            : VAEntrypointEncSlice
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointEncSliceLP
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointEncSliceLP
      VAProfileH264MultiviewHigh      : VAEntrypointVLD
      VAProfileH264MultiviewHigh      : VAEntrypointEncSlice
      VAProfileH264StereoHigh         : VAEntrypointVLD
      VAProfileH264StereoHigh         : VAEntrypointEncSlice
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointEncPicture
      VAProfileVP8Version0_3          : VAEntrypointVLD
      VAProfileVP8Version0_3          : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileVP9Profile0            : VAEntrypointVLD

Hacer una compilación de FFmpeg utilizable para probar los codificadores:

Ahora, crearemos un binario FFmpeg que puede aprovechar VAAPI para probar las capacidades de codificación y decodificación en Skylake, usando un prefijo personalizado porque cargamos FFmpeg a través del sistema de módulos de entorno en el banco de pruebas.

Prepare los directorios de destino primero:

sudo mkdir -p /apps/ffmpeg/dyn
sudo chown -Rc $USER:$USER /apps/ffmpeg/dyn
mkdir -p ~/ffmpeg_sources

Incluya componentes adicionales según sea necesario:

(a). Construya e implemente nasm:
Nasm es un ensamblador para optimizaciones x86 utilizado por x264 y FFmpeg. Muy recomendable o su construcción resultante puede ser muy lenta.

Tenga en cuenta que ahora hemos cambiado de Yasm a nasm, ya que este es el ensamblador actual que están adoptando x265, x264, entre otros.

cd ~/ffmpeg_sources
wget wget http://www.nasm.us/pub/nasm/releasebuilds/2.14rc0/nasm-2.14rc0.tar.gz
tar xzvf nasm-2.14rc0.tar.gz
cd nasm-2.14rc0
./configure --prefix="/apps/ffmpeg/dyn" --bindir="/apps/ffmpeg/dyn/bin"
make -j$(nproc) VERBOSE=1
make -j$(nproc) install
make -j$(nproc) distclean

(B). Construya e implemente libx264 estáticamente:
Esta biblioteca proporciona un codificador de video H.264. Consulte la Guía de codificación H.264 para obtener más información y ejemplos de uso. Esto requiere que ffmpeg se configure con –habilitar-gpl–enable-libx264.

cd ~/ffmpeg_sources
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="/apps/ffmpeg/dyn/bin:$PATH" ./configure --prefix="/apps/ffmpeg/dyn" --bindir="/apps/ffmpeg/dyn/bin" --enable-static --disable-opencl
PATH="/apps/ffmpeg/dyn/bin:$PATH" make -j$(nproc) VERBOSE=1
make -j$(nproc) install VERBOSE=1
make -j$(nproc) distclean

(C). Construya y configure libx265:
Esta biblioteca proporciona un codificador de video H.265 / HEVC. Consulte la Guía de codificación H.265 para obtener más información y ejemplos de uso.

sudo apt-get install cmake mercurial
cd ~/ffmpeg_sources
hg clone https://bitbucket.org/multicoreware/x265
cd ~/ffmpeg_sources/x265/build/linux
PATH="$/apps/ffmpeg/dyn/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/apps/ffmpeg/dyn" -DENABLE_SHARED:bool=off ../../source
make -j$(nproc) VERBOSE=1
make -j$(nproc) install VERBOSE=1
make -j$(nproc) clean VERBOSE=1

(D). Cree e implemente la biblioteca libfdk-aac:
Esto proporciona un codificador de audio AAC. Consulte la Guía de codificación de audio AAC para obtener más información y ejemplos de uso. Esto requiere que ffmpeg se configure con –enable-libfdk-aac (y –enable-nonfree si también incluiste –habilitar-gpl).

cd ~/ffmpeg_sources
wget -O fdk-aac.tar.gz https://github.com/mstorsjo/fdk-aac/tarball/master
tar xzvf fdk-aac.tar.gz
cd mstorsjo-fdk-aac*
autoreconf -fiv
./configure --prefix="/apps/ffmpeg/dyn" --disable-shared
make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

(mi). Construye y configura libvpx

   cd ~/ffmpeg_sources
   git clone https://github.com/webmproject/libvpx/
   cd libvpx
   ./configure --prefix="/apps/ffmpeg/dyn" --enable-runtime-cpu-detect --enable-vp9 --enable-vp8 
   --enable-postproc --enable-vp9-postproc --enable-multi-res-encoding --enable-webm-io --enable-vp9-highbitdepth --enable-onthefly-bitpacking --enable-realtime-only 
   --cpu=native --as=yasm
   time make -j$(nproc)
   time make -j$(nproc) install
   time make clean -j$(nproc)
   time make distclean

(F). Construir LibVorbis

   cd ~/ffmpeg_sources
   wget -c -v http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.5.tar.xz
   tar -xvf libvorbis-1.3.5.tar.xz
   cd libvorbis-1.3.5
   ./configure --enable-static --prefix="/apps/ffmpeg/dyn"
   time make -j$(nproc)
   time make -j$(nproc) install
   time make clean -j$(nproc)
   time make distclean

(gramo). Construir FFmpeg:

cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/FFmpeg -b master
cd FFmpeg
PATH="/apps/ffmpeg/dyn/bin:$PATH" PKG_CONFIG_PATH="/apps/ffmpeg/dyn/lib/pkgconfig" ./configure 
  --pkg-config-flags="--static" 
  --prefix="/apps/ffmpeg/dyn" 
  --extra-cflags="-I/apps/ffmpeg/dyn/include" 
  --extra-ldflags="-L/apps/ffmpeg/dyn/lib" 
  --bindir="/apps/ffmpeg/dyn/bin" 
  --enable-debug=3 
  --enable-vaapi 
  --enable-libvorbis 
  --enable-libvpx 
  --enable-gpl 
  --cpu=native 
  --enable-opengl 
  --enable-libfdk-aac 
  --enable-libx264 
  --enable-libx265 
  --enable-nonfree 
PATH="/apps/ffmpeg/dyn/bin:$PATH" make -j$(nproc) 
make -j$(nproc) install 
make -j$(nproc) distclean 
hash -r

Nota: Para obtener compilaciones de depuración, omita el distclean paso y encontrarás el ffmpeg_g binario en el subdirectorio de fuentes.

A menudo queremos depurar compilaciones cuando surge un problema y es posible que se requiera un rastreo de gdb para fines de depuración.

El archivo de módulos de entorno para FFmpeg (edite según sea necesario si sus prefijos difieren, y agregue conflictos si es necesario):

less /usr/share/modules/modulefiles/ffmpeg/vaapi


#%Module1.0#####################################################################
##
## ffmpeg media transcoder modulefile
## By Dennis Mungai <[email protected]>
## February, 2016
##

# for Tcl script use only
set     appname         ffmpeg
set     version         dyn
set     prefix          /apps/$appname/$version
set     exec_prefix     $prefix/bin

conflict        ffmpeg/git

prepend-path    PATH            $exec_prefix
prepend-path    LD_LIBRARY_PATH $prefix/lib

Para cargar y probar, ejecute:

module load ffmpeg/vaapi

Confirme que todo está cuerdo a través de:

which ffmpeg

Rendimiento esperado:

/apps/ffmpeg/dyn/bin/ffmpeg

Fragmentos de muestra para probar los nuevos codificadores:

Confirme que los codificadores VAAPI se hayan construido correctamente:

ffmpeg  -hide_banner -encoders | grep vaapi 

 V..... h264_vaapi           H.264/AVC (VAAPI) (codec h264)
 V..... hevc_vaapi           H.265/HEVC (VAAPI) (codec hevc)
 V..... mjpeg_vaapi          MJPEG (VAAPI) (codec mjpeg)
 V..... mpeg2_vaapi          MPEG-2 (VAAPI) (codec mpeg2video)
 V..... vp8_vaapi            VP8 (VAAPI) (codec vp8)

Consulte la documentación de ayuda de cada codificador en cuestión:

ffmpeg -hide_banner -h encoder='encoder name'

Pruebe los codificadores;

Usando GNU en paralelo, codificaremos algunos archivos mp4 (muestras de prueba 4k H.264, 40 minutos cada una, audio AAC de 6 canales) en la ruta ~ / src del sistema a VP8 y HEVC respectivamente usando los ejemplos a continuación. Tenga en cuenta que he ajustado los codificadores para que se adapten a mis casos de uso y que el cambio de escala a 1080p está habilitado. Ajuste según sea necesario.

Para VP8, lanzar 10 trabajos de codificación simultáneamente:

parallel -j 10 --verbose '/apps/ffmpeg/dyn/bin/ffmpeg -loglevel debug -threads 4 -hwaccel vaapi -i ""  -vaapi_device /dev/dri/renderD129 -c:v vp8_vaapi -loop_filter_level:v 63 -loop_filter_sharpness:v 15 -b:v 4500k -maxrate:v 7500k -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -c:a libvorbis -b:a 384k -ac 6 -f webm "..webm"' ::: $(find . -type f -name '*.mp4')

A HEVC con GNU Parallel:

Al perfil principal HEVC, el lanzamiento de 10 trabajos de codificación simultáneamente:

parallel -j 4 --verbose '/apps/ffmpeg/dyn/bin/ffmpeg -loglevel debug -threads 4 -hwaccel vaapi -i ""  -vaapi_device /dev/dri/renderD129 -c:v hevc_vaapi -qp:v 19 -b:v 2100k -maxrate:v 3500k -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -c:a libvorbis -b:a 384k -ac 6 -f matroska "..mkv"' ::: $(find . -type f -name '*.mp4')

Algunas notas:

  1. QuickSync de Intel es muy eficiente. Vea las trazas de utilización de energía y las cargas promedio del sistema con 10 codificaciones ejecutándose simultáneamente aquí.
  2. El codificador HEVC de Skylake es muy lento y sospecho que en mi hardware puede ser más lento que el codificador x265 basado en software y los codificadores HEVC de kvazaar. Sin embargo, su calidad, cuando está bien ajustada, es significativamente superior a la de otros codificadores basados ​​en hardware, como el codificador Nvidia NVENC HEVC en las SKU de la serie Maxwell GM200. Sin embargo, el codificador NVENC en Pascal es más rápido y superior al de la implementación del codificador HEVC Skylake de Intel.
  3. A diferencia de NVENC de Nvidia, no existen limitaciones de codificación simultánea en los SKU de los consumidores. Pude ejecutar 10 sesiones de codificación simultáneamente con VAAPI, mientras que con NVENC, me habría limitado a dos codificaciones simultáneas máximas en las GPU de la serie GeForce GTX en los bancos de pruebas. Buen trabajo, Intel.

Una pequeña actualización: la codificación acelerada por hardware VP9 ahora está disponible para FFmpeg. Sin embargo, necesitará una GPU integrada basada en Intel Kabylake para aprovechar esta función.

Y ahora, con el nuevo codificador vp9_vaapi, esto es lo que obtenemos.

Opciones de codificador ahora disponibles:

ffmpeg -h vp9_vaapi

Producción:

Encoder vp9_vaapi [VP9 (VAAPI)]:
    General capabilities: delay 
    Threading capabilities: none
    Supported pixel formats: vaapi_vld
vp9_vaapi AVOptions:
  -loop_filter_level         E..V.... Loop filter level (from 0 to 63) (default 16)
  -loop_filter_sharpness         E..V.... Loop filter sharpness (from 0 to 15) (default 4)

¿Qué sucede cuando intenta llevar a cabo esto en hardware no compatible, digamos Skylake?

Vea el resultado de muestra a continuación:

[Parsed_format_0 @ 0x42cb500] compat: called with args=[nv12]
[Parsed_format_0 @ 0x42cb500] Setting 'pix_fmts' to value 'nv12'
[Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'w' to value '1920'
[Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'h' to value '1080'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'video_size' to value '3840x2026'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pix_fmt' to value '0'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'time_base' to value '1/1000'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pixel_aspect' to value '1/1'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'frame_rate' to value '24000/1001'
[graph 0 input from stream 0:0 @ 0x42cce00] w:3840 h:2026 pixfmt:yuv420p tb:1/1000 fr:24000/1001 sar:1/1 sws_param:flags=2
[format @ 0x42cba40] compat: called with args=[vaapi_vld]
[format @ 0x42cba40] Setting 'pix_fmts' to value 'vaapi_vld'
[auto_scaler_0 @ 0x42cd580] Setting 'flags' to value 'bicubic'
[auto_scaler_0 @ 0x42cd580] w:iw h:ih flags:'bicubic' interl:0
[Parsed_format_0 @ 0x42cb500] auto-inserting filter 'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0'
[AVFilterGraph @ 0x42ca360] query_formats: 6 queried, 4 merged, 1 already done, 0 delayed
[auto_scaler_0 @ 0x42cd580] w:3840 h:2026 fmt:yuv420p sar:1/1 -> w:3840 h:2026 fmt:nv12 sar:1/1 flags:0x4
[hwupload @ 0x42cbcc0] Surface format is nv12.
[AVHWFramesContext @ 0x42ccbc0] Created surface 0x4000000.
[AVHWFramesContext @ 0x42ccbc0] Direct mapping possible.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000001.
[AVHWFramesContext @ 0x42c3e40] Direct mapping possible.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000002.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000003.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000004.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000005.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000006.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000007.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000008.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000009.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x400000a.
[vp9_vaapi @ 0x409da40] Encoding entrypoint not found (19 / 6).
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
[AVIOContext @ 0x40fdac0] Statistics: 0 seeks, 0 writeouts
[aac @ 0x40fcb00] Qavg: -nan
[AVIOContext @ 0x409f820] Statistics: 32768 bytes read, 0 seeks
Conversion failed!

Los bits interesantes son las advertencias de punto de entrada para la codificación VP9 que está ausente en esta plataforma en particular, como lo confirma la salida de vainfo:

libva info: VA-API version 0.40.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_40
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.40 (libva 1.7.3)
vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.4.pre1 (glk-alpha-71-gc3110dc)
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Simple            : VAEntrypointEncSlice
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointEncSliceLP
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointEncSliceLP
      VAProfileH264MultiviewHigh      : VAEntrypointVLD
      VAProfileH264MultiviewHigh      : VAEntrypointEncSlice
      VAProfileH264StereoHigh         : VAEntrypointVLD
      VAProfileH264StereoHigh         : VAEntrypointEncSlice
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointEncPicture
      VAProfileVP8Version0_3          : VAEntrypointVLD
      VAProfileVP8Version0_3          : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileVP9Profile0            : VAEntrypointVLD

El punto de entrada VLD (para decodificación de longitud variable) para el perfil 0 de VP9 es lo más lejos al que llega Skylake en términos de aceleración de hardware VP9.

Estos con los bancos de prueba de Kabylake, ejecute estas pruebas de codificación e informe 🙂

Aquí puedes ver las comentarios y valoraciones de los usuarios

Puedes añadir valor a nuestro contenido participando con tu experiencia en las explicaciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *