FFmpeg

VAAPIとffmpeg

1月に続いてASRock H97 Pro4にXeon E3-1265L v3を載せたHaswellでのQSVなハードウェアエンコードの続き。

参照

P-Life http://mypedia.info/

水珈琲の日誌 https://www.mizucoffee.com/

FFmpeg https://ffmpeg.org/

Wikipedia https://en.wikipedia.org/wiki/

VAAPIとffmpeg

昨年12月に続いてASRock H97 Pro4にXeon E3-1265L v3を載せたHaswellでのQSVなハードウェアエンコードの続き。

h264_vaapiffmpegの準備。2017年に倣ってbuildしないとなぁ…と思ってたんだけれども、

ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-17ubuntu1~20.04)
  configuration: --extra-libs='-lpthread -lm' --enable-libmfx --enable-gpl --enable-libaom --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libx264 --enable-libx265 --enable-nonfree
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...
Use -h to get full help or, even better, run 'man ffmpeg'
root@haswell:~# ffmpeg -encoders 2>/dev/null | grep vaapi
 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)
root@haswell:~#

aptで導入されたffmpegでもVAAPI対応しているみたいだ。

二ヶ国語音声対応

昨年の二ヶ国語音声対応では日本語/英語それぞれ2chステレオを確保した2トラックに対して全てMAPオプションで列挙する事で多国語対応したのだが、『きかんしゃトーマス』がL/Rを日本語/英語に置き換えたモノラル2カ国語フォーマットで聞きづらいので、これもL/Rを分離してモノラルマルチトラックとする事に。

要は"channelsplit[FL][FR]“で分離して -map “[FL]” -map “[FR]” すれば良いという事なので、 ~/bin/stereo2bilingual.sh

#!/bin/bash
TMPFIL=$$.mp4
# IN_FILES="${1:-*.mp4}";
IN_FILES=$*
for f in ${IN_FILES}; do
    ffmpeg -i ${f} \
      -filter_complex "channelsplit[FL][FR]" -map "0:v" -map "[FL]" -map "[FR]" \
      -metadata:s:a:0 language=jpn -metadata:s:a:1 language=eng \
      -c:v copy ${TMPFIL};
    mv ${f} ${f}.origin;
    mv ${TMPFIL} ${f};
    touch --reference=${f}.origin ${f};
done

というスクリプトを書いて録画済みの『きかんしゃトーマス』をコンバート。jpn/engをmetadataとして入れるのもポイントだ。

今後の録画エンコードについては~/bin/get_stream_map.plにchannelsplit対応を追加した~/bin/get_audio_parameter.plを作成。ストリームからステレオ/多国語の判断はできそうにないので、ファイル名に【二】が入っているかどうかとして、着地。

参照

82.hatenablog.com http://82.hatenablog.com/

ニコラボ https://nico-lab.net/

FFmpeg https://ffmpeg.org/

Wikipedia https://ja.wikipedia.org/wiki/

サラウンド音声対応

二ヶ国語音声対応で薄々気付いていたのだが、3D再生とサラウンドの対応が片付いたので、MPEG-4 AVC(H.264)トランスコードのサラウンド対応に本腰を入れる事に。

と言っても、取り敢えずAudio CODECをAACからドルビーAC-3に変更、チャンネル数を6にするだけで良い事がわかった。

# OPT_ACODEC="-acodec **aac -ac 2** -ar 48000 -ab 128k"
OPT_ACODEC="-acodec ac3 -ac 6 -ar 48000 -ab 128k"

AACの6CHだと2チャンネル環境のVLCでは音が出ないので、ドルビーAC-3にするのが肝要。

ソースが2chステレオか6ch(5.1ch)サラウンドなのかの判断について悩み中なのだが、ドルビーAC-3では2chステレオのソースを6ch(5.1ch)にエンコードしても問題無いので、取り敢えず全部6chでいいか。

参照

Wikipedia https://ja.wikipedia.org/wiki/

二ヶ国語音声対応

久々に動画エンコードの件。

Dlife/ディーライフ ロゴ

Dlife/ディーライフより

