EPGStationでQSVエンコード 2024夏 梅雨明け記念増刊号
前回のお話はこちら。
10年落ちのHaswellを使うのがSDGsとか書きましたが、結局おニューのCPUを試してみたくてN100マシンを買っちゃいました。
なので前回記事の増補版として、N100マシンでいろいろ遊んでみた記録を書き残しておきます。
N100マシンでProxmox
これは特に躓くことなくすんなり入った。すんなり行きすぎて面白くないけど、とても便利。デバイスのパススルー設定とかもとても簡単。
VMを作って、チューナー、内蔵GPU、ICカードリーダーをパススルーしてあげればOK。
N100なのでHEVCをQSVでエンコしたい
こんなの簡単でしょ…とか思ってたら意外と手こずった。
試行錯誤の末、最終的に行き着いたコマンドは以下。
ffmpeg -fflags +igndts -probesize 10M -analyzeduration 10M -f mpegts -vaapi_device /dev/dri/renderD128 -i “$INPUT” -map 0:v:0 -map 0:a:0 -vf 'format=nv12,hwupload' -c:a aac -b:a 128k -c:v hevc_vaapi -profile:v main -level 4.1 -qp 23 “$OUTPUT”
試行錯誤中にぶち当たった問題のまとめ。
m2ts入力ファイルをデコードする際の無効なフレームサイズエラー。これはソースビデオの破損や非標準的な要素に関連しているようでした。ハードウェアデコーダではどうしてもエラー解消に至らなかったので、入力にソフトウェアデコードを使用しつつ、エンコードにだけVAAPIを使用することで解決しました。
scale_vaapiフィルターを使用する際の「Impossible to convert between the formats」エラー。これは、デコードされたフレームのピクセルフォーマットとスケーラーが期待するものとの不一致が原因でした。フレームをNV12フォーマットに明示的に変換し、スケーリング前にVAAPIサーフェスにアップロードすることで修正されました。まぁ最終的にスケーリングやめたんですけど…。
"filter_hw_device"オプションを使用する際のVAAPIデバイス初期化エラー。これは/dev/dri/renderD128のアクセス権の問題が原因でした。あれこれ考えるのが面倒だったのでアクセス権を777にして解決しましたが、多分666でもいける(未検証)
AACオーディオエンコーディングエラー。ソースの音声データの破損や不正が原因と思われます。どうも放送波のストリームはエラーが多いですね。直接コピーする代わりに、ソフトウェアエンコーダーを使用してオーディオストリームを再エンコードすることで回避しました。
Dockerコンテナ内でffmpegコマンドを実行した際のメモリ割り当てエラー。VMへのメモリ割り当てやらコンテナのメモリ最大値をいろいろいじったのですが結局メモリのサイズにはあまり依存していない様でした。とりあえずVAAPIスケーリングフィルターを削除したら動いたのでそれでよしとしてます。
字幕を焼き付ける際の「arib_caption」デコーダーが見つからないエラー。ffmpegがそのコーデックをサポートするようにコンパイルされていなかったため、ビデオとオーディオのストリームだけを明示的にマッピングして(-map 0:v:0 -map 0:a:0)、出力からそのストリームを無視または除外することで解決しました。
最終的に採用したコマンドに出てくるオプションの説明。
-fflags +igndts: 入力ファイルのDTSタイムスタンプを無視します。これにより、破損したタイムスタンプを含むファイルでもffmpegが処理を続行できます。
-probesize 10M: 入力ファイルの先頭10MBを解析して、ファイルのフォーマットやコーデックを判定します。デフォルトは5MBです。
-analyzeduration 10M: 入力ファイルの先頭10MBを解析して、ストリーム情報を判定するのに使う時間を指定します。デフォルトは5秒です。
-f mpegts: 入力ファイルのフォーマットをMPEG-TSと指定します。
-vaapi_device /dev/dri/renderD128: VAAPIハードウェアアクセラレーションに使用するデバイスを指定します。
-i "$INPUT": 入力ファイルを指定します。
-map 0:v:0 -map 0:a:0: 入力ファイルから1つ目のビデオストリームと1つ目のオーディオストリームを選択してマッピングします。
-vf 'format=nv12,hwupload': ビデオフィルターを指定します。デコードされたフレームをNV12フォーマットに変換し、VAAPIサーフェスにアップロードします。
-c:a aac -b:a 128k: オーディオコーデックをAACに指定し、ビットレートを128kbpsに設定します。
-c:v hevc_vaapi: ビデオコーデックをVAAPI経由のHEVCエンコーダーに指定します。
-profile:v main -level 4.1: HEVCのプロファイルをmainに、レベルを4.1に設定します。
-qp 23: 量子化パラメーター(QP)を23に設定し、出力画質を制御します。値が小さいほど高画質になりますが、ファイルサイズは大きくなります。
"$OUTPUT": 出力ファイルを指定します。
それはそうとProxmox便利
チョー気軽にブラウザ上のGUIからLXCコンテナ作ってシェルに入ってサーバを立てられるし、入れてみた結果イマイチだな、と思ったらコンテナごと消しちまえば綺麗さっぱりなくなって他の環境にはなんの影響もないので、大変気に入りました。以下参考サイト。