使用 FFmpeg 通过 Intel QuickSync 将视频编码为 h264

使用 FFmpeg 通过 Intel QuickSync 将视频编码为 h264

我正在运行这个命令:

ffmpeg -init_hw_device qsv=hw -filter_hw_device -f rawvideo -pix_fmt yuv420p -s:v 2560x1440 -i normal-desktop-use-1440p.mkv -c:v h264_qsv - b:v 5M output.mp4

我收到以下错误:

Splitting the commandline.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'.
Reading option '-init_hw_device' ... matched as option 'init_hw_device' (initialise hardware device) with argument 'qsv=hw'.
Reading option '-filter_hw_device' ... matched as option 'filter_hw_device' (set hardware device used when filtering) with argument 'hw'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'rawvideo'.
Reading option '-pix_fmt' ... matched as option 'pix_fmt' (set pixel format) with argument 'yuv420p'.
Reading option '-s:v' ... matched as option 's' (set frame size (WxH or abbreviation)) with argument '2560x1440'.
Reading option '-i' ... matched as input url with argument 'normal-desktop-use-1440p.mkv'.
Reading option '-vf' ... matched as option 'vf' (set video filters) with argument '-c:v'.
Reading option 'h264_qsv' ... matched as output url.
Reading option '-b:v' ... matched as option 'b' (video bitrate (please use -b:v)) with argument '15M'.
Reading option '-framerate' ... matched as AVOption 'framerate' with argument '30'.
Reading option 'output.mp4' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option loglevel (set logging level) with argument debug.
Applying option init_hw_device (initialise hardware device) with argument qsv=hw.
[AVHWDeviceContext @ 0x556f744cf5c0] Cannot open X11 display .
[AVHWDeviceContext @ 0x556f744cf5c0] Opened VA display via DRM device /dev/dri/renderD128.
[AVHWDeviceContext @ 0x556f744cf5c0] libva: VA-API version 1.1.0
[AVHWDeviceContext @ 0x556f744cf5c0] libva: va_getDriverName() returns 0
[AVHWDeviceContext @ 0x556f744cf5c0] libva: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
[AVHWDeviceContext @ 0x556f744cf5c0] libva: Found init function __vaDriverInit_1_1
[AVHWDeviceContext @ 0x556f744cf5c0] libva: va_openDriver() returns 0
[AVHWDeviceContext @ 0x556f744cf5c0] Initialised VAAPI connection: version 1.1
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x32315659 -> yuv420p.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x30323449 -> yuv420p.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x3231564e -> nv12.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x32595559 -> yuyv422.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x59565955 -> uyvy422.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x48323234 -> yuv422p.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x58424752 -> rgb0.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x58524742 -> bgr0.
[AVHWDeviceContext @ 0x556f744cf5c0] Format 0x30313050 -> p010le.
[AVHWDeviceContext @ 0x556f744cf5c0] VAAPI driver: Intel i965 driver for Intel(R) Skylake - 2.1.0.
[AVHWDeviceContext @ 0x556f744cf5c0] Driver not found in known nonstandard list, using standard behaviour.
[AVHWDeviceContext @ 0x556f744cf140] Error initializing an MFX session: -3.
Device creation failed: -1313558101.
Failed to set value 'qsv=hw' for option 'init_hw_device': Unknown error occurred
Error parsing global options: Unknown error occurred

我希望 ffmpeg 通过 Intel QuickSync 使用硬件加速 h264 编码器对我的视频进行编码。

关于我的 ffmpeg 构建的有用信息:

ffmpeg version N-93636-g6829c3c Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.3.0-27ubuntu1~18.04)
  configuration: --prefix=/root/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/root/ffmpeg_build/include --extra-ldflags=-L/root/ffmpeg_build/lib --extra-libs='-lpthread -lm' --bindir=/root/bin --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libmfx --enable-nonfree

我已经--enable-libmfx启用。

使用此处理器:model name : Intel(R) Xeon(R) CPU E3-1578L v5 @ 2.00GHz

如果我这样做,ffmpeg -encoders | grep qsv我会得到以下信息:

 V..... h264_qsv             H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h264)
 V..... hevc_qsv             HEVC (Intel Quick Sync Video acceleration) (codec hevc)
 V..... mjpeg_qsv            MJPEG (Intel Quick Sync Video acceleration) (codec mjpeg)
 V..... mpeg2_qsv            MPEG-2 video (Intel Quick Sync Video acceleration) (codec mpeg2video)

