以前にnvidiaのnvencを使ったffmpegHWEncode環境についての投稿をしました。
今度はIntel内蔵GPUの機能であるQSVを使った例です。
下記をベースに入れていきます。
このテーマに向いている人
・多量のMPEG2やH.264動画を所有していて、H.265に変換したい人
(画質にそこまでこだわりはなく、ストレージの容量逼迫してるからさっさと片付けたい!など)
・何かしらのMPEG2-TSを録画する環境があり、録画した後にH.265へのトランスコードをしたいなと思ってる人
(多分このような用途の人には一番おすすめな気がする)
・動画配信などでリアルタイムトランスコードが必要な人
(画質より速度が重要視される分野)
必須環境
・intelCPUを使っていて内蔵GPUが使えるUbuntu 20.04 マシン
・Broadwell世代以降のGPU内蔵CPU
今回は Intel Media SDK + iHDで作成してるためCPU世代でgen8以降が対象です。
GPU世代によってH.265のエンコードができない等があります。詳しくは
https://trac.ffmpeg.org/wiki/Hardware/QuickSync
準備
Intel media stack componentsとiHDドライバのインストール
Ubuntu19.04以降は公式aptに用意されてるので非常に楽です。
# Intel media stack componentsのインストール
sudo apt-get install libva-dev libmfx-dev intel-media-va-driver-non-free vainfo
export LIBVA_DRIVER_NAME=iHD
インストール完了後、vainfoを実行し、ドライバが見えるか確認しましょう。
test@test:~$ sudo vainfo
error: XDG_RUNTIME_DIR not set in the environment.
error: can't connect to X server!
libva info: VA-API version 1.7.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_7
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.7 (libva 2.6.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 20.1.1 ()
vainfo: Supported profile and entrypoints
VAProfileNone : VAEntrypointVideoProc
VAProfileNone : VAEntrypointStats
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointFEI
VAProfileH264Main : VAEntrypointEncSliceLP
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointFEI
VAProfileH264High : VAEntrypointEncSliceLP
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointFEI
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
VAProfileVP8Version0_3 : VAEntrypointVLD
VAProfileVP8Version0_3 : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointFEI
VAProfileHEVCMain10 : VAEntrypointVLD
VAProfileHEVCMain10 : VAEntrypointEncSlice
VAProfileVP9Profile0 : VAEntrypointVLD
VAProfileVP9Profile2 : VAEntrypointVLD
Driver version: Intel iHD driver for Intel(R) Gen Graphics - 20.1.1
とのことで、問題なくiHDが使えます。
しかし、このままでは、エンコードに使う /dev/dri/renderD128 のパーミッションの問題で、一般ユーザーでffmpegを使う場合、HWエンコードができなくなります。
test@test:~$ ls -l /dev/dri/render*
crw-rw---- 1 root render 226, 128 Aug 15 13:53 /dev/dri/renderD128
test@test:~$
そこで、一般ユーザーでもアクセス可能にするための設定ファイルを作成します。
sudo vi /etc/udev/rules.d/99-render.rules
KERNEL=="render*" GROUP="render", MODE="0666"
OS再起動後、デバイスのパーミッションを確認します。
test@test:~$ ls -l /dev/dri/render*
crw-rw-rw- 1 root render 226, 128 Aug 15 13:53 /dev/dri/renderD128
test@test:~$
vainfoも一般ユーザーで実行できるようになるはずです。
test@test:~$ vainfo
error: XDG_RUNTIME_DIR not set in the environment.
error: can't connect to X server!
libva info: VA-API version 1.7.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_7
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.7 (libva 2.6.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 20.1.1 ()
vainfo: Supported profile and entrypoints
VAProfileNone : VAEntrypointVideoProc
VAProfileNone : VAEntrypointStats
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointFEI
VAProfileH264Main : VAEntrypointEncSliceLP
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointFEI
VAProfileH264High : VAEntrypointEncSliceLP
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointFEI
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
VAProfileVP8Version0_3 : VAEntrypointVLD
VAProfileVP8Version0_3 : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointFEI
VAProfileHEVCMain10 : VAEntrypointVLD
VAProfileHEVCMain10 : VAEntrypointEncSlice
VAProfileVP9Profile0 : VAEntrypointVLD
VAProfileVP9Profile2 : VAEntrypointVLD
FFmpegのインストール
Compile FFmpeg for Ubuntu, Debian, or Mint
https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
こちらをベースに全てソースコードで入れていきます。
個人的にhapエンコードを使いたいので libsnappy-dev をインストールの上
--enable-libsnappy
を追記しています。
またTLS対応のために libssl-dev をインストールの上
--enable-openssl
を追記しています。
#FFmpegコンパイルに必要なものを導入
sudo apt-get update -qq && sudo apt-get -y install \
autoconf \
automake \
build-essential \
cmake \
git-core \
libass-dev \
libfreetype6-dev \
libgnutls28-dev \
libssl-dev \
libtool \
libvorbis-dev \
libsnappy-dev \
meson \
ninja-build \
pkg-config \
texinfo \
wget \
yasm \
zlib1g-dev
#作業ディレクトリ作成
mkdir -p ~/ffmpeg_sources ~/bin
#NASM インストール
cd ~/ffmpeg_sources && \
wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2 && \
tar xjvf nasm-2.15.05.tar.bz2 && \
cd nasm-2.15.05 && \
./autogen.sh && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" && \
make && \
make install
# libx264 インストール
cd ~/ffmpeg_sources && \
git -C x264 pull 2> /dev/null || git clone --depth 1 https://code.videolan.org/videolan/x264.git && \
cd x264 && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --enable-pic && \
PATH="$HOME/bin:$PATH" make && \
make install
# libx265 インストール
sudo apt-get install libnuma-dev && \
cd ~/ffmpeg_sources && \
git -C x265_git pull 2> /dev/null || git clone https://bitbucket.org/multicoreware/x265_git && \
cd x265_git/build/linux && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED=off ../../source && \
PATH="$HOME/bin:$PATH" make && \
make install
# libvpx インストール
cd ~/ffmpeg_sources && \
git -C libvpx pull 2> /dev/null || git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git && \
cd libvpx && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm && \
PATH="$HOME/bin:$PATH" make && \
make install
# libfdk-aac インストール
cd ~/ffmpeg_sources && \
git -C fdk-aac pull 2> /dev/null || git clone --depth 1 https://github.com/mstorsjo/fdk-aac && \
cd fdk-aac && \
autoreconf -fiv && \
./configure --prefix="$HOME/ffmpeg_build" --disable-shared && \
make && \
make install
# libmp3lame インストール
cd ~/ffmpeg_sources && \
wget -O lame-3.100.tar.gz https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz && \
tar xzvf lame-3.100.tar.gz && \
cd lame-3.100 && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --disable-shared --enable-nasm && \
PATH="$HOME/bin:$PATH" make && \
make install
# libopus インストール
cd ~/ffmpeg_sources && \
git -C opus pull 2> /dev/null || git clone --depth 1 https://github.com/xiph/opus.git && \
cd opus && \
./autogen.sh && \
./configure --prefix="$HOME/ffmpeg_build" --disable-shared && \
make && \
make install
# libaom インストール
cd ~/ffmpeg_sources && \
git -C aom pull 2> /dev/null || git clone --depth 1 https://aomedia.googlesource.com/aom && \
mkdir -p aom_build && \
cd aom_build && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED=off -DENABLE_NASM=on ../aom && \
PATH="$HOME/bin:$PATH" make && \
make install
# libsvtav1 インストール
cd ~/ffmpeg_sources && \
git -C SVT-AV1 pull 2> /dev/null || git clone https://gitlab.com/AOMediaCodec/SVT-AV1.git && \
mkdir -p SVT-AV1/build && \
cd SVT-AV1/build && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DCMAKE_BUILD_TYPE=Release -DBUILD_DEC=OFF -DBUILD_SHARED_LIBS=OFF .. && \
PATH="$HOME/bin:$PATH" make && \
make install
# FFmpeg インストール
cd ~/ffmpeg_sources && \
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \
tar xjvf ffmpeg-snapshot.tar.bz2 && \
cd ffmpeg && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
--prefix="$HOME/ffmpeg_build" \
--pkg-config-flags="--static" \
--extra-cflags="-I$HOME/ffmpeg_build/include" \
--extra-ldflags="-L$HOME/ffmpeg_build/lib" \
--extra-libs="-lpthread -lm" \
--ld="g++" \
--bindir="$HOME/bin" \
--enable-vaapi \
--enable-libmfx \
--enable-openssl \
--enable-gpl \
--enable-libaom \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libsvtav1 \
--enable-libvorbis \
--enable-libsnappy \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 \
--enable-static \
--enable-nonfree && \
PATH="$HOME/bin:$PATH" make && \
make install && \
hash -r
パスを通したり
source ~/.profile
echo "MANPATH_MAP $HOME/bin $HOME/ffmpeg_build/share/man" >> ~/.manpath
動作確認
実際にインストールが成功したか、下記のコマンドでQSVエンコード関連オプションが使えるか確認します。
for i in buildconf hwaccels decoders filters encoders; do echo $i:; ffmpeg -hide_banner -${i} | egrep -i "qsv|vaapi|libmfx"; done
結果はこのようになると思います。
test@test:~$ for i in buildconf hwaccels decoders filters encoders; do echo $i:; ffmpeg -hide_banner -${i} | egrep -i "qsv|vaapi|libmfx"; done
buildconf:
--enable-vaapi
--enable-libmfx
hwaccels:
vaapi
qsv
decoders:
V....D av1_qsv AV1 video (Intel Quick Sync Video acceleration) (codec av1)
V....D h264_qsv H264 video (Intel Quick Sync Video acceleration) (codec h264)
V....D hevc_qsv HEVC video (Intel Quick Sync Video acceleration) (codec hevc)
V....D mjpeg_qsv MJPEG video (Intel Quick Sync Video acceleration) (codec mjpeg)
V....D mpeg2_qsv MPEG2VIDEO video (Intel Quick Sync Video acceleration) (codec mpeg2video)
V....D vc1_qsv VC1 video (Intel Quick Sync Video acceleration) (codec vc1)
V....D vp8_qsv VP8 video (Intel Quick Sync Video acceleration) (codec vp8)
V....D vp9_qsv VP9 video (Intel Quick Sync Video acceleration) (codec vp9)
filters:
... deinterlace_qsv V->V QuickSync video deinterlacing
... deinterlace_vaapi V->V Deinterlacing of VAAPI surfaces
... denoise_vaapi V->V VAAPI VPP for de-noise
... overlay_qsv VV->V Quick Sync Video overlay.
... procamp_vaapi V->V ProcAmp (color balance) adjustments for hue, saturation, brightness, contrast
... scale_qsv V->V QuickSync video scaling and format conversion
... scale_vaapi V->V Scale to/from VAAPI surfaces.
... sharpness_vaapi V->V VAAPI VPP for sharpness
... tonemap_vaapi V->V VAAPI VPP for tone-mapping
... transpose_vaapi V->V VAAPI VPP for transpose
... vpp_qsv V->V Quick Sync Video VPP.
encoders:
V..... h264_qsv H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h264)
V....D h264_vaapi H.264/AVC (VAAPI) (codec h264)
V..... hevc_qsv HEVC (Intel Quick Sync Video acceleration) (codec hevc)
V....D hevc_vaapi H.265/HEVC (VAAPI) (codec hevc)
V..... mjpeg_qsv MJPEG (Intel Quick Sync Video acceleration) (codec mjpeg)
V....D mjpeg_vaapi MJPEG (VAAPI) (codec mjpeg)
V..... mpeg2_qsv MPEG-2 video (Intel Quick Sync Video acceleration) (codec mpeg2video)
V....D mpeg2_vaapi MPEG-2 (VAAPI) (codec mpeg2video)
V....D vp8_vaapi VP8 (VAAPI) (codec vp8)
V....D vp9_vaapi VP9 (VAAPI) (codec vp9)
V..... vp9_qsv VP9 video (Intel Quick Sync Video acceleration) (codec vp9)
test@test:~$
実際に使ってみる
では実際に使ってみましょう。
MPEG2からH.265へ720pでエンコード
ffmpeg -hwaccel qsv -hwaccel_output_format qsv -c:v mpeg2_qsv -i input.mp2ts -vf deinterlace_qsv,scale_qsv=-1:720 -c:v hevc_qsv -tag:v hvc1 -f mp4 out.mp4
解説です。
-hwaccel qsv
HWエンコードでqsvを明示
-hwaccel_output_format qsv
デコードしたRAWデータをGPUメモリに残したまま処理するためのおまじない
-c:v mpeg2_qsv
MPEG2のハードウェアデコードを明示
-i input.mp2ts
変換元ファイルを指定します。
-vf deinterlace_qsv,scale_qsv=-1:720
インターレス解除と720Pになるよう縮小
-c:v hevc_qsv
H.265でQSVを使います
-tag:v hvc1
Apple製品で扱えるH.265は hev1ではなくhvc1の方なので、タグで明示します
-f mp4
出力ファイルフォーマットがをmp4であると明示します
out.mp4
出力先ファイル名を指定
最後に
使ってみた結果だけ言うと、NVEncの方が速度が速く画質が良いのでソフトエンコするよりは早いけど。てところかなーとおもってます(といってもGPU世代によっても変わるので、出力結果をみてご自身で判断いただければ)