Dlife/ディーライフでオンエアしているミッキーマウスとロードレーサーズだが、放送波では日本語と英語の二ヶ国語放送なのに、MPEG-4 AVC(H.264)にトランスコードしたファイルによって日本語だったり英語だったりしている事に気付いた。

2か国語放送の仕組みとしてはアナログ放送時代から伝統的にステレオのL/Rを日本語/英語に置き換えたモノラル2カ国語が一般的なのだが、BSデジタル放送なディーライフの場合は日本語/英語それぞれ2chステレオを確保した2トラック(ストリーム)の構成となっているので、音声トラックが期待通りに選択されていないようだ。

「結果オーライで日本語が選択される期待だったのになぁ…」と思いつつ、現行の~/bin/get_stream_map.plをチェックしたところ、ビットレートの高いストリームが選ばれるようになっているのに気付いた。これは地上波デジタル放送をトランスコードするケースで低解像度なワンセグデータに惑わされないように、複数ストリームが含まれる場合にビットレートの一番高いストリームに着目するという処理を入れたのが安直過ぎ(考慮不足)で、結果的にAudioでは日本語か英語かが気まぐれでチョイスされてしまった模様。

そもそも、多言語音声は再生時に選択可能であるべきなので、Audioはビットレート100kbps以上の音声ストリームを全てMAPオプションで列挙する事で、MPEG-4 AVC(H.264)ファイルに複数音声トラックが取り込まれるように改修。

参照

82.hatenablog.com http://82.hatenablog.com/

Dlife/ディーライフ https://dlife.disney.co.jp/

Wikipedia https://ja.wikipedia.org/wiki/

NVENC実戦配備

昨日、NVENCに対応したUbuntuでのハードウェアエンコード環境ができたので、溜まったtsファイルをエンコードしていくことに。

PT2とPT3の複数実装で録画は並列でできるものの、GPUエンコードは並列処理できないと思われるので予約録画の流れでエンコードさせる仕組みは見直し、録画スクリプトはtsファイルを/mnt/ts_pool/10_recordedに移動させたところで終了とする。

yano@GT110b:~$ ll /mnt/ts_pool/
total 76
drwxr-xr-x  6 yano family    97 Feb  3 22:00 ./
drwxr-xr-x 14 root root    4096 Dec  9 17:23 ../
drwxrwxrwx  2 yano family 49152 Feb  4 22:45 10_recorded/
drwxrwxrwx  2 yano family  4096 Feb  4 09:39 19_encode_failed/
drwxrwxrwx  2 yano family 12288 Feb  4 22:45 20_encoded/
drwxrwxrwx  2 yano family 16384 Feb  4 08:02 30_ts_files/
yano@GT110b:~$

10分ごとにcronで起動する周期タスク~/etc/cron.sh/encode_mp4.cron/mnt/ts_pool/10_recordedから古い順に数本ずつピックアップして、エンコードできたのは/mnt/ts_pool/20_encodedに、エラーになったものは/mnt/ts_pool/19_encode_failedに移動させていく仕組みに。PIDFILEを使って重複起動しないようにするのを忘れずに。

yano@GT110b:~$ cat ~/etc/cron.sh/encode_mp4.cron
#!/bin/bash
PATH=/bin:/usr/bin:/sbin:/usr/sbin
NUM_FILES=5
EXT_TS=".ts"
PIDFILE=/home/yano/run/`basename $0`.pid
UUID=`id | sed 's/uid=\([0-9]*\)(.*/\1/'`;
[ $UUID -eq 0 ] && PIDFILE=/var/run/`basename $0`.pid;
if [ -e ${PIDFILE} ];
then
    exit;
fi
echo $$ > ${PIDFILE}
trap "/bin/rm -f ${PIDFILE}; exit" 1 2 3 15
CONFIGFILE=/etc/default/epgrec
# source config info
[ -r ${CONFIGFILE} ] && . ${CONFIGFILE}
TS_FILES=`ls -1 ${TS_RECORDED}/*${EXT_TS} | head -${NUM_FILES}`
for f in ${TS_FILES};
do
    /home/yano/bin/ts2mp4_nvidia.sh $f 2>&1 > /dev/null
    if [ $? -eq 0 ];
    then
        chown ${OWNER} ${MP4DIR}/`basename $f ${EXT_TS}`.mp4;
        mv $f ${TS_ENCODED};
    else
        mv $f ${TS_ENCODE_FAILED};
    fi;
