11月 242015
 

LinuxでIntel QSVを使ったH.264ハードウェアエンコード(CentOS7+ffmpeg)

動画データをffmpegを使ってエンコードしていたがCPUが張り付くため、改善したいなと考えていたらIntel QSVでのハードウェアエンコードを見つけた。Sandy以降(できればHaswell)のCPUでQSV機能があれば、H.264のハードウェアエンコードが利用することができる。ハードウェアエンコードを使えば、CPU負荷が減りエンコード中も別なことができるようになる。
※QSV対応CPUはIntel ARKから確認ができる。

ネットの情報ではWindowsがほとんどでLinux記事が少なく、しかもツール必須で有償とあったので調べてみることにした。
しらべて見るとWindowsでもLinuxでもそうだがQSVを使うにはIntel Media Server Studioが必要なようで、Community Editionがあり無償利用ができるようだ。

https://software.intel.com/en-us/intel-media-server-studio/try-buy

Intel Media Server StudioにはQSVを利用するのに必要なドライバとカーネルモジュールが含まれている。上記リンクからユーザー登録しダウンロードをする。

基本的にはほとんどのディストリに対応しているのだが、Intelでの動作確認済み&推奨はCentOS7.1のデフォルトカーネルとなっている。今回は推奨カーネルを利用することにした。

Intel Media Server Studio

RPMでのツールやライブラリをインストールし、SRPMからのカーネルパッチを適用したカスタムカーネルを作成することになる。カーネルをビルドするので容量(10G程度)や時間が掛かるので注意が必要。

必要なパッケージを導入

yum groupinstall "Development Tools"
yum install autoconf automake cmake freetype-devel gcc gcc-c++ git libtool make mercurial nasm pkgconfig zlib-devel mesa-dri-drivers wget bc

ダウンロードしたIntel Media Server Studioを展開しRPM等をインストールする。展開場所は/usr/local/srcとする。

cd /usr/local/src
tar xf mediaserverstudioessentials2015r6.tar.gz
cd MediaServerStudioEssentials2015R6/
tar xf SDK2015Production16.4.2.1.tar.gz
cd SDK2015Production16.4.2.1
cd CentOS/
tar xf install_scripts_centos_16.4.2.1-39163.tar.gz
./install_sdk_UMD_CentOS.sh

次にカスタムカーネルをビルドするが、rootユーザでのビルドは禁止されているため別ユーザを作成する。

useradd build
mkdir /usr/local/src/MSS
chown build /usr/local/src/MSS
cp build_kernel_rpm_CentOS.sh /usr/local/src/MSS/
su - build
cd /usr/local/src/MSS/
./build_kernel_rpm_CentOS.sh
exit

以降、rootユーザで実施。カスタムカーネルをインストールしリブート。

cd /usr/local/src/MSS/rpmbuild/RPMS/x86_64
yum localinstall *
reboot

リブート後にモジュールがロードされていることを確認

lsmod | grep 'i915'

i915                  938175  0
video                  19263  1 i915
i2c_algo_bit           13413  1 i915
drm_kms_helper         98226  2 i915,vmwgfx
drm                   311336  5 ttm,i915,drm_kms_helper,vmwgfx
i2c_core               40325  5 drm,i915,i2c_piix4,drm_kms_helper,i2c_algo_bit

QSV対応ffmpegのビルド

ffmpeg本家やRPMで配布されているサイト(RPMForge等)でもQSV有効のffmpegが配布されていないため、コンパイルして作成することにした。コンパイル手順は本家サイトを参考にlibfmxを追加した。

yasm

cd /usr/local/src
git clone --depth 1 git://github.com/yasm/yasm.git
cd yasm/
autoreconf -fiv
./configure
make
make install
make distclean

x264

cd /usr/local/src
git clone --depth 1 git://git.videolan.org/x264
cd x264
./configure --enable-static
make
make install
make distclean

x265

cd /usr/local/src
hg clone https://bitbucket.org/multicoreware/x265
cd x265/build/linux
cmake -G "Unix Makefiles" -DENABLE_SHARED:bool=off ../../source
make
make install

fdk-aac

cd /usr/local/src
git clone --depth 1 git://git.code.sf.net/p/opencore-amr/fdk-aac
cd fdk-aac
autoreconf -fiv
./configure --disable-shared
make
make install
make distclean

lame

cd /usr/local/src
curl -L -O http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
tar xzvf lame-3.99.5.tar.gz
cd lame-3.99.5/
./configure --disable-shared --enable-nasm
make
make install
make distclean

opus

cd /usr/local/src
git clone git://git.opus-codec.org/opus.git
cd opus
autoreconf -fiv
./configure --disable-shared
make
make install
make distclean

libogg