答案1

注意控制台的输出:

[AVHWDeviceContext @ 0x556f744cf5c0] VAAPI driver: Intel i965 driver for Intel(R) Skylake - 2.1.0.
[AVHWDeviceContext @ 0x556f744cf5c0] Driver not found in known nonstandard list, using standard behaviour.
[AVHWDeviceContext @ 0x556f744cf140] Error initializing an MFX session: -3.
Device creation failed: -1313558101.
Failed to set value 'qsv=hw' for option 'init_hw_device': Unknown error occurred

发生这种情况是因为您为 QuickSync 使用了错误的 VAAPI 驱动程序。正确的驱动程序应设置为英特尔媒体驱动程序,,iHD因为您使用的是 QuickSync 的 Media SDK,而不是基于 VAAPI 的编码器。

我将记录构建具有您所需功能(QuickSync)的 FFmpeg 所需的步骤,并根据需要支持额外的编解码器,以及有关使用以下正确驱动程序的额外说明:

确保平台是最新的:

我注意到您使用的是 Ubuntu 18.04 LTS,因此可以按照以下说明进行操作:

sudo apt update && sudo apt -y upgrade && sudo apt -y dist-upgrade

首先安装基线依赖项:

sudo apt-get -y install autoconf automake build-essential libass-dev libtool pkg-config texinfo zlib1g-dev libva-dev cmake mercurial libdrm-dev libvorbis-dev libogg-dev git libx11-dev libperl-dev libpciaccess-dev libpciaccess0 xorg-dev intel-gpu-tools libwayland-dev xutils-dev libssl-dev

然后添加安装 libva 最新开发头文件的 Oibaf PPA:

sudo add-apt-repository ppa:oibaf/graphics-drivers
sudo apt-get update && sudo apt-get -y upgrade && sudo apt-get -y dist-upgrade

为了解决 Ubuntu 18.04LTS 中的链接器问题:

更新:这不再需要,但保留以供将来参考。

参考这个:https://forum.openframeworks.cc/t/ubuntu-unable-to-compile-missing-glx-mesa/29367/2

创建以下符号链接,如下所示:

sudo ln -s /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0 /usr/lib/x86_64-linux-gnu/libGLX_mesa.so

从源代码构建最新的 libva 和所有驱动程序:

设置构建环境:

工作空间初始化:

mkdir -p ~/vaapi
mkdir -p ~/ffmpeg_build
mkdir -p ~/ffmpeg_sources
mkdir -p ~/bin

从 libva 开始:

1.Libva:

Libva 是 VA-API(视频加速 API)的实现

VA-API 是一个开源库和 API 规范,它提供对视频处理的图形硬件加速功能的访问。它由一个主库和每个受支持硬件供应商的驱动程序特定加速后端组成。它是构建下面的 VAAPI 驱动程序组件的先决条件。

cd ~/vaapi
git clone https://github.com/01org/libva
cd libva
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
sudo ldconfig -vvvv

2.Gmmlib:

英特尔(R) 图形内存管理库为用于 OpenCL(TM) 的英特尔(R) 图形计算运行时和用于 VAAPI 的英特尔(R) 媒体驱动程序提供设备特定和缓冲区管理。

该组件是下面 Intel Media 驱动程序构建步骤的先决条件。

要构建它,请在 vaapi 子目录中创建一个工作区目录并运行构建:

mkdir -p ~/vaapi/workspace
cd ~/vaapi/workspace
git clone https://github.com/intel/gmmlib
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE= Release ../gmmlib
make -j$(nproc)

然后安装包:

sudo make -j$(nproc) install 

然后继续。

3.英特尔媒体驱动程序:

适用于 VAAPI 的英特尔(R) 媒体驱动程序是一种新的 VA-API(视频加速 API)用户模式驱动程序,支持基于 GEN 的图形硬件的硬件加速解码、编码和视频后期处理,根据 MIT 许可发布。

cd ~/vaapi/workspace
git clone https://github.com/intel/media-driver
cd media-driver
git submodule init
git pull
mkdir -p ~/vaapi/workspace/build_media
cd ~/vaapi/workspace/build_media

使用 cmake 配置项目:

