次の方法で共有


動的なフォーマット変更の処理

DirectShow のビデオ レンダラは、効率的に描画できるビデオ フォーマットしか受け入れない。たとえば、ビデオ レンダラ フィルタは、現在のディスプレイ デバイス モードに一致する RGB フォーマット (たとえば、ディスプレイが 16 ビット色に設定されている場合は RGB565) だけを受け入れる。また、最後の手段として、ビデオ レンダラは、ほとんどのディスプレイ カードで効率的な描画が可能である 8 ビットのパレット化されたフォーマットを受け入れる。Microsoft® DirectDraw® をロードした場合、レンダラは DirectDraw サーフェイスに書き込んだりディスプレイ ハードウェアから直接描画できるものに切り替えるように後でソース フィルタに要求することがある。場合によっては、ビデオの再生中にレンダラのアップストリーム フィルタがビデオ フォーマットを変更しようとすることもある。このような操作は、ビデオ ストリームがパレットの変更を行ったときによく発生する。動的なフォーマット変更を開始するのは、ほとんどの場合ビデオ デコンプレッサである。

フォーマットを動的に変更しようとするアップストリーム フィルタは、レンダラの入力ピンで必ず IPin::QueryAccept メソッドを呼び出さなければならない。ビデオ レンダラでは、どのような種類の動的フォーマット変更をサポートするかについて、ある程度自由になる。少なくともレンダラはアップストリーム フィルタによるパレットの変更を許可しなければならない。アップストリーム フィルタはメディア タイプを変更する場合、新しいフォーマットで配送された最初のサンプルにメディア タイプをアタッチする。レンダラがレンダリング用にサンプルをキューに入れている場合、タイプを変更してサンプルをレンダリングするまで、フォーマットは変更しないこと。

ビデオ レンダラはデコーダからのフォーマット変更も要求できる。たとえば、biHeight が負の値である DirectDraw 互換フォーマットをデコーダに求めることができる。レンダラがポーズするときは、アップストリーム ピンの QueryAccept を呼び出して、デコーダが提供できるフォーマットを調べる。しかし、デコーダは受け入れ可能なすべてのタイプを列挙するとは限らないため、デコーダが公表しないタイプもレンダラは提供すること。

デコーダが要求されたフォーマットに切り替え可能な場合は、QueryAccept から S_OK を返す。次に、レンダラはアップストリーム アロケータの次のメディア サンプルに新しいメディア タイプをアタッチする。それには、次のサンプルにメディア タイプをアタッチするプライベート メソッドを実装するカスタム アロケータをレンダラが提供する必要がある。(このプライベート メソッド内で、タイプを設定する IMediaSample::SetMediaType を呼び出す。)

レンダラの入力ピンは IMemInputPin::GetAllocator メソッドでレンダラのカスタム アロケータを返す必要がある。アップストリーム フィルタがレンダラのアロケータを使わない場合は失敗するように、IMemInputPin::NotifyAllocator をオーバーライドすること。

一部のデコーダでは、YUV タイプで biHeight を正の数に設定すると、デコーダはイメージを上下逆に描画する。(これは不正な動作であり、デコーダのバグと見なす必要がある。)

フォーマットの変更を検出するごとに、ビデオ レンダラは EC_DISPLAY_CHANGED 通知を送信しなければならない。ほとんどのビデオ レンダラは接続中にフォーマットを選択して、そのフォーマットが GDI を介して効率的に描画されるようにする。ユーザーがコンピュータを再起動せずに現在のディスプレイ モードを変更した場合、レンダラはそれ自体のイメージ フォーマット接続が不良であると判断してこの通知を送信しなければならない。第 1 パラメータは、再接続が必要なピンとする。フィルタ グラフ マネージャは、フィルタ グラフを停止してピンの再接続が行われるように準備する。それに続く再接続の間、レンダラはより適切なフォーマットを受け入れることができる。

ストリーム内でパレットの変更を検出するごとに、ビデオ レンダラは EC_PALETTE_CHANGED 通知をフィルタ グラフ マネージャに送信しなければならない。DirectShow ビデオ レンダラは、パレットが動的に変更されたかどうかを検出する。ビデオ レンダラは、送信された EC_PALETTE_CHANGED 通知をフィルタで除外するほかに、必要なパレットの作成、インストール、削除処理の量を減らす目的で、このような動作を行う。

最後に、ビデオ レンダラはビデオのサイズが変更されたことを検出することがある。この場合、ビデオ レンダラは EC_VIDEO_SIZE_CHANGED 通知を送信しなければならない。アプリケーションはこの通知を使って複合ドキュメント内の空間を調整できる。ビデオの実際のディメンジョンは、IBasicVideo コントロール インターフェイスを使って取得できる。DirectShow レンダラは、これらのイベントを送信する前に、ビデオのサイズが変更されたかどうかを検出する。