Windows 8.1 での Miracast エンコード チャンクと統計のレポート

Windows 10 (WDDM 2.0) 以降、オペレーティング システムには、任意の GPU で動作できる組み込みの Miracast スタックが付属しています。 Microsoft Miracast スタックと、Windows 10 以降の Miracast ディスプレイをサポートするためのドライバーとハードウェアの要件については、次のドキュメントを参照してください。

ドライバー開発者は、カスタム Miracast スタックを実装する必要がなくなりました。 Microsoft は、将来のバージョンの Windows でカスタム Miracast スタックのサポートを削除する可能性があります。

Windows 8.1 では、ディスプレイ ハードウェアは、Miracast ワイヤレス ディスプレイ リンク経由で送信された各ビデオ フレームを、フレームを複数の部分に分割するか、チャンクをエンコードして処理できます。 各チャンクには、フレーム番号とフレーム パーツ (またはスライス) 番号から生成される一意のチャンク ID があります。 同じデスクトップ フレームの更新に関連する各チャンクには、同じフレーム番号を割り当てる必要があります。

チャンク処理のレポート

ドライバーは、Miracast ワイヤレス リンク経由で送信されるフレームのエンコードを、複数の処理ステップ (エンコードから色変換を分離するなど) あるいは 1 つのステップで行うことができます。 各処理ステップには、フレーム内の一意のフレーム部品番号を割り当てる必要があります。

Miracast ユーザー モード ドライバーまたはディスプレイ ミニポート ドライバーのどちらかが、次のことが行われるたびにオペレーティング システムに通知する必要があります。

  • ハードウェアが、フレームの処理ステップを完了した。
  • フレームの各部分がネットワークに送信される直前の状態である。

特定のレポート済み処理ステップの時刻は、イベントがオペレーティング システムにレポートされた時刻と見なされるため、ステージをできるだけ早くレポートすることが重要です。

オペレーティング システムは、Windows イベント トレーシング (ETW) カーネル レベルのトレース機能を使用して、これらのイベントのログを記録する以外のアクションを実行しません。 この情報は、パフォーマンス問題を測定し調査するために重要です。

ドライバーは、次のいずれかの方法を使用して通知を提供できます。

  • Miracast ユーザー モード ドライバーは、ReportStatistic コールバック関数を呼び出して、MIRACAST_STATISTIC_TYPE_CHUNK_PROCESSING_COMPLETE 型またはMIRACAST_STATISTIC_TYPE_CHUNK_SENT の詳細をレポートして、チャンクが伝送に向けてネットワーク スタックに送信される寸前であることを示します。
  • ディスプレイ ミニポート ドライバーは、DXGK_INTERRUPT_MICACAST_CHUNK_PROCESSING_COMPLETE 割り込み型に関するチャンク処理の詳細をレポートしますが、このレポートは割り込み時にのみ行うことができます。 チャンク情報のログ記録に加えて、チャンク パケットが作成されキューに入れられて、Miracast ユーザー モード ドライバーが GetNextChunkData コールバック関数を呼び出して取得できるようにします。
  • ディスプレイ ミニポート ドライバーは、DxgkCbReportChunkInfo コールバック関数を任意の IRQL レベルで呼び出します。 この関数は、チャンク情報のみのログを記録し、チャンク パケットをキューに入れることはしません。

デスクトップ イメージが更新されていないが、ドライバーが画質を向上させるためにデスクトップ イメージをもう一度エンコードする必要がある場合は、同じフレーム番号と部品番号を使用する必要があります。 パフォーマンス ツールは、同じフレーム番号と部品番号に対して 2 番目のエンコード完了イベントをトリガーして、同じフレームの 2 番目のエンコードが実行されたことを示します。

各フレームの最後のスライスでは、フレーム部品番号が 0 である必要があります。これは、フレームの最後のスライスをパフォーマンス ツールに示します。

プライマリ サーフェスの正しい同期を確保するために、ピクセル パイプラインがエンコードを実行する場合は、エンコードがプライマリ サーフェスへのアクセスを完了する前に、VSync 間隔で要求されたフリップ操作をレポートすべきではありません。 この動作により、エンコード エンジンがまだ読み取っている間にプレゼンターがプライマリ サーフェスにレンダリングしてしまう処理が防止されます。