cmake ../media-driver \
-DMEDIA_VERSION="2.0.0" \
-DBS_DIR_GMMLIB=$PWD/../gmmlib/Source/GmmLib/ \
-DBS_DIR_COMMON=$PWD/../gmmlib/Source/Common/ \
-DBS_DIR_INC=$PWD/../gmmlib/Source/inc/ \
-DBS_DIR_MEDIA=$PWD/../media-driver \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INSTALL_LIBDIR=/usr/lib/x86_64-linux-gnu \
-DINSTALL_DRIVER_SYSCONF=OFF \
-DLIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri

然后构建媒体驱动程序:

time make -j$(nproc) VERBOSE=1

然后安装项目:

sudo make -j$(nproc) install VERBOSE=1

将您自己添加到视频组:

sudo usermod -a -G video $USER

笔记:FFmpeg 现在可以在启动时选择正确的 QSV 驱动程序,通常iHD是在它已安装并存在于ldconfig条目中的情况下。您不再需要在/etc/environmentFFmpeg 中或每个启动会话中在整个系统范围内设置正确的驱动程序。

4.libva-实用程序:

此软件包提供了针对 VA-API 的一组测试,例如vainfo,用于验证平台所支持的功能(通过 VAAPI 入口点信息对每个编解码器进行编码、解码和后处理属性)。

cd ~/vaapi
git clone https://github.com/intel/libva-utils
cd libva-utils
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install

此时,发出重新启动命令:

sudo systemctl reboot

这是为了反映上面所做的更改,例如将您的用户添加到视频组。

然后恢复时,继续以下步骤。

建造英特尔的 MSDK

此软件包提供 API,用于访问集成显卡的 Intel® 平台上的硬件加速视频解码、编码和过滤。它受 intel-media-driver 所针对的平台支持。

有关每代支持的功能,请参阅

构建步骤:

(a). 将源代码放入工作目录~/vaapi

cd ~/vaapi
git clone https://github.com/Intel-Media-SDK/MediaSDK msdk
cd msdk
git submodule init
git pull

(b). 配置构建:

mkdir -p ~/vaapi/build_msdk
cd ~/vaapi/build_msdk
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_WAYLAND=ON -DENABLE_X11_DRI3=ON ../msdk
time make -j$(nproc) VERBOSE=1
sudo make install -j$(nproc) VERBOSE=1

CMake 将自动检测您所在的平台并启用工作构建所需的特定于平台的挂钩。

为 iMSDK 创建库配置文件:

sudo nano /etc/ld.so.conf.d/imsdk.conf

内容:

/opt/intel/mediasdk/lib
/opt/intel/mediasdk/plugins

然后运行:

sudo ldconfig -vvvv

继续。

使用 iMSDK 构建可用的 FFmpeg 二进制文件:

根据需要添加额外的组件:

(a). 构建并部署nasm: 纳什是 x264 和 FFmpeg 使用的 x86 优化汇编程序。强烈推荐,否则您的最终构建可能会非常慢。

请注意,我们现在已经从 Yasm 切换到 nasm,因为这是 x265、x264 等当前采用的汇编程序。

cd ~/ffmpeg_sources
wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz
tar xzvf nasm-2.14.02.tar.gz
cd nasm-2.14.02
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

(b). 静态构建并部署 libx264:此库提供 H.264 视频编码器。请参阅H.264 编码指南了解更多信息和使用示例。这需要使用 来配置 ffmpeg --enable-gpl --enable-libx264

cd ~/ffmpeg_sources
git clone https://code.videolan.org/videolan/x264.git
cd ~/ffmpeg_sources/x264
git pull
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --disable-opencl --bit-depth=all --enable-pic
PATH="$HOME/bin:$PATH" make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

(c). 构建并配置 libx265:此库提供 H.265/HEVC 视频编码器。请参阅H.265 编码指南了解更多信息和使用示例。

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

(d). 构建并部署 libfdk-aac 库:这提供了 AAC 音频编码器。请参阅AAC 音频编码指南了解更多信息和使用示例。这需要配置 ffmpeg --enable-libfdk-aac(并且--enable-nonfree如果您还包括--enable-gpl)。

cd ~/ffmpeg_sources
git clone https://github.com/mstorsjo/fdk-aac
cd fdk-aac
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

(e). 构建并配置 libvpx:

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