done
if [ -e ${PIDFILE} ];
then
    rm -f ${PIDFILE};
fi
yano@GT110b:~$

参照

www.nodoka.org http://www.nodoka.org/

UbuntuとNVENC

Ubuntuでのハードウェアエンコード環境構築作業は先月18日24日とGStreamer+VAAPIにトライしたもののまだ先が長そうだ。

とはいえGT110bにもひと月分の録画済みファイルが溜まってしまったので、気分転換も兼ねてCUDA改めNVENCを試してみることに。

まずはGT710なMSI GT710 1GD3H LPを突っ込んで、libcudaとnvidiaドライバをインストール。

yano@haswell:~$ sudo apt-get install libcuda1-367 nvidia-367 nvidia-367-dev

nvidiaドライバと喧嘩するらしいnouveauをblacklistに登録して再起動。 続いてCompilationGuide/Ubuntuを読みながら、ffmpegのインストール。と思ったが、気まぐれに"ffmpeg -encoders"を見たところ、“NVIDIA NVENC H.264 encoder"が有効になっている事に気付いた。

yano@haswell:~$ ~/bin/ffmpeg -encoders 2>&1 | grep NVIDIA
 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)
yano@haswell:~$

ダメ元で

yano@haswell:~$ ~/bin/ffmpeg -i input.ts -vcodec h264_nvenc ouput.mkv
yano@haswell:~$

てな感じで動かしたところ、あっさりエンコードできたっぽい。まだチューニングの余地はあるものの

GstreamerとVAAPI

宿題を残したQSVハードウェアエンコード環境。

Intel VAAPI h264 encoding: gstreamer vs ffmpeg\avconvなどによるとVAAPI対応の選択肢としてGStreamerもあるようなので、試してみた。

yano@haswell:~/gst-test$ sudo apt-get install gstreamer1.0-vaapi*
yano@haswell:~/gst-test$ gst-inspect-1.0 vaapi
Plugin Details:
  Name                     vaapi
  Description              VA-API based elements
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvaapi.so
  Version                  0.5.7
  License                  LGPL
  Source module            gstreamer-vaapi
  Binary package           gstreamer-vaapi
  Origin URL               gwenole.beauchesne@intel.com
  vaapidecode: VA-API decoder
  vaapipostproc: VA-API video postprocessing
  vaapisink: VA-API sink
  3 features:
  +-- 3 elements
yano@haswell:~/gst-test$

との事。GStreamer VA-API Plugins 1.0 Plugins Reference Manualを見る限り「VA-API based H.264 video encoder」がありそうなのだが、どうやらubuntu 14.04の公式パッケージはデコーダ未対応の旧版な雰囲気だ。

というわけで、必然的に最新版をソースコードからbuildする方向にハンドルを切るわけだが、その前にGstreamerの独特な作法に馴染むべく、取り敢えずx264で試行錯誤してmp4のファイル出力にトライ。

yano@haswell:~/gst-test$ ffmpeg -i ~/20161210_2313_28_GRhd.ts -map 0:0 -map 0:1 \
  -vcodec copy -acodec copy ./input.ts
yano@haswell:~/gst-test$ gst-launch-1.0 \
  filesrc location=./input.ts ! progressreport ! tsdemux name=demuxer demuxer. ! queue ! \
  aacparse ! avdec_aac ! audioresample ! audioconvert dithering=0 ! voaacenc bitrate=25800 ! mux. \
  mp4mux name=mux ! filesink location=./gst-x264-`date +%Y%m%d_%H%M`.mp4 demuxer. ! queue ! mpegvideoparse ! mpeg2dec ! \
  videoconvert ! x264enc pass=quant ! video/x-h264,stream-format=byte-stream,profile=high ! h264parse ! mux.
