H.265/HEVC Web ライブ ブロードキャスト プレーヤーの開発

H5 ビデオ プレーヤー コアの開発は、フロントエンド エンジニアがめったに関与しない分野です。私はたまたま仕事中にそれを調査し、興味のある学生に共有しました。簡単に言うと、プレーヤー コアの機能はビデオ タグに似ており、ビデオ リソースのカプセル化解除、デコード、再生を担当します。

ビデオプレーヤーのアーキテクチャ

典型的な最新のプレーヤーは、UI、マルチメディア エンジン、デコーダーの 3 つの部分に分割できます [1]。この記事で説明するビデオ プレーヤーのコアは、図 1 の下の 2 つの層で主な作業を行い、主にデコーダ、レンダラー、ネットワーク管理エンジン、メディア管理エンジンが含まれます。

関連背景技術

ライブ ブロードキャストは、現在最も一般的な情報発信や交流の方法ですが、録画されたオンデマンド ビデオとは異なり、プレーヤーはストリーミング ビデオ データをリアルタイムで取得して再生する必要があります。ライブ ブロードキャストを実現するには、プレーヤー コアでいくつかの HTML5 テクノロジを使用する必要があります。以下に示すように:

このうち、Audio MSE Con​​troller は Media Source Extension API に依存し、Stream Loader は Stream 標準に依存し、H.265 Decoder は WebAssembly テクノロジーに依存し、各モジュールは異なるスレッドに分割され、Web Workers に依存します。具体的には:

Media Source Extensions ( MSEと呼ばれる)は、プラグイン不要の Web ベースのストリーミング メディアを実装する機能を提供します。MSE API (主にメディア ソース、ソース バッファなど) を使用すると、JavaScript を通じてメディア ストリームを作成し、HTMLMediaElement 要素 (ビデオ要素やオーディオ要素など) を通じて再生できます。IE11 (win8+) およびその他の最新のブラウザーでサポートされています。

Streams [2] 標準は、ストリーム データ (具体的には ReadableStream、WritableStream、TransformStream など) を作成および操作するための API セットを提供します。これにより、すべてのデータをメモリにキャッシュして均一に処理するのではなく、データを段階的に処理できるようになります。Fetch API[3] を使用してビデオ データを取得できます。返される本体は ReadableStream オブジェクトです。このオブジェクトはデータ ソースを表し、まだ読み取られていない基になるデータ ソースを記録するキューを内部的に維持します。内部キュー内のチャンク データは、ReadableStream の getReader() インターフェイスを通じて読み取ることができます。

Web Workers [4] を使用すると、シングルスレッドの JavaScript にマルチスレッド プログラミング機能を持たせることができ、ビデオ プレーヤー コアが逆多重化、デコード、レンダリング、UI 操作の監視などのタスクを異なるスレッドに分離して、計算量の多いタスクを並列処理できるようになります。インターフェース表示など。ワーカー間の通信は MessageChannel を通じて行われます。IE10+ およびその他の最新のブラウザーでサポートされています。

WebAssembly [5] は Web 上のバイトコード技術であり、コンパイル対象として汎用的でコンパクトかつ高速にロードできるバイナリ形式を定義しており、一般的なハードウェアのパフォーマンスを活用してネイティブ アプリケーションに近い速度で実行できます。ブラウザーでの H.265 でエンコードされたビデオのソフトウェア デコードは、パフォーマンスに非常に厳しいタスクであり、JavaScript などのスクリプト言語ではこのタスクを実行できません。したがって、C/C++ 言語で書かれた高性能デコード ライブラリをバイトコードにコンパイルし、JavaScript 呼び出しを通じて実行できます。このテクノロジーは現在、Chrome、Firefox、Safari、Edge ブラウザー (Chrome57 以降、Firefox 52 以降) の新しいバージョンで利用できます。

H.265/HEVC エンコードおよびハード デコード プラットフォームのサポート