Miracast ユーザー モード ドライバーは、フレームを処理するいくつかのステージごとに、次の件についてオペレーティング システムに通知する必要があります。

  • 開始フレーム、チャンク タイプ MIRACAST_CHUNK_TYPE_FRAME_START

    オペレーティング システムがドライバーに新しいデスクトップ フレームの表示を求めるポイントです。 技術的には Miracast ユーザー モード ドライバーはこのステージをレポートできますが、新しいフレームの処理の開始には常にディスプレイ ミニポート ドライバーが関与するため、そのドライバー側からレポートする必要があります。

  • 色変換完了、チャンク タイプ MIRACAST_CHUNK_TYPE_COLOR_CONVERT_COMPLETE

    一部のソリューションには、個別の色変換とエンコード ステージがあります。 このようなソリューションでは、色変換完了処理イベントはできるだけ早くレポートする必要があり、ドライバーは DXGK_MIRACAST_CHUNK_INFO.ProcessingTime メンバーを使用して、ハードウェアがその操作を実行するのに要した時間をレポートする必要があります。 フレーム全体がスライス単位ではなく一度にまとめて色変換される場合、部品番号は 0 にする必要があります。

  • エンコード完了、チャンク タイプ MIRACAST_CHUNK_TYPE_ENCODE_COMPLETE

    H.264 エンコードが完了したことを示します。 DXGK_MIRACAST_CHUNK_INFO 構造体の ProcessingTime メンバーと EncodeRate メンバーを完了する必要があります。

  • フレーム送信、MIRACAST_STATISTIC_TYPE_CHUNK_SENT を使用した ReportStatistic の呼び出し

    Miracast ユーザー モード ドライバーが、このフレーム/部品番号のデータ パケットを伝送のために Networking API に送信しようとしていることを示します。 このフレーム/部品のデータが、Networking API への複数の呼び出しを使用して送信される場合は、最初のパケットが送信される直前にのみログを記録する必要があります。 呼び出しは、Networking API を呼び出す直前に行う必要があります。 Networking API が呼び出しをブロックする場合、グラフィックス スタック内のフレーム処理に対してブロックされた時間をカウントされては困るので、このタイミングは重要です。

  • ドロップ フレーム、チャンクの種類 MIRACAST_CHUNK_TYPE_FRAME_DROPPED

    任意のタイミングで、ドライバーがフレーム/パーツの処理を完了せず、シンクに送信しないことを決定した場合は、ドライバーはドロップ フレームをレポートする必要があります。 この状況では、フレームがドロップされたと見なされるのは、ドライバーが実際に MIRACAST_CHUNK_TYPE_FRAME_START のログを記録して、処理を開始した場合のみです。 ドライバーは、処理なしでこのフレームをスキップすることを計算する場合は、MIRACAST_CHUNK_TYPE_FRAME_START のログを記録しないで MIRACAST_CHUNK_TYPE_FRAME_DROPPED のログを記録することができます。

  • ドライバーで定義されたチャンク タイプ MIRACAST_CHUNK_TYPE_ENCODE_DRIVER_DEFINED_1 または _2

    これらのチャンク タイプは、シナリオのパフォーマンスを理解するのに役立ちます。 次に例をいくつか示します。

    • ドライバーは、これらのタイプを使用して、このフレームのために I フレームが作成されたことを示します。
    • ドライバーは、フレームの最後のスライスが、エンコードされたフレームの合計サイズを含んでいる Networking API に送信された後、別のパケットのログを記録します。

フレーム色変換の例

次の例では、フレーム色の変換方法と、ディスプレイ ミニポート ドライバーが色変換の完了をレポートする方法を示します。

MIRACAST_CHUNK_INFO 構造体のメンバーへのテーブル参照は次のとおりです。

  • ChunkType は、MIRACAST_CHUNK_TYPE_XXX 値です。

  • FrameNumberPartNumberChunkId union のメンバーです。

  • ProcessingTime はマイクロ秒単位の時刻です。

  • EncodeRate はキロビット/秒です。

