コーデックと特許

SENCA がどのコーデックをどう扱うかを説明します。H.264・H.265 は GPU メーカーの SDK だけで変換し、AV1・VP8/VP9・Opus はロイヤリティフリーのライブラリで処理します。用意するものと、無いときの動作をまとめます。

運用と安全

このページの見出し
  1. 方針
  2. パススルーはいつでも使えます
  3. エンコード・デコードが必要な操作
  4. ハードウェアのプロバイダー
  5. ロイヤリティフリーのソフトウェアコーデック
  6. コーデックワーカー
  7. ロイヤリティフリーのコーデックだけを使う(codec_profile: royalty_free)
  8. GET /capabilities と GET /devices
  9. ライセンスについての注意
  10. 関連するページ

自分の環境に何を入れれば何ができるのか。その判断に必要なことを、コーデック(映像・音声を圧縮・展開する方式)ごとにまとめました。 SENCA が製品に含めないもの、実行時に読み込むもの、運用する人が用意するもの(GPU のドライバー、ロイヤリティフリーのコーデックライブラリ)と、それらが無いときの動作を説明します。

法的な助言ではありません。 このページは、SENCA の実装の方針を説明するものです。配信するコンテンツ、サービス、地域によって どのライセンス(特許プールの料金を含む)が必要になるかは、ご自身で確認してください。

まず押さえておきたいのは、受信した映像・音声をそのまま配信・録画する経路(パススルー)なら、GPU もライブラリも無しでいつでも使えることです。 変換(エンコード・デコード)が要る場面でだけ、以下の方針が関わってきます。

方針

  1. H.264・H.265 のエンコード・デコードは、GPU メーカーのハードウェアコーデックだけで行います。 ソフトウェアの H.264/H.265 コーデック (libavcodec、OpenH264、x264、x265 など)は製品に含めず、読み込みもしません。
  2. AAC は変換せず、そのまま通す(パススルー)だけです。 AAC のエンコード・デコード(fdk-aac など)は含めないので、音声を変換するときは Opus にします。
  3. ロイヤリティフリーのコーデックは、ソフトウェアで処理します。 使うのは dav1d(AV1 のデコード)、SVT-AV1(AV1 のエンコード)、 libvpx(VP8/VP9)、libopus(Opus)です。
  4. 外部のコーデックライブラリは製品に同梱しません。実行時に、別のプロセスであるコーデックワーカー(実行ファイルは senca-codec-worker)が読み込みます(dlopen)。 ノード本体はコーデックライブラリを読み込みません。
  5. 必要なデバイスやライブラリが無いときに、黙って品質を落とすことはしません。理由を添えてエラー(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_pushFLV・Enhanced RTMP で運べるもの
SRT の再生・srt_pushTS で運べるもの
RTSP の再生RTP で運べるもの
WHEPH.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読み込むライブラリエンコードデコード
nvidiaNVENC・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・AV1H.264・H.265・AV1・VP9
intel-vploneVPL(Quick Sync)libvpl.so.2(このライブラリがドライバーの実装を探します)H.264・H.265・AV1H.264・H.265・AV1・VP9
amd-amfAMF(Linux では Vulkan)libamfrt64.so.1H.264・H.265・AV1H.264・H.265
vaapiVA-APIlibva.so.2・libva-drm.so.2、/dev/dri/renderD*なしH.264

どのプロバイダーでも、使うのはハードウェアの実装だけです。oneVPL・AMF が持つソフトウェア実装は使いません。 ライブラリやデバイスが無くてもエラーにはせず、そのプロバイダーを「使えない」状態として扱います。理由は GET /devices に表示されます。 Apple VideoToolbox には対応していません。

コンテナで GPU を使うときは、デバイスとドライバーのライブラリをコンテナに渡します(運用、compose.yaml)。

ロイヤリティフリーのソフトウェアコーデック

プロバイダーライブラリ(soname)用途ライセンス
dav1dlibdav1d.so.7AV1 のデコードBSD-2-Clause
svt-av1libSvtAv1Enc.so.2AV1 のエンコードBSD-3-Clause+AOM の特許許諾
libvpxlibvpx.so.12(libvpx 1.16 の ABI)VP8・VP9 のエンコード・デコードBSD-3-Clause+WebM の特許許諾
opuslibopus.so.0Opus のエンコード・デコード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 に合わせています。

ライブラリは、次の順に探します。

  1. --codec-lib-dir DIR で指定した場所。ノードがコーデックワーカーの環境変数 SENCA_CODEC_LIB_DIR として渡します。: 区切りで複数指定できます。 公式のコンテナイメージは --codec-lib-dir /usr/lib/x86_64-linux-gnu で起動します。
  2. そこで見つからなければ、システム既定の 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)に合わせています。