4K ビデオの人気が高まるにつれ、Apple の最新のオペレーティング システム バージョン (Mac Hight Sierra および iOS 11) は、新しい業界標準 HEVC (High Efficiency Videocoding、別名 H.265) の導入をもたらしました[6]。現在の H.264 ビデオ圧縮規格と比較して、ビデオ圧縮率を最大 40% 高めることができます。H.265 を使用すると、同じビデオ品質を維持しながらビデオ ストリーミング効果が向上します。同じビットレートであれば、品質はほぼ 2 倍向上します。下の画像は、同じビット レートと同じ解像度 (400kpbs 1080p) の 2 つの画像です。左側は H.265 エンコードを使用し、右側は H.264 エンコードを使用しています。

一般に、OS はハードウェア (グラフィック カード) を使用して H.265 でエンコードされたビデオをデコードしますが、ハード デコードの消費電力が低く、デコード速度が速いという利点があります。ただし、現在、ブラウザーでの H.265 エンコードのハードウェア デコード サポートは普及していません。テスト後は、カスタマイズされた Chromium[7] および Edge 14 ブラウザーでのみサポートされます。このページを使用して、H.265 でエンコードされたオンデマンド ビデオのブラウザー再生をテストできます。

ハードウェア デコードには、ユーザーのグラフィック カードが H.265 コーデックをサポートする必要があることに注意してください。現在、H.265 デコードをサポートするグラフィック カードは主に次のとおりです: Intel HD Graphic 4400/4600/5000/5500/6000/620、Iris Graphics 5100 /5200/6100、NVIDIA GeForce GTX 745、GTX 750、GTX 750 Ti、GTX 850M、GTX 860M、GeForce 830M、840M、GeForce GTX 970、GTX 980、GTX 970M、GTX 980M、GeForce GTX TITAN X、GeForce GTX 980ティ、GeForce GTX 750 SE、GTX 950、GTX 960、GeForce GTX 1070、GTX 1080、GeForce GTX 1060、NVIDIA TITAN XP、GeForce GTX 1050、GTX 1050 Ti

ライブ ブロードキャスト シナリオでは、再生のためにビデオ ストリームを MSE インターフェイス経由で HTMLMediaElement に送信する必要があるため、MediaSource インターフェイスも H.265 メディア タイプ文字列をサポートする必要があります。現在、H.265 でエンコードされたストリーミング メディアの再生をサポートしていると主張しているのは Edge ブラウザだけです。測定された MediaSource.isTypeSupported('video/mp4; codecs="hvc1.xxx"') は確かに true を返しますが、実際には H.265 でエンコードされたストリーミング メディアを再生します。動画データを mp4 にカプセル化すると、画面が真っ暗になり、画像が表示されなくなります。さらに、HEVC エンコーディングのサポートを宣伝する他の 2 つの Web プレーヤー、Radiant Media Player [9] と Bitmovin Video Player [10] もテストしたところ、同じ現象が見つかりました。

ウェブサイドのソフトウェアソリューション

現在、ライブ ブロードキャスト用の Web 側のハードウェア ソリューションはブラウザのサポートに限定されているため、ソフトウェア デコードが唯一の選択肢となっています。H.265 ビデオのデコードは、高いパフォーマンス要件を伴う CPU 集中型のタスクであるため、Web サイド スクリプト言語で実装されたデコーダのパフォーマンスでは要件を満たすことが困難です。私たちのチームは以前、Flash ベースの H.265 デコード ソリューションを試しました。これは、C 言語で書かれたデコーダを FlasCC[11] コンパイラを通じて swc ライブラリにコンパイルし、アクション スクリプトを使用して Flash 内の swc ライブラリを呼び出すというものでした。プレーヤー。テスト結果は、1080p 高解像度ビデオは 1 秒あたり約 10 フレームでしかデコードおよびレンダリングできず、アプリケーションの要件を満たすことができないことを示しています。

