私はデール・カーティスです Chromium メディア再生のエンジニアリングリードです私のチームは、MSE や WebCodecs などの動画再生用のウェブ向け API と、音声と動画のデマルチューシング、デコード、レンダリングに関連するプラットフォーム固有の内部を担当しています。
この記事では、Chromium の動画レンダリング アーキテクチャについて説明します。 拡張性に関する詳細は Chromium 固有のものである可能性がありますが、ここで説明するコンセプトと設計のほとんどは、他のレンダリング エンジンやネイティブの再生アプリにも適用されます。
Chromium の再生アーキテクチャは、ここ数年で大きく変化しました。 このシリーズの最初の投稿で述べた成功のピラミッドという考え方から始めたわけではありませんが、最終的には信頼性、パフォーマンス、拡張性という同様のステップをたどりました。
当初、動画のレンダリングは非常に簡単でした。for ループで、どのソフトウェアがデコードした動画フレームをコンポジタに送信するかを選択するだけです。ここ数年は十分に信頼性が確保されていましたが、ウェブが複雑になるにつれ、パフォーマンスと効率性を高める必要に迫られ、アーキテクチャが変更されていました。多くの改善では、OS 固有のプリミティブが必要でした。そのため、Google のアーキテクチャを拡張して、Chromium のすべてのプラットフォームに対応できるようにする必要がありました。
動画レンダリングは、配信する内容の選択とその情報の効率的な配信の 2 つのステップに分けられます。読みやすくするために 効率的な配信について説明します
用語とレイアウト
この記事ではレンダリングに焦点を当てているので パイプラインの非多重化とデコードの側面についてのみ簡単に触れます
今日のセキュリティ意識の高い世界において、デコードと分離にはかなりの注意が必要です。バイナリ パーサーは豊富なターゲット環境であり、メディアの再生ではバイナリ解析が多用されます。そのため、メディア パーサーのセキュリティ問題はごく一般的なものです。
Chromium では、多層防御を実践し、ユーザーが直面するセキュリティ問題のリスクを低減しています。実際には、これは、多重化とソフトウェア デコードは常に低権限プロセスで行われるのに対し、ハードウェア デコードはシステムの GPU と通信するのに十分な権限のみを持つプロセスで行われることを意味します。
Chromium のプロセス間通信メカニズムは Mojo と呼ばれます。この記事ではプロセス間の抽象化レイヤとして Mojo の詳細については触れませんが、Mojo は Chromium の拡張可能なメディア パイプラインの基礎となっています。再生パイプラインのチュートリアルを進める際は、この点に注意することが重要です。これは、メディアの受信、demux、デコード、最終的にの表示に相互作用するクロスプロセス コンポーネントの複雑なオーケストレーションを通知するためです。
多数のビット
今日の動画レンダリング パイプラインを理解するには、動画が特別な理由である帯域幅に関する知識が必要です。3,840x2,160(4K)解像度を 60 フレーム/秒で再生する場合、9 ~ 12 ギガビット/秒のメモリ帯域幅が使用されます。最新のシステムのピーク帯域幅は数百 Gbit/秒ですが、動画再生は依然としてかなりの部分を占めています。GPU と CPU メモリ間のコピーやトリップが原因で、帯域幅の合計が簡単に倍増することがあります。
効率性を考慮した最新の動画再生エンジンの目標は、デコーダと最終的なレンダリング ステップとの間の帯域幅を最小限に抑えることです。このため、動画レンダリングは Chromium のメイン レンダリング パイプラインから主に分離されています。 具体的には、メインのレンダリング パイプラインから見ると、動画は不透明度を持つ固定サイズの穴です。Chromium では、サーフェスと呼ばれるコンセプトを使用してこれを実現しています。サーフェスでは、各動画が Viz と直接通信します。
モバイル コンピューティングの普及により、現在の世代では電力と効率が重要な焦点となっています。その結果、デコードとレンダリングがハードウェア レベルでこれまで以上に密接に結びついており、OS 自体に対しても、動画は不透明度のある穴のように見えます。多くの場合、プラットフォーム レベルのデコーダで提供されるのは不透明なバッファのみです。Chromium はこのバッファをオーバーレイの形式でプラットフォーム レベルの合成システムに渡します。
どのプラットフォームにも独自の形式のオーバーレイがあり、プラットフォームのデコード API が連携して機能します。Windows には Direct Composition と Media Foundation Transforms、macOS には CoreAnimation Layers と VideoToolbox、Android には SurfaceView と MediaCodec、Linux には VASurfaces と VA-API があります。これらのコンセプトに対する Chromium の抽象化は、それぞれ OverlayProcessor と mojo::VideoDecoder インターフェースによって処理されます。
場合によっては、これらのバッファをシステムメモリにマッピングできるため、不透明である必要はなく、アクセスされるまで帯域幅を消費することはありません。Chromium では、これらのバッファを GpuMemoryBuffers と呼んでいます。Windows では、これらは DXGI バッファ、macOS IOSurfaces、Android AHardwareBuffers、Linux DMA バッファによって支えられています。通常、動画再生ではこのアクセスは必要ありませんが、キャプチャ デバイスと結果エンコーダとの間の帯域幅を最小限に抑えるには、これらのバッファが動画キャプチャにとって重要です。
多くの場合、GPU がデコードと表示の両方を担うため、これらの(多くの場合)不透明バッファを使用することで、高帯域幅の動画データが GPU の外に出ることがなくなります。すでに説明したように、GPU 上にデータを保持することは、特に高解像度とフレームレートにおいて、効率を高めるために非常に重要です。
オーバーレイや GPU バッファなどの OS プリミティブを活用すればするほど、不必要に動画のバイトをシャッフルするために消費される帯域幅が少なくなります。デコードからレンダリングまで、すべてを 1 か所で管理することで、驚くほどの電力効率を実現できます。 たとえば、macOS で Chromium でオーバーレイが有効になっていると、全画面表示での動画再生中の消費電力が半減しました。Windows、Android、ChromeOS などの他のプラットフォームでは、全画面表示されないケースでもオーバーレイを使用できるため、ほぼすべての場所で最大 50% の節約になります。
レンダリング
最適な配信メカニズムについて説明したので 次は Chromium で配信対象が選択される仕組みについて説明します Chromium の再生スタックは「pull」ベースのアーキテクチャを採用しています。つまり、スタック内の各コンポーネントは、階層順に下位コンポーネントからの入力をリクエストします。スタックの一番上は音声フレームと動画フレームのレンダリングで、その下はデコードで、次いで非多重化、最後に I/O です。レンダリングされた各音声フレームは、プレゼンテーション間隔と組み合わせた場合に、レンダリングする動画フレームの選択に使用されるクロックを進めます。
各表示間隔(ディスプレイの更新)ごとに、動画レンダラは、前述の SurfaceLayer にアタッチされた CompositorFrameSink によって動画フレームの提供を求められます。フレームレートが表示レートよりも低いコンテンツの場合、つまり同じフレームが複数回表示されます。一方、フレームレートが表示レートより大きい場合、一部のフレームは表示されません。
視聴者を満足させる方法で音声と動画を同期する方法は他にもあります。 Chromium で最適な動画の滑らかさを実現する方法については、Project Butter をご覧ください。動画レンダリングを、各フレームの表示回数を表す理想的なシーケンスに分割する方法について説明します。たとえば、「表示間隔ごとに 1 フレーム([1]、60 Hz で 60 fps)」、「2 間隔ごとに 1 フレーム([2], 60 Hz で 30 fps」)、「[2:3:2:3:2] のようなより複雑なパターン」(60 Hz で 25 fps の個別のフレーム)のように表示し、複数の異なるフレームを表示します。動画レンダラがこの理想的なパターンに近いほど、ユーザーが再生がスムーズだと感じる可能性が高くなります。
ほとんどの Chromium プラットフォームはフレーム単位でレンダリングしていますが、すべてそうであるとは限りません。Google の拡張可能なアーキテクチャはバッチ レンダリングにも対応しています。 バッチ レンダリングは、複数のフレームについて事前に OS レベルのコンポジタに通知され、アプリが提供するタイミング スケジュールでフレームの解放を処理する効率的な手法です。
未来は今?
Google は、Chromium が OS プリミティブを活用して最高水準の再生エクスペリエンスを提供する方法に重点を置いてきました。 しかし、基本的な動画再生にとどまらないウェブサイトではどうすればよいでしょうか。Chromium 自体が次世代のウェブ コンテンツの先駆者に使用しているのと同じパワフルなプリミティブを提供できるか
その答えはイエスです。 最近のウェブ プラットフォームに対する考え方の中心は拡張性です。Google は、他のブラウザやデベロッパーと協力して、WebGPU や WebCodecs などの新しいテクノロジーを開発しています。これにより、ウェブ デベロッパーは、Chromium が OS とまったく同じプリミティブを使用できるようにしています。WebGPU は GPU バッファをサポートしており、WebCodecs は前述のオーバーレイ システムおよび GPU バッファ システムと互換性のあるプラットフォームのデコードおよびエンコードのプリミティブを提供します。
ストリームの終了時
最後までお読みいただきありがとうございました。最新の再生システムについて、また Chromium が 1 日あたりの総再生時間を何億時間も支えている仕組みについてご理解いただけたことと思います。 コーデックと最新のウェブ動画について詳しくは、Sid Bala の H.264 is magic、Erica Beaves の「How Modern Video Players Work」、受賞歴のあるテクノロジーによる番組のパッキング(Cyril Concolato)をおすすめします。
1 枚は Una Kravets によるイラストです。