(f). 构建 LibVorbis:

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

(g). 构建 FFmpeg:

使用所需选项构建 FFmpeg 二进制文件:

cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/FFmpeg -b master
cd FFmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig:/opt/intel/mediasdk/lib/pkgconfig" ./configure \
  --pkg-config-flags="--static" \
  --prefix="$HOME/bin" \
  --bindir="$HOME/bin" \
  --extra-cflags="-I$HOME/bin/include" \
  --extra-ldflags="-L$HOME/bin/lib" \
  --extra-cflags="-I/opt/intel/mediasdk/include" \
  --extra-ldflags="-L/opt/intel/mediasdk/lib" \
  --extra-ldflags="-L/opt/intel/mediasdk/plugins" \
  --enable-libmfx \
  --enable-vaapi \
  --enable-opencl \
  --disable-debug \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libdrm \
  --enable-gpl \
  --cpu=native \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-openssl \
  --enable-pic \
  --extra-libs="-lpthread -lm -lz -ldl" \
  --enable-nonfree 
PATH="$HOME/bin:$PATH" make -j$(nproc) 
make -j$(nproc) install 
make -j$(nproc) distclean 
hash -r

~/bin/ffmpeg现在您可以从 启动具有所需功能的FFmpeg 二进制文件。

使用 QSV 编码器进行编码的注意事项:

通常,您需要初始化一个硬件设备,该设备将由正在使用的编码器和过滤器使用,如下例所示:

ffmpeg -y -loglevel debug -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv \
-i simpsons.mp4 -vf 'format=qsv,hwupload=extra_hw_frames=64'  \
-c:v hevc_qsv \
-bf 3 -b:v 3.75M -maxrate:v 3.75M -bufsize:v 0.5M -r:v 30 -c:a copy -f mp4 trolled.mp4

了解用于 MFX 会话的硬件设备是如何初始化的 ( ) 并映射到过滤器(-init_hw_device qsv=hw例如)的。推荐进一步阅读:hwupload-filter_hw_device hw高级视频选项FFmpeg wiki 上的部分。

上面的例子演示了如何使用hevc_qsv编码器并传递一些私有选项,以供参考。

另一个例子,展示了编码器的使用h264_qsv

ffmpeg -y -loglevel debug -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv \
-i simpsons.mp4 -vf 'format=qsv,hwupload=extra_hw_frames=64'  \
-c:v h264_qsv \
-bf 3 -b:v 15M -maxrate:v 15M -bufsize:v 2M -r:v 30 -c:a copy -f mp4 trolled.mp4

请注意,上面的两个示例都将使用 MFX 中的恒定比特率控制 (CBR) 方法,如控制台日志所示:

[hevc_qsv @ 0x55faf21eedc0] Using the constant bitrate (CBR) ratecontrol method

速率控制,类似于VAAPI 实现控制它,由传递给编码器的参数-b:v(目标视频比特率)和-maxrate:v(最大视频比特率)驱动。如果它们相等,则使用 CBR(恒定比特率控制)。如果最大比特率大于目标比特率,则启用 VBR,实际上,启用基于前瞻的控制(如果需要)。

观察我们如何调用hwupload过滤器,并与过滤器链接format=qsv以确保 MFX 运行时收到支持的像素格式。未能通过此视频过滤器链将导致初始化失败,输出类似于以下内容:

[h264_qsv @ 0x560e1bda7280] Selected ratecontrol mode is unsupported
[h264_qsv @ 0x560e1bda7280] Low power mode is unsupported
[h264_qsv @ 0x560e1bda7280] Current frame rate is unsupported
[h264_qsv @ 0x560e1bda7280] Current picture structure is unsupported
[h264_qsv @ 0x560e1bda7280] Current resolution is unsupported
[h264_qsv @ 0x560e1bda7280] Current pixel format is unsupported
[h264_qsv @ 0x560e1bda7280] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
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

该错误消息乍一看可能有些模棱两可,但它主要源于将无效选项映射到底层 MFX 库,例如不受支持的像素格式。

extra_hw_frames=64传递给的额外参数hwupload与 MFX 运行时需要固定帧池大小按每次分配进行。使用适合您要求的数字。通常,如果使用以下功能,则需要更大的数字(64 左右)前瞻 (LA-ICQ)

相关内容