Got EOS from element "pipeline0".
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Redistribute latency...
Redistribute latency...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
progressreport0 (00:00:05): 4869200 / 250449088 bytes ( 1.9 %)
progressreport0 (00:00:10): 8648000 / 250449088 bytes ( 3.5 %)
~中略~
progressreport0 (00:04:15): 241937200 / 250449088 bytes (96.6 %)
progressreport0 (00:04:20): 246054400 / 250449088 bytes (98.2 %)
Execution ended after 0:04:27.257661620
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
yano@haswell:~/gst-test$

ちなみに生のTSをそのまま喰わせると

UbuntuとQSV

昨日構築したQSVハードウェアエンコード環境。

16x32 8bit AVC/H.264って

真空波動研SuperLite 150418より

mp4/720pのエンコードが200fpsを超え、x264ソフトウェアと比較して10分の1以下という強烈な時短効果が得られる結果に満足。

同ファイルサイズ(≒ビットレート)での画質を考えるとx264には遠く及ばないものの、TVのオンエアを録画する観点では充分な印象だ。

ただ気になっているのが、エクスプローラーでの詳細情報で時間などが表示されないこと。

「真空波動研SuperLite」でもちょっとおかしなプロファイル表示になるので、宿題としておきたい。

参照

Qiita http://qiita.com/

大ちゃんのいろいろ雑記 https://www.taruki.com/

Web Net Force http://webnetforce.net/

hirooka.pro https://hirooka.pro/

Kung Noi Blog http://www.goodnai.com/

rigayaの日記兼メモ帳 http://rigaya34589.blog135.fc2.com/

UbuntuとQSV

H97 Pro4は修理に出して、再びUbuntuでのハードウェアエンコード環境構築に着手。

2015年9月にIntel® Media Server StudioのCommunity Editionが無償公開されたので、予てよりこそこそとトライしていたのだが、対応するCPU世代がHaswell以降に限定されてたり、カーネルのカスタマイズ(rebuild)が必要なことからCentOSやカーネル版数の縛りが避けられずUbuntuでの環境構築になかなか難儀。昨年9月公開のIntel Media Server Studio 2017ではカーネルのrebuildも不要になったという噂も耳にしたが、CentOSとUbuntuでは話が異なる事から鵜呑みにするわけにも行かず。

Intel® Media Server StudioではなくVAAPI経由でffmpegから気軽にQSVを使えるレポートがtappieさんから報告されていたので、試してみる事に。

まずはVAAPIドライバのインストール。

yano@haswell:~$ sudo apt-get update
yano@haswell:~$ sudo apt-get install libva1 vainfo i965-va-driver
yano@haswell:~$ vainfo
error: can't connect to X server!
libva info: VA-API version 0.39.2
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_38
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.39 (libva 1.7.1)
vainfo: Driver version: Intel i965 driver for Intel(R) Haswell Desktop - 1.6.1.pre1 (1.6.1.pre1)
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Simple            : VAEntrypointEncSlice
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileH264MultiviewHigh      : VAEntrypointVLD
      VAProfileH264MultiviewHigh      : VAEntrypointEncSlice
      VAProfileH264StereoHigh         : VAEntrypointVLD
      VAProfileH264StereoHigh         : VAEntrypointEncSlice
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileH264MultiviewHigh      : VAEntrypointVLD
      VAProfileH264MultiviewHigh      : VAEntrypointEncSlice
      VAProfileH264StereoHigh         : VAEntrypointVLD
      VAProfileH264StereoHigh         : VAEntrypointEncSlice
yano@haswell:~$ ls -n /dev/dri
total 0
crw-rw----+ 1 0 44 226,   0 Jan 12 22:30 card0
crw-rw----  1 0 44 226,  64 Jan 12 22:30 controlD64
crw-rw----+ 1 0 44 226, 128 Jan 12 22:30 renderD128

と/dev/dri配下にrenderD128ができれば(恐らく)OK。 続いてCompilationGuide/Ubuntuを読みながら、ffmpegのインストール。