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

Suh*_*shi 7 ffmpeg intel-graphics ubuntu

我正在运行这个命令:

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
Run Code Online (Sandbox Code Playgroud)

我期待 ffmpeg 通过英特尔 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
Run Code Online (Sandbox Code Playgroud)

我已--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)
Run Code Online (Sandbox Code Playgroud)

Den*_*gai 10

注意控制台的输出:

[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
Run Code Online (Sandbox Code Playgroud)

出现这种情况是因为您对 QuickSync 使用了错误的 VAAPI 驱动程序。正确的驱动程序应设置为intel 媒体驱动程序, iHD,因为您使用的是用于 QuickSync 的媒体 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

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

sudo add-apt-repository ppa:oibaf/graphics-drivers
sudo apt-get update && sudo apt-get -y upgrade && sudo apt-get -y dist-upgrade
Run Code Online (Sandbox Code Playgroud)

要在 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
Run Code Online (Sandbox Code Playgroud)

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

设置编译环境:

工作空间初始化:

mkdir -p ~/vaapi
mkdir -p ~/ffmpeg_build
mkdir -p ~/ffmpeg_sources
mkdir -p ~/bin
Run Code Online (Sandbox Code Playgroud)

从 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
Run Code Online (Sandbox Code Playgroud)

2. Gmmlib:

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

该组件是下面英特尔媒体驱动程序构建步骤的先决条件。

要构建它,请在 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)
Run Code Online (Sandbox Code Playgroud)

然后安装包:

sudo make -j$(nproc) install 
Run Code Online (Sandbox Code Playgroud)

然后继续。

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
Run Code Online (Sandbox Code Playgroud)

使用 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
Run Code Online (Sandbox Code Playgroud)

然后构建媒体驱动程序:

time make -j$(nproc) VERBOSE=1
Run Code Online (Sandbox Code Playgroud)

然后安装项目:

sudo make -j$(nproc) install VERBOSE=1
Run Code Online (Sandbox Code Playgroud)

将自己添加到视频组:

sudo usermod -a -G video $USER
Run Code Online (Sandbox Code Playgroud)

注意: FFmpeg 现在可以在启动时选择正确的 QSV 驱动程序,通常是iHD如果它已安装并出现在ldconfig条目中。您不再需要/etc/environment在 FFmpeg中或每个启动会话中在系统范围内设置正确的驱动程序。

4. libva-utils:

该软件包提供了一系列 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
Run Code Online (Sandbox Code Playgroud)

此时,发出重启:

sudo systemctl reboot
Run Code Online (Sandbox Code Playgroud)

这是反映上述更改所必需的,例如将您的用户添加到视频组。

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

构建英特尔的 MSDK

该软件包提供了一个 API,用于在具有集成显卡的英特尔® 平台上访问硬件加速的视频解码、编码和过滤。intel-media-driver 所针对的平台支持它。

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

构建步骤:

(一种)。将源提取到工作目录中~/vaapi

cd ~/vaapi
git clone https://github.com/Intel-Media-SDK/MediaSDK msdk
cd msdk
git submodule init
git pull
Run Code Online (Sandbox Code Playgroud)

(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
Run Code Online (Sandbox Code Playgroud)

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

为 iMSDK 创建库配置文件:

sudo nano /etc/ld.so.conf.d/imsdk.conf
Run Code Online (Sandbox Code Playgroud)

内容:

/opt/intel/mediasdk/lib
/opt/intel/mediasdk/plugins
Run Code Online (Sandbox Code Playgroud)

然后运行:

sudo ldconfig -vvvv
Run Code Online (Sandbox Code Playgroud)

继续。

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

根据需要包括额外的组件:

(一种)。构建和部署 nasm: 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

Run Code Online (Sandbox Code Playgroud)

(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
Run Code Online (Sandbox Code Playgroud)

(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

Run Code Online (Sandbox Code Playgroud)

(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
Run Code Online (Sandbox Code Playgroud)

(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
Run Code Online (Sandbox Code Playgroud)

(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
Run Code Online (Sandbox Code Playgroud)

(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
Run Code Online (Sandbox Code Playgroud)

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

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

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

sudo add-apt-repository ppa:oibaf/graphics-drivers
sudo apt-get update && sudo apt-get -y upgrade && sudo apt-get -y dist-upgrade
Run Code Online (Sandbox Code Playgroud)

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

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

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

sudo ln -s /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0 /usr/lib/x86_64-linux-gnu/libGLX_mesa.so
Run Code Online (Sandbox Code Playgroud)

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

mkdir -p ~/vaapi
mkdir -p ~/ffmpeg_build
mkdir -p ~/ffmpeg_sources
mkdir -p ~/bin
Run Code Online (Sandbox Code Playgroud)

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

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

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
Run Code Online (Sandbox Code Playgroud)

错误消息起初可能看起来不明确,但它主要源于将无效选项映射到底层 MFX 库,例如不受支持的像素格式。

extra_hw_frames=64传递给的额外参数hwupload与 MFX 运行时有关,需要一个固定的帧池大小来为 per-allocated。使用适合您要求的数字。通常,如果使用前瞻(LA-ICQ)等功能,您将需要更大的数字(64 左右

  • 我只想指出,通常最好获取 iHD(英特尔媒体驱动程序)的发行版并查看发行说明。他们通常会提供与 iHD 版本一起使用的 libva 和 gmmlib 的特定散列/版本。 (2认同)