運用と安全
このページの見出し
自分の環境に何を入れれば何ができるのか。その判断に必要なことを、コーデック(映像・音声を圧縮・展開する方式)ごとにまとめました。 SENCA が製品に含めないもの、実行時に読み込むもの、運用する人が用意するもの(GPU のドライバー、ロイヤリティフリーのコーデックライブラリ)と、それらが無いときの動作を説明します。
法的な助言ではありません。 このページは、SENCA の実装の方針を説明するものです。配信するコンテンツ、サービス、地域によって どのライセンス(特許プールの料金を含む)が必要になるかは、ご自身で確認してください。
まず押さえておきたいのは、受信した映像・音声をそのまま配信・録画する経路(パススルー)なら、GPU もライブラリも無しでいつでも使えることです。 変換(エンコード・デコード)が要る場面でだけ、以下の方針が関わってきます。
方針
- H.264・H.265 のエンコード・デコードは、GPU メーカーのハードウェアコーデックだけで行います。 ソフトウェアの H.264/H.265 コーデック (libavcodec、OpenH264、x264、x265 など)は製品に含めず、読み込みもしません。
- AAC は変換せず、そのまま通す(パススルー)だけです。 AAC のエンコード・デコード(fdk-aac など)は含めないので、音声を変換するときは Opus にします。
- ロイヤリティフリーのコーデックは、ソフトウェアで処理します。 使うのは dav1d(AV1 のデコード)、SVT-AV1(AV1 のエンコード)、 libvpx(VP8/VP9)、libopus(Opus)です。
- 外部のコーデックライブラリは製品に同梱しません。実行時に、別のプロセスであるコーデックワーカー(実行ファイルは
senca-codec-worker)が読み込みます(dlopen)。 ノード本体はコーデックライブラリを読み込みません。 - 必要なデバイスやライブラリが無いときに、黙って品質を落とすことはしません。理由を添えてエラー(503
CAPACITY_UNAVAILABLEや検証のエラー)を返します。
H.264/H.265 のビットストリームの解析と形式の変換(Annex B 形式と長さプレフィックス形式の相互変換、SPS/PPS/VPS の解析、RTP のパケット化、TS・fMP4・FLV への格納)は、 エンコード・デコードにはあたらないため、SENCA 自身が行います。
パススルーはいつでも使えます
エンコード・デコードをしない経路では、GPU もコーデックライブラリも要りません。経路ごとにパススルーできるコーデックは次のとおりです。
| 経路 | パススルーできるコーデック |
|---|---|
| 取り込み(RTMP・SRT・WHIP・pull) | H.264・H.265・AV1・VP8・VP9・AAC・Opus・G.711(経路ごとの対応は 取り込みと再生) |
| HLS(TS) | H.264・H.265・AAC・Opus |
| HLS(fMP4) | H.264・H.265・AV1・VP9・AAC・Opus |
| 録画・VOD・MP4 のエクスポート | HLS と同じ(同じセグメントを使います) |
RTMP の再生・rtmp_push | FLV・Enhanced RTMP で運べるもの |
SRT の再生・srt_push | TS で運べるもの |
| RTSP の再生 | RTP で運べるもの |
| WHEP | H.264・VP8・VP9・AV1・Opus・PCMA・PCMU(AAC は運べないため、AAC の音声は出ません) |
| 字幕 | AAC・Opus の音声を、変換せずに入れ物だけ替えて送ります(字幕と翻訳) |
POST /streams/{id}/plan を使うと、現在の入力の各トラックが各出力でどう扱われるか(remux・repacketize・passthrough・unsupported と、その理由)を確認できます。
エンコード・デコードが必要な操作
| 操作 | 必要なもの | 無いとき |
|---|---|---|
現在の画像 GET /streams/{id}/snapshot | 映像のデコード | 503 CAPACITY_UNAVAILABLE(retryable: false) |
静止画の保存(snapshots の設定・snapshot の予約) | 映像のデコード | 保存されません(ログに理由が出力されます) |
| 録画のサムネイル | 映像のデコード | 作成されません(GET /recordings/{id}/thumbnail は 404) |
パイプライン(decode・encode) | 処理ノードごとのデコード・エンコード | 作成・変更が 503 CAPACITY_UNAVAILABLE、または 400 POLICY_REJECTED・UNSUPPORTED_CODEC(パイプライン) |
| ルームのメディアパイプラインの合成 | 参加者の映像のデコードと合成のエンコード(既定 AV1) | メディアパイプライン を参照 |
| キャプチャの入力 | キャプチャワーカーでのエンコード(既定 VP9) | 入力が error・backoff になります |
たとえば、GPU の無いノードで H.264 のストリームの現在の画像を要求すると、次の応答が返ります。
{"type":"urn:senca:error:capacity-unavailable","title":"h264 を復号できる装置がありません(H.264/H.265 はハードウェアのデコーダーだけを使います)",
"status":503,"code":"CAPACITY_UNAVAILABLE","retryable":false}
VP9 のストリームなら、同じノードでも libvpx でデコードでき、JPEG・PNG が返ります。
ハードウェアのプロバイダー
プロバイダー(provider) | API | 読み込むライブラリ | エンコード | デコード |
|---|---|---|---|---|
nvidia | NVENC・NVDEC(Video Codec SDK 13.1、Linux ドライバー 610 以上) | libcuda.so.1・libnvidia-encode.so.1・libnvcuvid.so.1(libnvidia-ml.so.1 はバージョン表示だけに使い、無くてもかまいません) | H.264・H.265・AV1 | H.264・H.265・AV1・VP9 |
intel-vpl | oneVPL(Quick Sync) | libvpl.so.2(このライブラリがドライバーの実装を探します) | H.264・H.265・AV1 | H.264・H.265・AV1・VP9 |
amd-amf | AMF(Linux では Vulkan) | libamfrt64.so.1 | H.264・H.265・AV1 | H.264・H.265 |
vaapi | VA-API | libva.so.2・libva-drm.so.2、/dev/dri/renderD* | なし | H.264 |
どのプロバイダーでも、使うのはハードウェアの実装だけです。oneVPL・AMF が持つソフトウェア実装は使いません。
ライブラリやデバイスが無くてもエラーにはせず、そのプロバイダーを「使えない」状態として扱います。理由は GET /devices に表示されます。
Apple VideoToolbox には対応していません。
コンテナで GPU を使うときは、デバイスとドライバーのライブラリをコンテナに渡します(運用、compose.yaml)。
ロイヤリティフリーのソフトウェアコーデック
| プロバイダー | ライブラリ(soname) | 用途 | ライセンス |
|---|---|---|---|
dav1d | libdav1d.so.7 | AV1 のデコード | BSD-2-Clause |
svt-av1 | libSvtAv1Enc.so.2 | AV1 のエンコード | BSD-3-Clause+AOM の特許許諾 |
libvpx | libvpx.so.12(libvpx 1.16 の ABI) | VP8・VP9 のエンコード・デコード | BSD-3-Clause+WebM の特許許諾 |
opus | libopus.so.0 | Opus のエンコード・デコード | BSD-3-Clause+IETF での宣言に基づく特許許諾 |
インストール
ディストリビューションのパッケージをインストールします。公式のコンテナイメージ(Dockerfile)は Ubuntu 26.04 をもとにしており、次のパッケージを入れています。
apt-get install -y --no-install-recommends libdav1d7 libvpx12 libopus0 libsvtav1enc2 libva2 libva-drm2 libvpl2
soname(ライブラリのバージョンを表す名前)が合わないもの(例: libvpx.so.9 しか無い場合)は読み込みません。libvpx は 1.16(libvpx.so.12)の ABI に合わせています。
ライブラリは、次の順に探します。
--codec-lib-dir DIRで指定した場所。ノードがコーデックワーカーの環境変数SENCA_CODEC_LIB_DIRとして渡します。:区切りで複数指定できます。 公式のコンテナイメージは--codec-lib-dir /usr/lib/x86_64-linux-gnuで起動します。- そこで見つからなければ、システム既定の dlopen の検索順(
LD_LIBRARY_PATHを含む)で探します。
読み込むのはプロバイダーごとに決まった soname だけで、API からライブラリのパスを指定することはできません。
特定のプロバイダーを使わせないときは、ノードの環境変数 SENCA_CODEC_DISABLE に、, 区切りでプロバイダー名(nvidia・intel-vpl・amd-amf・vaapi・
dav1d・libvpx・svt-av1・opus)か、hardware・software を指定します。
インストールできたかどうかは、GET /api/v1/capabilities の codecs.transcode と GET /api/v1/devices で確認できます(下の「GET /capabilities と GET /devices」)。
コーデックワーカー
実行ファイル senca-codec-worker は、senca-node と同じディレクトリに置いてください。別の場所に置くなら --codec-worker-bin FILE で指定します。
静止画・サムネイルのような短いジョブ用のコーデックワーカーの数は、--codec-workers N で決めます(0 か省略で CPU のコア数)。パイプラインはこれとは別に、1 つにつき 1 プロセスを使います。
1 つのジョブのタイムアウトは 30 秒で、コーデックワーカーが異常終了したら起動し直します。
コーデックワーカーが見つからないか起動しないときも、ノードは codec worker unavailable: ... をログに出して動き続けます。
ただしその間、静止画・サムネイル・パイプラインは使えず、503 になるか作成されません。GET /capabilities の pipelines は false、codecs.transcode は空になります。
サンドボックス(Linux)
コーデックワーカーは、適用した制限を起動時のログに出力します(例: sandbox: core=0; nofile=256; no_new_privs; landlock(abi 8): writes only under /dev; cpu=300s/job; seccomp deny-list)。
コーデックワーカーは、親プロセス(ノード)が終了すると一緒に終了します。ほかのプロセスから ptrace で操作されないようにし(PR_SET_DUMPABLE=0)、core ファイルを作らず、PR_SET_NO_NEW_PRIVS も設定します。
対応するカーネルでは、Landlock で /dev の下(GPU のデバイスファイル)以外でのファイルの作成・書き込み・削除を禁止します。ライブラリを dlopen で読み込む必要があるので、読み取りは許可しています。
さらに seccomp の拒否リストで、ネットワーク(socket・connect・bind・listen・accept)、プログラムの実行、ptrace、mount、カーネルモジュール、bpf、名前空間などを禁止します。
ネットワークを禁じているため、NVIDIA の persistenced への接続など、ドライバーの補助機能の一部は使えません。
ジョブごとに CPU 時間の上限もあり、超えるとコーデックワーカーは終了して起動し直されます。
詳しくは セキュリティ を見てください。
ロイヤリティフリーのコーデックだけを使う(codec_profile: royalty_free)
ストリームの codec_profile を royalty_free にすると、そのストリームでは特許プールのあるコーデック(H.264・H.265・AAC)を扱いません。
配信者には、AV1・VP9・VP8 と Opus で送ってもらってください(WHIP・Enhanced RTMP。取り込みと再生)。
H.264・H.265・AAC のトラックが届いた場合、配信者の接続は切らずに、そのトラックだけを捨てます(ログに rejected by royalty_free profile; dropping track)。
映像が H.264 なら、映像の無い配信になってしまいます。
hls.container は fmp4 にしてください。AV1・VP9 は TS に格納できないため、ts のままだと作成・変更が 400 になります。
パイプラインでは、入力(source)か出力先(sink)のストリームのどれか 1 つでも royalty_free なら、H.264・H.265・AAC を使うと(パススルーでも)POLICY_REJECTED になります。
静止画・サムネイル・キャプチャのエンコードでも、この方針に従ってプロバイダーを選びます。
ストリームの処理では再エンコードしないので、配信計画(POST /streams/{id}/plan)に変換は出てきません。royalty_free のストリームに届いた
H.264・H.265・AAC のトラックは、計画ではすべての出力で unsupported(理由付き)になります。AV1 などへ変換したいときは、
パイプラインの decode・encode で別のストリームに出力してください。H.264・H.265 のデコードには GPU が必要です(上の「エンコード・デコードが必要な操作」)。
curl -s -X POST "$API/streams" "${H[@]}" -d '{"name":"rf1","codec_profile":"royalty_free","hls":{"container":"fmp4"}}'
GET /capabilities と GET /devices
GET /api/v1/capabilities(認証されていれば権限は問いません)は、このノードでできることを返します。
{
"api_version": "v1",
"codecs": {
"passthrough": ["h264","h265","av1","vp8","vp9","aac","opus","pcma","pcmu"],
"transcode": [
{"provider":"dav1d","codec":"av1","direction":"decode","hardware":false,"max_width":16384,"max_height":16384,"max_sessions":null,"device":"dav1d"},
{"provider":"libvpx","codec":"vp8","direction":"encode","hardware":false,"max_width":16383,"max_height":16383,"max_sessions":null,"device":"libvpx"}
]
},
"codec_profiles": ["any","royalty_free"],
"pipelines": true
}
(抜粋です。GPU の無いマシンに、ロイヤリティフリーのライブラリをインストールした場合の例です)
codecs.transcode には、コーデックワーカーが実際に使えるプロバイダーが並びます。各要素に、プロバイダー、コーデック、方向、ハードウェアかどうか、最大解像度、同時セッション数、デバイス名が入ります。
応答にはほかに ingest・output・recordings・schedules・inputs・outputs・paas_providers・captions・rtsp_play・cluster があります(管理 API と SDK)。
GET /api/v1/devices(node:admin)は、プロバイダーごとの状態と理由、サンドボックス、キャプチャデバイスを返します。
{"nodes": [{"node": "…",
"devices": {"providers": [{"provider": "nvidia", "available": false, "detail": "…libcuda.so.1…"},
{"provider": "dav1d", "available": true, "detail": "…"}],
"sandbox": "…"},
"capture": {"available": false, "reason": "senca-capture-worker がありません"}}]}
available: false のときは、detail にライブラリやデバイスが見つからない理由が表示されます。
ライセンスについての注意
ハードウェアのコーデックは、メーカーがライセンス料を支払った製品の機能です。それでも、配信サービスやコンテンツの配布にかかわる特許料 (例: Via LA の AVC/HEVC、Access Advance)は、ハードウェアを買っただけでは済まない場合があります。
AAC をそのまま中継するときの扱いや、AV1・VP8・VP9・Opus について第三者の特許プールが権利を主張していることなど、確認すべき点はほかにもあります。SENCA は、AV1 などを「特許がない」とは表示しません。 ご自身のサービス、地域、コンテンツに何が必要かは、ご自身で確認してください。
関連するページ
この文書の原文は、リポジトリの docs/guide/ja/14-codecs-and-patents.md にあります。内容は現在の版(v0.0.1)に合わせています。