El estudio de Video en Casa: aceleración hardware para transcodificación con ffmpeg
En esta serie de artículos veremos trucos, software y hardware para poder grabar y editar los cursos en nuestra casa usando Linux, Davinci Resolve y herramientas de software libre. Davinci es una herramienta profesional de edición de video y audio, que dispone de una versión gratuita que tiene instalador para Linux, en nuestro caso usaremos OBS Studio para las grabaciones. Los codecs de video y audio que soporta Davinci en linux son algo limitados pero veremos que con sencillos pasos podremos editar sin problema los videos.
Lo primero que debemos saber es qué codecs se han utilizado en el fichero para su codificación:
ffprobe -v error -show_streams -print_format json fichero.mp4
por ejemplo:
(base) pepesan@sauron:~/videos-grabados$ ffprobe -v error -show_streams -print_format json 2020-07-11\ 17-03-06.mp4 { "streams": [ { "index": 0, "codec_name": "h264", "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", "profile": "High", "codec_type": "video", "codec_time_base": "1/60", "codec_tag_string": "avc1", "codec_tag": "0x31637661", "width": 1920, "height": 1080, "coded_width": 1920, "coded_height": 1088, "has_b_frames": 2, "pix_fmt": "yuv420p", "level": 40, "chroma_location": "left", "refs": 1, "is_avc": "true", "nal_length_size": "4", "r_frame_rate": "30/1", "avg_frame_rate": "30/1", "time_base": "1/15360", "start_pts": 0, "start_time": "0.000000", "duration_ts": 60452352, "duration": "3935.700000", "bit_rate": "3000122", "bits_per_raw_sample": "8", "nb_frames": "118071", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "language": "und", "handler_name": "VideoHandler" } }, { "index": 1, "codec_name": "aac", "codec_long_name": "AAC (Advanced Audio Coding)", "profile": "LC", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "mp4a", "codec_tag": "0x6134706d", "sample_fmt": "fltp", "sample_rate": "44100", "channels": 2, "channel_layout": "stereo", "bits_per_sample": 0, "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/44100", "start_pts": 0, "start_time": "0.000000", "duration_ts": 173560832, "duration": "3935.619773", "bit_rate": "192001", "max_bit_rate": "192001", "nb_frames": "169494", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "language": "und", "handler_name": "SoundHandler" } } ] }
ESto nos dará una salida los codecs usados, por ejemplo h264 y aac en el caso de mp4 es lo más normal
Aceleración CUDA
En esta sección veremos cómo usar la aceleración CUDA en FFmpeg
nvidia-smi
Si todo va bien ejecutando este comando veremos la tarjeta NVidia, sino tendremos que realizar una instalación de CUDA:
(base) pepesan@sauron:~/videos-grabados$ nvidia-smi
Sat Jul 18 19:35:00 2020
+—————————————————————————–+
| NVIDIA-SMI 440.100 Driver Version: 440.100 CUDA Version: 10.2 |
|——————————-+———————-+———————-+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 Quadro P2000 Off | 00000000:01:00.0 Off | N/A |
| N/A 66C P0 N/A / N/A | 1017MiB / 4042MiB | 6% Default |
+——————————-+———————-+———————-+
+—————————————————————————–+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 1946 G /usr/lib/xorg/Xorg 141MiB |
| 0 6303 G /usr/lib/xorg/Xorg 216MiB |
| 0 6660 G /usr/bin/gnome-shell 222MiB |
| 0 6850 G /usr/bin/nextcloud 1MiB |
| 0 17634 G …AAAAAAAAAAAACAAAAAAAAAA= –shared-files 227MiB |
| 0 34664 G obs 193MiB |
+—————————————————————————–+
también podremos comprobar que está bien instalado CUDA (ojo el directorio puede variar dependiendo de la versión de CUDA instalada):
(base) pepesan@sauron:~/videos-grabados$ /usr/local/cuda-11.0/bin/nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Thu_Jun_11_22:26:38_PDT_2020
Cuda compilation tools, release 11.0, V11.0.194
Build cuda_11.0_bu.TC445_37.28540450_0
Comprobar que FFmpeg tiene soporte de cuda
(base) pepesan@sauron:~/videos-grabados$ ffmpeg -hwaccels
Deberíamos poder ver algo así:
ffmpeg version 4.2.2-1ubuntu1 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-3ubuntu1)
configuration: –prefix=/usr –extra-version=1ubuntu1 –toolchain=hardened –libdir=/usr/lib/x86_64-linux-gnu –incdir=/usr/include/x86_64-linux-gnu –arch=amd64 –enable-gpl –disable-stripping –enable-avresample –disable-filter=resample –enable-avisynth –enable-gnutls –enable-ladspa –enable-libaom –enable-libass –enable-libbluray –enable-libbs2b –enable-libcaca –enable-libcdio –enable-libcodec2 –enable-libflite –enable-libfontconfig –enable-libfreetype –enable-libfribidi –enable-libgme –enable-libgsm –enable-libjack –enable-libmp3lame –enable-libmysofa –enable-libopenjpeg –enable-libopenmpt –enable-libopus –enable-libpulse –enable-librsvg –enable-librubberband –enable-libshine –enable-libsnappy –enable-libsoxr –enable-libspeex –enable-libssh –enable-libtheora –enable-libtwolame –enable-libvidstab –enable-libvorbis –enable-libvpx –enable-libwavpack –enable-libwebp –enable-libx265 –enable-libxml2 –enable-libxvid –enable-libzmq –enable-libzvbi –enable-lv2 –enable-omx –enable-openal –enable-opencl –enable-opengl –enable-sdl2 –enable-libdc1394 –enable-libdrm –enable-libiec61883 –enable-nvenc –enable-chromaprint –enable-frei0r –enable-libx264 –enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Hardware acceleration methods:
vdpau
cuda
vaapi
drm
opencl
cuvid
Comprobar los encoders, decoders y filtros disponibles
(base) pepesan@sauron:~/videos-grabados$ for i in encoders decoders filters; do
echo $i:; ffmpeg -hide_banner -${i} | egrep -i “npp|cuvid|nvenc|cuda|nvdec”
done
encoders:
V….. h264_nvenc NVIDIA NVENC H.264 encoder (codec h264)
V….. nvenc NVIDIA NVENC H.264 encoder (codec h264)
V….. nvenc_h264 NVIDIA NVENC H.264 encoder (codec h264)
V….. nvenc_hevc NVIDIA NVENC hevc encoder (codec hevc)
V….. hevc_nvenc NVIDIA NVENC hevc encoder (codec hevc)
decoders:
V….. h264_cuvid Nvidia CUVID H264 decoder (codec h264)
V….. hevc_cuvid Nvidia CUVID HEVC decoder (codec hevc)
V….. mjpeg_cuvid Nvidia CUVID MJPEG decoder (codec mjpeg)
V….. mpeg1_cuvid Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
V….. mpeg2_cuvid Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
V….. mpeg4_cuvid Nvidia CUVID MPEG4 decoder (codec mpeg4)
V….. vc1_cuvid Nvidia CUVID VC1 decoder (codec vc1)
V….. vp8_cuvid Nvidia CUVID VP8 decoder (codec vp8)
V….. vp9_cuvid Nvidia CUVID VP9 decoder (codec vp9)
filters:
… hwupload_cuda V->V Upload a system memory frame to a CUDA device.
Ejemplo de uso, cambiar el bitrate de un fichero de manera acelerada
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i fichero_entrada.mp4 -c:v h264_nvenc -b:v 2048k -y fichero_salida.mp4
Ejemplo de uso, pasar de vp9 a mp4
ffmpeg -hwaccel cuvid -c:v vp9_cuvid -i fichero_entrada.webm -c:v h264_nvenc -b:v 2048k -y fichero_salida.mp4
Aceleración Integrada de Intel
Para ver qué tarjetas tenemos disponibles para la aceleración gráfica tendremos que instalar algunos paquetes:
sudo apt install vainfo libva2 libmfx1 libva-dev libmfx-dev
Después deberemos verificar que tarjeta es la que tenemos disponible:
vainfo –display drm –all
Con este comando podemos ver que dispositivos tenermos disponibles en /dev/dri/
ls -la /dev/dri/
En mi caso la intel integrada la tengo en /dev/dri/renderD128
vainfo –display drm –device /dev/dri/renderD128
Codecs y filtros disponibles con vaapi
(base) pepesan@sauron:~/videos-grabados$ for i in encoders decoders filters; do
echo $i:; ffmpeg -hide_banner -${i} | egrep -i “vaapi”
done
encoders:
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)
V….. vp9_vaapi VP9 (VAAPI) (codec vp9)
decoders:
filters:
… deinterlace_vaapi V->V Deinterlacing of VAAPI surfaces
… denoise_vaapi V->V VAAPI VPP for de-noise
… procamp_vaapi V->V ProcAmp (color balance) adjustments for hue, saturation, brightness, contrast
… scale_vaapi V->V Scale to/from VAAPI surfaces.
… sharpness_vaapi V->V VAAPI VPP for sharpness
… transpose_vaapi V->V VAAPI VPP for transpose
Conversión acelerada de mkv con vp9 y flac a mp4 con h264 y aac
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -hwaccel_device /dev/dri/renderD128 -i fichero_original.mkv -vf ‘format=nv12,hwupload’ -acodec aac -vcodec h264_vaapi fichero_salida.mp4
ffmpeg version 4.2.2-1ubuntu1 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 9 (Ubuntu 9.3.0-3ubuntu1) configuration: --prefix=/usr --extra-version=1ubuntu1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 Input #0, matroska,webm, from '2020-07-18 20-32-48.mkv': Metadata: ENCODER : Lavf58.29.100 Duration: 00:00:03.66, start: 0.000000, bitrate: 258 kb/s Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv, bt470bg/unknown/unknown), 1920x1080, 30 fps, 30 tbr, 1k tbn, 1k tbc (default) Metadata: DURATION : 00:00:02,966000000 Stream #0:1: Audio: flac, 44100 Hz, stereo, s16 (default) Metadata: DURATION : 00:00:03,657000000 Stream mapping: Stream #0:0 -> #0:0 (vp9 (native) -> h264 (h264_vaapi)) Stream #0:1 -> #0:1 (flac (native) -> aac (native)) Press [q] to stop, [?] for help Output #0, mp4, to '2020-07-18 20-32-48.mp4':e=-577014:32:22.77 bitrate= -0.0kbits/s speed=N/A Metadata: encoder : Lavf58.29.100 Stream #0:0: Video: h264 (h264_vaapi) (High) (avc1 / 0x31637661), vaapi_vld(progressive), 1920x1080, q=-1--1, 30 fps, 15360 tbn, 30 tbc (default) Metadata: DURATION : 00:00:02,966000000 encoder : Lavc58.54.100 h264_vaapi Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp (16 bit), 128 kb/s (default) Metadata: DURATION : 00:00:03,657000000 encoder : Lavc58.54.100 aac frame= 89 fps= 37 q=-0.0 Lsize= 111kB time=00:00:03.66 bitrate= 247.2kbits/s speed=1.54x video:53kB audio:54kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 3.661503
Referencias:
- https://developer.nvidia.com/blog/nvidia-ffmpeg-transcoding-guide/
- David Marzal: https://twitter.com/davidmarzalc
- https://gist.github.com/Brainiarc7/c6164520f082c27ae7bbea9556d4a3ba
Comments