cd /usr/local/src
curl -O http://downloads.xiph.org/releases/ogg/libogg-1.3.2.tar.gz
tar xzvf libogg-1.3.2.tar.gz
cd libogg-1.3.2
./configure --disable-shared
make
make install
make distclean

libvorbis

cd /usr/local/src
curl -O http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.4.tar.gz
tar xzvf libvorbis-1.3.4.tar.gz
cd libvorbis-1.3.4
./configure --disable-shared
make
make install
make distclean

libvpx

cd /usr/local/src
git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git
cd libvpx
./configure --disable-examples
make
make install
make clean

libfmx

libfmxのコンパイル自体はSDKインストールで完了しているのだがpkgconfigファイルがなかったり、リンク処理ができていないので補足する。

pkgconfigの新規作成

vi /usr/lib64/pkgconfig/libmfx.pc
prefix=/usr/local
libdir=${prefix}/lib
includedir=${prefix}/include

Name: libmfx
Description: Intel Media SDK Dispatched static library
Version: 2015
Requires:
Requires.private:
Conflicts:
Libs: -L/usr/local/lib -L${libdir} -lmfx -ldispatch_shared -lva -lva-drm -lstdc++ -ldl
Libs.private:
Cflags: -I${includedir} -I/opt/intel/mediasdk/opensource/mfx_dispatch/include -I/usr/local/include

includeパスのリンク

ln -s /opt/intel/mediasdk/include/ /usr/local/include/mfx

ライブラリのリンク

ln -s /opt/intel/mediasdk/lib/lin_x64/libdispatch_shared.a /usr/local/lib
ln -s /opt/intel/mediasdk/lib/lin_x64/libdispatch_trace.a /usr/local/lib
ln -s /opt/intel/mediasdk/lib/lin_x64/libmfx.a /usr/local/lib
ranlib /usr/local/lib/libdispatch_shared.a

ffmpeg

cd /usr/local/src
git clone --depth 1 git://source.ffmpeg.org/ffmpeg
cd ffmpeg
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --pkg-config-flags="--static" --enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libmfx
make
make install

エンコード方法

ffmpegのオプションに-vcodec h264_qsvを指定すればQSVエンコードされる。

自分がよく利用しているエンコードサンプル

/usr/local/bin/ffmpeg -y -i sample.ts -f mp4 -vcodec h264_qsv -vprofile main -level 4.1 -s 1280x720 -q 27 -acodec aac -strict experimental -ac 2 -ar 48000 -ab 128k sample.mp4

スクリプト処理で注意

Apacheからのスクリプト処理などでシェルを経由しない場合だと、QSVに必要な環境変数が足りなくH/WエンコードされずにS/Wエンコードされてしまう。失敗している場合には以下のようなエラーメッセージが出力され、CPU使用率が高い状態でエンコードされる。

libva info: VA-API version 0.35.0
libva info: va_getDriverName() returns 0
libva info: User requested driver ''
libva info: va_openDriver() returns -1
[h264_qsv @ 0x4228c20] mfx init: /dev/dri/renderD128 vaInitialize failed
[h264_qsv @ 0x4228c20] mfx init: /dev/dri/renderD129 fd open failed
[h264_qsv @ 0x4228c20] mfx init: /dev/dri/renderD130 fd open failed
libva info: VA-API version 0.35.0
libva info: va_getDriverName() returns 0
libva info: User requested driver ''
libva info: va_openDriver() returns -1
[h264_qsv @ 0x4228c20] mfx init: /dev/dri/card0 vaInitialize failed
[h264_qsv @ 0x4228c20] mfx init: /dev/dri/card1 fd open failed
[h264_qsv @ 0x4228c20] mfx init: /dev/dri/card2 fd open failed
[h264_qsv @ 0x4228c20] Encoder will work with partial HW acceleration

正常に実行されると以下のようなメッセージが出力され、CPU利用率は30%未満程度となる。

libva info: VA-API version 0.35.0
libva info: va_getDriverName() returns 0
libva info: User requested driver 'iHD'
libva info: Trying to open /opt/intel/mediasdk/lib64/iHD_drv_video.so
libva info: Found init function __vaDriverInit_0_32
libva info: va_openDriver() returns 0

Apache等からのスクリプト実行する場合には直接ffmpegを実行するのではなく、以下のようなスクリプト経由で実行すると問題なく処理できる。

export LIBVA_DRIVERS_PATH=/opt/intel/mediasdk/lib64
export LIBVA_DRIVER_NAME=iHD
export MFX_HOME=/opt/intel/mediasdk
export PKG_CONFIG_PATH=/opt/intel/opencl:

/usr/local/bin/ffmpeg -y -i "$1" -f mp4 -vcodec h264_qsv -vprofile main -level 4.1 -s 1280x720 -q 27 -acodec aac -strict experimental -ac 2 -ar 48000 -ab 128k "${1}.mp4"

Sorry, the comment form is closed at this time.