もう 1 つのソリューションは HTML5 に基づいており、WebAssembly テクノロジを使用して Kingsoft Cloud の自社開発高性能デコーダを wasm ライブラリにコンパイルします。wasm ファイルはバイナリ形式で存在し、プラットフォームに依存しない仮想命令 (アセンブリ命令と同様) が含まれています。WebAssembly テクノロジは現在、4 つの主要なブラウザの新しいバージョンでサポートされています。このテクノロジに基づくプレーヤー コアの実装を次の図に示します (図内の点線はオブジェクト参照関係を表し、実装はデータ転送を表します)。


この実装には、トランスマックス/多重化ワーカー (TransmuxingWorker)、デコード ワーカー (H265decodingWorker)、色空間変換ワーカー (RGBConvertingWorker)、およびレンダリングと再生制御を担当するメイン スレッドの 4 つのスレッドが含まれています。TransmuxingWorker では、ストリーミング メディア データは DownloadController を通じてダウンロードされ (Safari、Chrome、および Edge ブラウザではダウンロードを実装するために Stream API を使用しますが、Firefox ではデータは XMLHttpRequest に基づいてダウンロードできます)、さまざまな形式に従って逆多重化されます。デマルチプレクサーはオーディオとビデオのデータを分離します (http-flv ストリームの逆多重化方法については flv.js 関連のコードを参照してください。HLS ストリームの逆多重化については hls.js 関連のコード [12] を参照してください)。 。次に、オーディオ データは Fragmented MP4 形式 [(メディア タイプは mp4a) に再パッケージ化されます。最後に、mp4a オーディオ データはメイン スレッドに戻され、AudioMSEController に渡され、AudioMSEController は MSE インターフェイスを介してオーディオ タグにオーディオ データを渡し、再生します。

一方、カプセル化解除されたビデオ データは、MessageChannel を通じてデコード ワーカー (H265decodingWorker) に送信され、H265Decoder のデータ キューに入れられてデコードされます。H265Decoder は、基礎となるデコーダーを呼び出して WebAssembly テクノロジーに基づいてデコードし、YUV[14] データを出力します。次に、RGBConvertingWorker の RGBConverter に送信され、YUV から RGB 色空間に変換されます。最後に、RGB データ フレームがメイン スレッドのオーディオおよびビデオ同期レンダラー (AVSyncRender) に送信され、レンダリングされるキューに保存されます。

オーディオとビデオの同期レンダリングでは、ビデオをオーディオに同期する戦略が採用されています。つまり、オーディオは通常どおり再生され、レンダリングされるビデオ キューの先頭にあるビデオ フレームが常にチェックされ、その表示タイムスタンプ (pts) がチェックされます。ビデオ フレームがオーディオの現在のタイムスタンプ (currentTime) と比較され、ビデオ タイムスタンプがオーディオ タイムスタンプより小さい場合、レンダリング対象の現在のキューの先頭にあるビデオ フレームがレンダリングされます。それ以外の場合は、ビデオ フレームをレンダリングする前に、上記の条件が満たされるまで待ちます。描画対象のキューが空の場合は、一定時間(例えば10ms)待ってから上記の動作を再開してください。ここでの画像レンダリングはキャンバス上でレンダリングされます。現在、主流のブラウザでのキャンバス レンダリングは GPU ハードウェアで高速化されています。テスト後のレンダリング フレーム レートは、このシーンでの WebGL [15] レンダリングよりもさらに優れています。さらに、パフォーマンス上の理由から、ワーカー間でデータを通信および転送する場合は、ゼロコピー方式 (転送可能オブジェクト [16] とも呼ばれる) を使用する必要があります。

この記事では、Web 側のライブ ブロードキャスト プレーヤーに関連するバックグラウンド テクノロジと、H.265 コーデックの Web 側のソフトおよびハード ソリューションの探求を紹介し、ソフト ソリューションの実装について説明します。

おすすめ

転載: blog.csdn.net/xiehuanbin/article/details/133311036