Intel入ってるNASでVAAPIを使う


きっかけ

nasneでTVを観ているのですが,

  • 視聴に専用のソフトが必要
  • Macで視聴するには,
    • Parallels/VMware Fusionなどのような,高性能な仮想化ソフトウェアを用いてPCTV Plusで視聴しないといけない.
    • 非公式なMac用ソフトウェアが必要.
  • そもそもnasneのHDDが死んだときに録画データも死ぬ.当然市販のレコーダーだって同様.
    • 市販の録画機では冗長性0.

などの問題があり,市販のエンドユーザ向け録画機ではまともに利用できません.

そこで,録画サーバを構築しようと思ったのですが,サーバでトランスコード/エンコードができないと,
帯域・ストレージリソースを大量に消費してしまいますよね.
そうなると,HWエンコーダなどの支援がほしいところです.

NAS

現在,私はSynology DS218+というNASを持っています.
このNASは,IntelのCeleron J3355というCPUが内蔵されています.このため,Synology公式でDockerに対応しています.
また,このCPU,Intel公式を見てみると,QSVに対応している模様です.
https://ark.intel.com/content/www/jp/ja/ark/products/95597/intel-celeron-processor-j3355-2m-cache-up-to-2-5-ghz.html
つまり,DockerからうまいことHWエンコーダを呼び出せば,QSVを利用して高速エンコードができるようになります.

目的

しかし,やはり実際にエンコードを走らせてみないと,まともに使えるのかわかりません.
そこで,本記事においての目的としては,録画サーバを組む前段階として,
Intel入ってるNASでは,HWエンコードがどのくらいの性能なのか?とします.

用意したもの

  • DS218+

    • おそらくQSV対応のIntel CPUを積んでいて,以下の条件に合致していれば,他のNASでも使えると思います.
    • NASにSSH可能
    • Dockerインストール済み
    • 後述するスクリプト
    • DSMのLinuxカーネル4.4.59+
      $ uname -r
      4.4.59+
    
  • 30分アニメを録画したtsファイル(hoge.ts)

  • 非公式なので,何があっても自分でなんとかする強い気持ち

検証

IntelCPUが入っている本NASにおいては,encordデバイスが/dev/dri:/dev/driにあります.
他のIntelCPUが内蔵されているものも同様かと思われます.
これをコンテナに渡してやることで,コンテナ内にて,ホストのHWエンコーダを利用できます.

方法

こちらを参考にしました.→https://timothybasanov.com/2018/12/08/hardware-accelerated-h264-encoding-synology-nas.html

今回は,VAAPIでQSVを使います.
このため,VAAPIに対応したffmpegなDockerコンテナで検証します.

以下のスクリプトを書きました.

encord_test.sh
#!/bin/sh
host_tsdir=/volume1/video
container_tsdir=/tmp
host_mp4dir=/volume1/video/mp4
container_mp4dir=/media
movie_name=hoge

sudo docker run --rm \
--device /dev/dri:/dev/dri \
-v ${host_tsdir}:${container_tsdir} \
-v ${host_mp4dir}:${container_mp4dir} \
jrottenberg/ffmpeg:vaapi \
-hwaccel vaapi -hwaccel_output_format vaapi \
-i ${container_tsdir}/${movie_name}.ts \
-vf 'scale_vaapi=w=1280:h=720' \
-c:v h264_vaapi \
${container_mp4dir}/${movie_name}.mp4

結果

エンコード速度とCPU負荷の検証,エンコード前後でのファイルサイズの比較を行いました.

実行速度

まず,スクリプトを実行したときの実行結果です.
4倍以上,安定してエンコードできているのがわかります.非常に高速です.

./encord_test.sh
(省略)
Output #0, mp4, to '/media/hoge.mp4':
  Metadata:
    encoder         : Lavf58.20.100
    Stream #0:0: Video: h264 (h264_vaapi) (avc1 / 0x31637661), vaapi_vld, 1280x720 [SAR 1:1 DAR 16:9], q=-1--1, 29.97 fps, 30k tbn, 29.97 tbc
    Metadata:
      encoder         : Lavc58.35.100 h264_vaapi
    Stream #0:1: Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc58.35.100 aac
frame= 1996 fps=142 q=-0.0 size=   42240kB time=00:01:06.46 bitrate=5206.1kbits/s dup=14 drop=0 speed=4.72x

処理負荷

このとき,どのくらいのCPUリソースを利用しているのかみてみました.
ちなみにリソース監視は,Prometheus+NetData+GrafanaをDockerで建てて,フルコンテナ運用しています.
スクリーンショットはGrafanaのダッシュボードです.
概ね40%ちょっとくらいのCPU使用率で安定しています.

圧縮率

今回,1920x1080のtsファイルを,1280x720のmp4(h264)に変換したため,割と小さいサイズになっています.
概ね半分以下のサイズに抑えられています.

まとめ

非常に実用的な速度で,実用的なリソース消費で,消費電力も(おそらく)そこまでではなさそうなので,
IntelのQSVが使えるNASをお持ちであれば,エンコードサーバにするのもありだと思います.
今回,録画サーバにおけるエンコード性能として検証しましたが,systemdで適当に動かすなり,
cronでスケジューリングなりすれば,NASに溜めておいたホームビデオの自動エンコードなども可能になると思います.
また,まだまだffmpegの設定を調整すれば,さらなる容量削減や,インターレース解除などもできると思いますし,
そこあたりは今後の課題とします.いいffmpegオプションなどありましたらぜひ教えて下さい.

録画サーバを組むとしたら

チューナデバイスとしては,PX-S1UDを考えています.このチューナ,ドライバがPLEX公式から出ています.
また,Linuxのディストリ依存などがなく,DSMでも動く模様(https://qiita.com/xingoxu/items/c813c4ed048116f653a6#%E3%82%A2%E3%83%B3%E3%83%86%E3%83%8A%E8%A8%AD%E7%BD%AE )です.良かった.
当初は,エンコード性能・省電力性能が高いRaspberry Pi4を買おうか迷っていましたが,NAS一台で完結しそうです.
また,録画サーバのソフトウェア周りも実はコンテナ化して運用可能です.
https://github.com/l3tnun/docker-mirakurun-epgstation
つまるところ,NAS一台で,録画サーバまでフルコンテナ運用ができそうです.
万一,Docker内サーバの環境が壊れても,別にいくつかのバックアップをちゃんと取るようにしているので,
ある程度の冗長性が確保できそうです.かなり安定性の高い録画システムが組めるのではないでしょうか.

おまけ

1920x1080で出力した結果がほしいという声が聞こえてきそうなので,検証してみました.

実行速度

Output #0, mp4, to '/media/hoge.mp4':
  Metadata:
    encoder         : Lavf58.20.100
    Stream #0:0: Video: h264 (h264_vaapi) (avc1 / 0x31637661), vaapi_vld, 1920x1080 [SAR 1:1 DAR 16:9], q=-1--1, 29.97 fps, 30k tbn, 29.97 tbc
    Metadata:
      encoder         : Lavc58.35.100 h264_vaapi
    Stream #0:1: Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc58.35.100 aac
frame=52707 fps= 85 q=-0.0 Lsize= 2034563kB time=00:29:18.59 bitrate=9477.6kbits/s dup=14 drop=0 speed=2.85x

処理負荷

ダウンコンバートしていないためか,多少,CPU負荷が少なくなっています.概ね40%行かないくらいのCPU使用率ですね.

圧縮率

ほとんど圧縮できていませんね.でもffmpegの設定をよしなに調整すればちゃんと圧縮できそうです.