ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
VideoToolboxによる低遅延ビデオエンコーディング
低遅延エンコーダーをサポートすることは、ビデオApp開発プロセスの重要な側面となっています。VideoToolboxがどのように低遅延のH.264ハードウェアエンコーディングをサポートし、エンドツーエンドのレイテンシを最小化し、最適なリアルタイムコミュニケーションと高品質のビデオ再生に向けて新たなレベルのパフォーマンスを達成するかを確認します。
リソース
関連ビデオ
WWDC21
WWDC20
-
ダウンロード
♪♪ こんにちは Video Coding and the Processingチームの Peikangです 「VideoToolboxによる 低遅延ビデオエンコーディング」 へようこそ
低遅延エンコードは 多くのビデオAppにとって 非常に重要であり 特にリアルタイムのビデオ コミュニケーションAppで重要です 今回のお話では 以下をご紹介します VideoToolboxでの 新しいエンコードモードです 低遅延でエンコードを実現 するためです この新しいモードの目的は エンコーダーパイプラインを リアルタイムAppのために 最適化することです では リアルタイムビデオ Appには何が必要か?
エンドツーエンドの遅延を 最小化することが必要です 通信手段において それで お互いに話し合うことは ありませんが
相互運用性を強化する 必要があります ビデオAppを可能にする ことによって より多くのデバイスと 通信することができます エンコーダーパイプラインは 効率的でなければなりません 通話に複数の 受信者がいる場合
Appはビデオを提示する 必要があります その最高の画質で
ネットワーク障害による エラーから通信を 回復するには信頼できる メカニズムが必要です
今日お話しする 低遅延でのビデオエンコードは これらすべての側面で 最適化されます このモードでは リアルタイムAppが 新しいレベルのパフォー マンスを実現できます
このお話では 最初に 低遅延でのビデオエンコードの 概要について説明します パイプラインの低遅延化の 達成について基本的な 考えを持つことができます 次にVTCompressionSession APIの使用方法を紹介します パイプラインを構築し低遅延 モードでエンコードします 最後に 低遅延モードで 導入している 複数の機能について 説明します まず 低遅延ビデオエンコードの 概要を説明します Appleのプラットフォームで ビデオエンコードの パイプラインの簡単な図です VideoToolboxは 入力画像として CVImageBufferを取ります ビデオエンコーダーに 以下を求めます 圧縮アルゴリズムを 実行するには H.264など 生データのサイズを縮小
出力圧縮データは CMSampleBufferで ラップされます ネットワークを介して ビデオ通信用として 送信することができます 先程の図から わかるように エンドツーエンドの遅延が 影響を受けることがあります 2つの要因によって: それは処理時間と ネットワーク 送信時間です
処理時間を最小限に 抑えるために 低遅延モードではフレームの 並べ替えが不要になります ワンイン ワンアウトの 符号化パターンに従います このモードの レートコントローラは ネットワークの変更に より速い適応を 持っています ネットワークの輻輳による 遅延は 最小限に抑えられます この2つの最適化により すでに確認できます デフォルトモードと比較して 明らかにパフォーマンス向上 低遅延エンコードで 遅延を減らすことができます 720p 30fps の映像では 最大100ミリ秒の遅延です このような省力はビデオ会議 に重要です
遅延を削減することで 以下 実現することができます より効率的な符号化 パイプラインや リアルタイム通信です ビデオ会議や ライブ中継のように
また 低遅延モードは 常に使用します 加速されたハードウェア によるビデオエンコード 省電力化のために 対応しているビデオコーデッ クタイプに注意してください このモードではH.264です この機能はiOSとmacOSの 両方に搭載されています
次にVideoToolboxで 低遅延モードの使用方法に ついて説明します 最初にVTCompressionSessionの 使用を要約します そして その手順を示します 低遅延の符号化を有効に する必要があります VTCompressionSessionを 使用する場合 まず セッションを 作成します VTCompressionSessionCreate APIを使用します
ターゲットビットレートなど オプションでセッションを 設定できます VTSessionSetProperty APIを介して 設定が提供されていない 場合 エンコーダーはデフォルトで 動作します
セッションが作成され 適切に設定されると CVImageBufferを セッションに渡します VTCompressionSessionEncodeFrame を呼び出し 符号化された結果を 取得できます 出力ハンドラーから セッションの作成中に 提供されます
低遅延エンコードの有効は 圧縮セッションでは簡単です 必要な変更は セッションの作成だけです
コードスニペットが その方法を次に示します まず CFMutableDictionaryが encoderSpecification のために必要です encoderSpecificationはエンコーダーを 指定するために使用されます セッションで使用する 特定のビデオエンコーダーで encoderSpecificationの EnableLowLatencyRateControl フラグを有効にします
最後に この encoderSpecificationを VTCompressionSessionCreateに与え 圧縮セッションが 低遅延モードで 動作します
設定手順は 通常と同じです 例えば ターゲット ビットレートを設定できます AverageBitRate を使用します
低遅延モードの基本について VideoToolboxで 説明しました 次は 新機能の紹介に 移ります このモードではさらに 助けになります リアルタイムビデオAppを 開発します 今まで低遅延モードを使用し 遅延のメリットについて 説明してきました 残りのメリットは 紹介する機能に よって 達成できます
最初の機能は 新しいプロファイルです 相互運用性を 強化しました パイプラインに2つの新しい プロファイルを追加します
時間的な拡張性についても お話しします この機能はビデオ会議で 非常に役立ちます
これで きめの細かい制御が 画質上で 可能になります 最大フレーム 量子化パラメータ付きで 最後に エラー耐性を 高めます 長期参照のサポートを 追加します
新しいプロファイルの サポートについて話します プロファイルはコーディング アルゴリズムを定義します デコーダーが サポートできます 受信側と通信するために 符号化された ビットストリームは デコーダーがサポートする 特定のプロファイルに 準拠する必要があります
VideoToolboxでは プロファイルをサポート ベースライン メイン ハイ プロファイルなどです
本日2つの新しい プロファイルを追加しました 制約のあるベースライン プロファイルのCBPと 制約のあるハイ プロファイルのCHPです
CBPは主に低コストの Appに使用されます 一方 CHPは 良い圧縮率のより高度な アルゴリズムがあります デコーダーの機能を 確認する必要があります どのプロファイルを使う べきかを知ってください
CBPを要求するにはプロ ファイルレベルを設定し セッションプロパティを オートレベルに設定します
同様にプロファイルレベル を設定できます ハイオートレベルに移動して CHPを使用します
それでは 時間的な拡張性に ついて説明しましょう 時間的な拡張性を使用して 多人数のビデオ通話で 効率を高めることができます
単純な3者間で ビデオ会議のシナリオを 考えてみましょう このモデルでは レシーバー”A”は 600kbpsの低い帯域幅で レシーバー"B"は 1,000kbpsの 高い帯域幅を持っています
送信者は2セットのビット ストリームのエンコードが必要 各受信機側の ダウンリンク帯域幅を 満たすためですが これは 最適でない可能性があります
モデルは時間的な拡張性で より効率的になります 送信者がエンコードする 必要があるのは 単一のビットストリーム ですが 2つの層に 後で分割できます
このプロセスがどのように 機能するかご覧ください
これが一連の符号化された ビデオフレームです ここで各フレームは 予測参照として 前のフレームを使用します
フレームの半分を別の レイヤに引き込みます フレームのみになるように 参照を変更できます 元のレイヤの予測に 使用されます
元のレイヤは ベースレイヤと呼ばれ 新しく構築されたレイヤは 拡張レイヤと呼ばれます
拡張レイヤは フレームレートを向上させる ベースレイヤの 補助的に使用できます
レシーバー”A”ではベース レイヤフレームを送信 ベースレイヤはすでに 復号可能だからです そしてさらに重要なのは ベースレイヤが フレームの半分しか 含まれていないため 送信されるデータレートが 低くなることです
一方 レシーバー"B"は 以下を楽しむことができます 十分な帯域幅があるため よりスムーズなビデオ ベースレイヤフレームと 拡張レイヤフレームを受信
エンコードされたビデオを お見せしましょう 時間的な拡張性を使用します 2つのビデオを再生します 1つはベースレイヤからで もう一方はベースレイヤ と一緒に 拡張レイヤ付きです
ベースレイヤ自体は 正常に再生できますが 同時に 映像が なめらかでないことに 気付くかもしれません
2番目のビデオを 再生すると 違いがすぐにわかります 右の映像のフレームレート は左のものと比較して フレームレートが高いです 右はベースレイヤと 拡張レイヤが 含まれているためです
左の映像は入力フレーム レートの50%で ターゲットビットレートの 60%を使用しています この2つのビデオは エンコーダーのみが必要です 一度に1つのビット ストリームをエンコードします これにより電力効率が 大幅に向上します 多人数でビデオ会議 を行っているとき
時間的な拡張性の もう1つの利点は エラー耐性です ご覧のとおり 拡張レイヤの フレームは 予測には使用されません よって これらのフレーム への依存はありません
これは もし1つ以上の 拡張レイヤフレームが ネットワーク送信中に ドロップされても 他のフレームは 影響を受けません これによりセッション全体が より強固になります
時間的な拡張性を 有効にする方法は 非常に簡単です 新しいセッションプロパティ を作成しました BaseLayerFrameRateFraction と呼ばれる低遅延モードです このプロパティを0.5に 設定します 入力フレームの半分は ベースレイヤに 残りは 拡張レイヤへ 割り当てられます
レイヤ情報の 確認は サンプルバッファ アタッチメントからできます ベースレイヤフレームは CMSampleAttachmentKey_で IsDependedOnByOthersは trueになり それ以外はfalseになります
ターゲットビットレートの 設定オプションも レイヤごとにあります セッションプロパティの使用 を忘れないでください ターゲットビットレートを 設定し 平均ビットを構成
ターゲットビットレートを 設定後 次を設定できます 新しいBaseLayerBitRate Fractionプロパティ ターゲットビットレートの パーセンテージを制御します ベースレイヤに必要です
このプロパティが設定 されていない場合 デフォルト値の0.6が 使用されます ベースレイヤのビット レートの割合は 0.6から0.8の範囲を勧めます
最大フレーム量子化パラ メータ か最大フレームQP に移りましょう
フレームQPは画質とデータ レートの調整に使用します
高品質画像を生成するために 低フレームQPを 使用できます この場合 画像サイズは 大きくなります
一方 低品質の画像を 生成するために 高フレームQPを使用できます ただサイズは小さくなります
低遅延モードではエンコー ダーがフレームQPを調整 画像の複雑さなどの 要素を使用します 入力フレームレート ビデオモーション 最高の画像品質を 生み出すために 現在のターゲットビット レートの制約を受けます 以下頼ることをお勧めします フレームQPの調整用の エンコーダーのデフォルト の動作について
しかし場合によっては クライアントが ビデオ品質に特定要件があり 最大フレームQPを 制御します エンコーダーは使用を 許可されています
最大フレームQPを使用すると 制限より小さいフレームQPを エンコーダーは 常に選択します そのためクライアントは 画質上できめ細かい制御を 行うことができます
通常のレート制御について 言及する価値があり 指定された最大フレームQP でも機能します エンコーダーが最大フレーム QPキャップに達し しかしビットレートの予算が 不足している場合は フレームのドロップを開始 ターゲットビットレートを 維持するためです
この機能を使用する一例は 劣悪なネットワークを介した 画面コンテンツビデオを 送信することです
フレームレートを犠牲にし トレードオフを行います シャープな画面コンテンツ 画像を送信するためです 最大フレームQPを設定すると この要件を満たせます
インターフェイスを見ると 最大フレームQPを 渡すことができます 新しいセッションプロパティ MaxAllowedFrameQPを使用
最大フレームQPの値に 注意してください 標準に従って1から51の範囲 でなければなりません
最後の機能について 話しましょう 低遅延モードで 開発しましたが 長期的な参考になります
長期参照またはLTRを 使用できます エラー耐性のためです エンコーダーを示すこの図を 見てみましょう パイプラインでの 送信側クライアントと 受信側クライアントです
ビデオ通信を 想定します 劣悪なネットワークを 経由した場合 送信エラーのため フレーム損失が発生する 可能性があります
受信側クライアントが フレーム損失を検出すると セッションリセットのために リフレッシュフレームを要求
エンコーダーが要求を 受け取ると リフレッシュ用キーフレーム が通常は符号化します しかし キーフレームは大抵 かなり大きいです
キーフレームが大きいと 受信者に届くまでに 時間がかかります ネットワークの状態はすでに 悪いのでフレームが大きいと ネットワークの輻輳問題が 悪化する可能性があります
では 更新用のキーフレーム の代わりに 予測フレームを 使用できますか? 答えはイエスです フレーム確認応答が ある場合です どのように機能するかを お見せしましょう
確認応答が必要なフレーム を決定する必要があります このフレームを長期参照 またはLTRと呼びます これはエンコーダーからの 決定です 送信側クライアントが LTRフレームを送信すると 受信側クライアントから 確認応答を要求する 必要があります
LTRフレームが正常に 受信された場合 確認応答を送り返す 必要があります
送信者クライアントが 確認応答を受け取ると その情報を エンコーダーに渡し エンコーダーは どのLTRフレームが 反対側で受け取られたか 認識しています
もう一度 悪いネットワーク の状況を見てみましょう
エンコーダーが更新要求を 受け取ると この時からエンコーダーは 承認されたLTRの束を 持っていて 予測されるフレームを 符号化することが 可能です これらの承認されたLTRの1つから
この符号化されたフレームは LTR-Pと呼ばれます
キーフレームと比較すると 通常LTR-Pは符号化され フレームサイズは極小です そのため 送信が簡単です それでは LTRのAPIについて 説明しましょう フレーム確認応答に 注意してください アプリケーション層で処理 する必要があります RPSIメッセージなどの メカニズムで実行できます RTP制御プロトコルで
ここではエンコーダーと 送信側クライアントが どのように通信しているのか にのみ焦点を当てます
低遅延エンコードを 有効にすると EnableLTRセッション プロパティを設定して この機能を有効にできます
LTRフレームが 符号化されると エンコーダーは固有の フレームトークンを通知 サンプルの添付ファイル RLTR確認応答トークンです
送信者クライアントは レポートを担当します エンコーダーへの確認済み LTRフレーム AcknowledgedLTRTokens フレームプロパティを介して 複数の確認応答が来る 可能性があるため 一度に配列を使用する 必要があります フレームトークンを保存する
いつでもフレームの更新を リクエストできます ForceLTRRefresh フレームプロパティを介して エンコーダーがこの要求を 受信すると LTR-Pが符号化されます 利用可能な承認済みLTR がない場合は エンコーダーはキーフレーム を生成します
結構です これで低遅延モードの 新機能について 説明しました これらの機能を一緒に使う ことについてお話します
例えば 時間的な拡張性を 使用できます および最大フレーム 量子化パラメータを グループ画面共有Appで 使用できます 時間的な拡張性は 受信者ごとに 出力ビデオを効率的に 生成できます 最大フレームQPを下げる ことができます 画面コンテンツのUIと テキストをより鮮明にします
通信が劣悪なネットワークを 経由する場合 回復するにはリフレッシュ フレームが必要です エラーから 長期参照を使用できます 受信者が制約された プロファイルを解読できると 制約されたベースラインプロ ファイルで符号化できます 制約されたハイプロファイル でも符号化できます
オーケー トピックを説明してきました VideoToolboxに低遅延の エンコードモードを導入
VTCompressionSession APIの 使用方法について説明しました 低遅延モードで ビデオを符号化
遅延化のメリットに加えて 以下を改善してきました 要件に対応するための 多くの新機能 リアルタイムビデオApp この全ての改善により低遅延 モードがビデオAppを 素晴らしいものにすることを 期待しています ご視聴ありがとうございました 素晴らしいWWDC2021を [明るい音楽]
-
-
5:03 - VTCompressionSession creation
CFMutableDictionaryRef encoderSpecification = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); CFDictionarySetValue(encoderSpecification, kVTVideoEncoderSpecification_EnableLowLatencyRateControl, kCFBooleanTrue) VTCompressionSessionRef compressionSession; OSStatus err = VTCompressionSessionCreate(kCFAllocatorDefault, width, height, kCMVideoCodecType_H264, encoderSpecification, NULL, NULL, outputHandler, NULL, &compressionSession);
-
7:35 - New profiles
// Request CBP VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_ConstrainedBaseline_AutoLevel); // Request CHP VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_ConstrainedHigh_AutoLevel);
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。