MIRACAST_STATISTIC_TYPE_CHUNK_SENT は、ReportStatistic の呼び出しが関係する処理ステージで使用されます。

スライスを使用しない単一フレームのレポート

処理ステージ ChunkType FrameNumber PartNumber ProcessingTime EncodeRate
フレーム処理を開始 FRAME_START 101 0 0 0
色変換が完了 COLOR_CONVERT_COMPLETE 101 0 950 0
エンコードが完了 ENCODE_COMPLETE 101 0 1042 15000
データをネットワーク ReportStatistic 呼び出しに送信する呼び出しの直前 該当なし 101 (ChunkSent.ChunkId.FrameNumber の値) 0 (ChunkSent.ChunkId.PartNumber の値) 該当なし 該当なし

スライスを使用して処理した単一フレームのレポート

処理ステージ ChunkType FrameNumber PartNumber ProcessingTime EncodeRate
フレーム処理を開始 FRAME_START 101 0 0 0
色変換が完了 COLOR_CONVERT_COMPLETE 101 0 950 0
スライス 1 のエンコードが完了 ENCODE_COMPLETE 101 1 1042 15000
スライス 2 のエンコードが完了 ENCODE_COMPLETE 101 0 400 15000
スライス 1 のデータをネットワーク ReportStatistic 呼び出しに送信する呼び出しの直前 該当なし 101 (スライス 1 の ChunkSent.ChunkId.FrameNumber の値) 1 (スライス 1 の ChunkSent.ChunkId.PartNumber の値) 該当なし 該当なし
スライス 2 のデータをネットワーク ReportStatistic 呼び出しに送信する呼び出しの直前 該当なし 101 (スライス 2 の ChunkSent.ChunkId.FrameNumber の値) 0 (スライス 2 の ChunkSent.ChunkId.FrameNumber の値) 該当なし 該当なし

スライスを使用しないで処理した後に再エンコードした元のフレームのレポート

処理ステージ ChunkType FrameNumber PartNumber ProcessingTime EncodeRate
フレーム処理を開始 FRAME_START 101 0 0 0
色変換が完了 COLOR_CONVERT_COMPLETE 101 0 950 0
エンコードが完了 ENCODE_COMPLETE 101 0 1042 15000
元のフレームのデータをネットワーク ReportStatistic 呼び出しに送信する呼び出しの直前 該当なし 101 (ChunkSent.ChunkId.FrameNumber の値) 0 (ChunkSent.ChunkId.PartNumber の値) 該当なし 該当なし
再エンコードが完了 ENCODE_COMPLETE 101 0 500 15000
再エンコードされたフレームのデータをネットワーク ReportStatistic に送信する呼び出しの直前 該当なし 101 (ChunkSent.ChunkId.FrameNumber の値) 0 (ChunkSent.ChunkId.PartNumber の値) 該当なし 該当なし

プロトコル イベントのレポート

Miracast ユーザー モード ドライバーが、 MIRACAST_STATISTIC_DATA.StatisticTypeMIRACAST_STATISTIC_TYPE_EVENT に設定された ReportStatistic 関数を呼び出して、プロトコル イベントをレポートすると、オペレーティング システムはイベントのログを記録しますが、他の操作は実行しません。 これらのイベントは、診断とパフォーマンスの調査に重要です。

MIRACAST_PROTOCOL_EVENT 列挙体には、レポート可能なプロトコル イベントの種類が含まれています。

プロトコル エラーのレポート

Miracast 接続セッションの進行中に、Miracast ユーザー モード ドライバーがエラーを検知した場合は、MiracastStatus パラメーターで適切な MIRACAST_STATUS エラー状態情報を使用して、ReportSessionStatus コールバック関数を呼び出す必要があります。 エラーがレポートされると、オペレーティング セッションは常にセッションを破棄します。

オペレーティング システムは診断の ReportSessionStatus Status パラメーターをログに記録するだけで、その値に基づいてアクションを実行しませんが、ドライバーでは、このパラメーターを使用して、エラーのさまざまな原因を区別する必要があります。