H.264プロファイル比較。ブラウザのビデオエンコード設定調査

こんにちは、テリーです。ブラウザでビデオ会議を毎日していますが、ビデオの画質設定はほとんどしたことがありません。あるとすると背景画像の設定か、最近ではボカシ設定でしょうか。日常的なビデオ会議で顔だけを映す場合、画質が重要になるシーンはそれほど多くありませんが、人以外のモノを映す場合、特に文字・水・森・多数の人が映っている細かい映像の場合は、画質もフレームレートもどちらも譲れないということがあります。ビットレートを上げずにビデオの品質を調整できないでしょうか?今回はWebRTCで映像配信する場合を想定した、ブラウザのH.264プロファイルの変更方法と比較方法をご紹介します。

動作確認環境

  • Windows 21H2(OS Build 22000.675)
  • Chrome 102.0.5005.63

対応ビデオコーデック一覧

ブラウザが対応しているビデオコーデックはどのように取得するのでしょうか?

こちらのサイトにアクセスしてください。Startボタンを押すとCodec preferences のドロップダウンに、ブラウザが対応しているビデオコーデックが表示されます。

当方の環境では、VP8, VP9, H.264, AV1コーデックに対応していることがわかります。

VP8とAV1コーデックは1通りしか選べないようですが、VP9とH.264のコーデックではprofileという値が複数あり、目的によってprofileを切り替えることができそうに見えます。

VP9のプロファイル

VP9のprofileはビット深度の変更です。10bit映像のカメラを配信する場合はprofile-id=2にすると画質向上が期待できます。空や水面のような微妙なグラデーションの場合、よく見るときれいに表現できることがわかります。

こちらのYouTubeビデオでは、8bitと10bitの映像を並べて比較し、ビット深度の違いを体験できます。

H.264のプロファイル

H.264はCPUの計算速度・メモリ容量に今ほど余裕のなかった時代に開発されたコーデックであるため、エンコード・デコードに必要な機能の実装をあえて省略する試みがなされたように見えます。プロファイルの大きい値を選択するほど、エンコードもデコードも計算量が増え、メモリを多く消費します。

profile-level-id 解釈
42001f 42 = Baselineプロファイル
1f = レベル3.1
42e01f 42 = Constrained Baselineプロファイル
e0 = Baseline, Main, Extendedプロファイルのデコードに対応
1f = レベル3.1
4d001f 4d = Mainプロファイル
1f = レベル3.1
64001f 64 = Highプロファイル
1f = レベル3.1

level-asymmetry-allowed=1というのは、送受信でレベルが異なっているのを許容するか否かです。レベルは確保するメモリの容量を意味します。昔はスペックの低い方の設定に合わせていたようです。レベル3.1の場合はフレームサイズ1280×720、30FPSに適したメモリ確保がされるようです。

packetization-mode=1というのは、WebRTCのパケット化の方法を指定します。歴史的経緯でデフォルト値0のモードが生き残っていますが、今ではほとんど使われていません。送受信側でこのモードに不整合があると、デコードできないことがあります。

BaselineプロファイルとMainプロファイルの大きな違いは、Bフレームを許可するか否かです。Bフレームを使用するとビットレートは抑えられますが、エンコードの計算量が増えます。

MainプロファイルとHighプロファイルの違いは、HD高解像度向けにエンコード計算量を減らす機能を有効にするかどうかです。

プロファイルの違いによる画質比較

仕様書を読んでも、自身が想定している映像がきれいに配信できるかどうかわからないので、H.264プロファイルの違いによる画質比較ツールを作成しました。画質の違いがわかりやすいように、映像を縮小表示せず、動画の中心部分320×180だけをクロッピングして表示しています。

こちらのページを別ウインドウで開き、「Start」ボタンを押すと、ブラウザが対応しているH.264プロファイル4通り(Baseline, Constrained Baseline, Main, High)のローカル送受信を行います。画面下部には、統計情報が3秒に1度更新されて表示されます。

上段がソース映像。下段は左から、Baseline、Constrained Baseline、Main、High

動きの激しい複雑な映像を使用しても、目視では画質の違いは見つけられませんが、統計情報からはわかることがあります。

特に注目するのはframeWidth、bytesReceivedです。フレームサイズの変わりやすさがプロファイルによって違うように見えます。平均ビットレートはフレームサイズごとに決まっているようです。

Constrained Baselineプロファイルだけ明らかに挙動が違います。フレームレートが最高解像度に上がるまでに時間がかかっていることがわかりました。

コード解説

画質比較ツールのコードの主要箇所を解説します。(こちらをクリックするとツールがソースコード付きで表示されます。右側に表示されるJavaScriptのコードについて解説します)

コーデックの変更は、本サンプル68~71行目の処理です。

送信側のPeerConnectionオブジェクトのtransceiverに、次に示すコーデックオブジェクトを指定します。

    const transceiver = pc
      .getTransceivers()
      .find((t) => t.sender && t.sender.track === stream.getVideoTracks()[0]);
    transceiver.setCodecPreferences([codec]);

ドロップダウンから選択したコーデックオブジェクトの取得は、本サンプル39~44行目の処理です。40行目の処理でブラウザが対応しているすべてのコーデックオブジェクトが取得できます。

    const [mimeType, sdpFmtpLine] = preferredCodec.value.split(" ");
    const { codecs } = RTCRtpSender.getCapabilities("video");
    selectedCodec = codecs.find(
      (c) => c.mimeType === mimeType && c.sdpFmtpLine === sdpFmtpLine
    );
    return selectedCodec;

まとめ

ブラウザのH.264のプロファイル設定を変更する方法と、その画質比較方法をご紹介しました。カメラ映像の場合は、目視でわかるほどの差は出にくい、という結論になりますが、Constrained Baselineを使用する場合は注意が必要です。本記事でご紹介したサンプルでは、コーデックを変更してH.264、VP8、VP9、AV1の比較も可能です。コーデックの違いについては、別の記事にて取り上げたいと思います。

有料サービスのご紹介

WebRTCを利用した会員制ライブ配信サービスを短期間で導入したい方、大規模配信のためのサーバ構築・インフラ運用を専門家に任せたい方は「ImageFlux Live Streaming」をご検討下さい。ポスプロ会社様向けに動画編集のコラボレーションシステムとして利用された実績があります。WebRTC SFUという技術を用いて、配信映像をサーバに中継させる仕組みです。1対多の会員制映像配信に特に強みがあり、初期の利用コストが低価格に抑えられます。