QueryAccept (ダウンストリーム)
この機構では、出力ピンがダウンストリームの対応するピンに新しいフォーマットを提示できる。新しいフォーマットには前より大きいバッファ サイズを要求できない。出力ピンは次の処理を行う。
ダウンストリーム ピンの IPin::QueryAccept または IPinConnection::DynamicQueryAccept を呼び出し、ピンが新しいメディア タイプを受け入れ可能かどうかを確認する (図の手順 A を参照すること)。
手順 1 からの戻り値が S_OK の場合、ピンは次のサンプルにメディア タイプをアタッチする。それには、初めに IMemAllocator::GetBuffer を呼び出して、サンプルを取得する (B)。次に、IMediaSample::SetMediaType を呼び出して、そのサンプルにメディア タイプをアタッチする (C)。フィルタは、サンプルにメディア タイプをアタッチすることで、そのサンプル以降はフォーマットが変わったことを示す。
ピンはサンプルを送信する (D)。
ダウンストリーム フィルタがサンプルを受信するときは、IMediaSample::GetMediaType を呼び出して、新しいメディア タイプを取得する。
すべてのピンは QueryAccept メソッドをサポートする。しかし、このメソッドには多少あいまいなところがある。これは、戻り値が S_OK でも、グラフがアクティブな間にフォーマットを変更できるとは限らないためである。一部のフィルタは S_OK を返すが、グラフがアクティブの場合に変更を拒否する。一部の入力ピンでサポートされている DynamicQueryAccept メソッドでは、S_OK はグラフのアクティブ中にピンがフォーマットを変更できることを明示的に意味する。入力ピンが IPinConnection インターフェイスをサポートする場合、QueryAccept ではなく DynamicQueryAccept を呼び出すこと。
ほとんどの場合、この機構では、ビット深度の変更のように、フォーマットを大きく変更することはできない。この機構は、ビデオ デコーダがパレットを切り替えるときなどに使える。この場合、イメージのディメンジョン、ビット深度など、フォーマットの基本的な詳細情報は変わらないが、新しいメディア タイプは異なるパレット エントリの集合を持つ。
実装上の注意
DirectShow 基底クラスで、CBasePin::QueryAccept は CheckMediaType メソッドを呼び出す。このメソッドは最初のピン接続中にも呼び出される。変換フィルタの場合、入力ピンの CheckMediaType メソッドは、出力ピンが接続されているかどうか、また接続されているときは入力メディア タイプが出力メディア タイプと互換性があるかどうかを常に確認する必要がある。したがって、この実装は QueryAccept に有効である可能性が高い。有効ではない場合、必要な追加チェックを行うため、QueryAccept をオーバーライドすること。また、CTransformFilter クラスは CheckInputType メソッドと CheckTransformメソッド内にこのロジックをカプセル化する点にも注意すること。一方、CTransInPlaceFilter クラスは、常に次のアップストリーム フィルタまたはダウンストリーム フィルタに対して QueryAccept を呼び出す。
CBaseInputPin::Receive メソッドは受け取ったサンプルにメディア タイプがあるかどうかを確認し、メディア タイプがある場合は、CheckMediaType を呼び出す。しかし、現在のメディア タイプを保持するピンの m_mt メンバは更新しない。フィルタがサンプルを処理するときは、サンプルにメディア タイプがあるかどうかを確認すること。新しいタイプがある場合は、ピンの SetMediaType を呼び出すか、m_mt の値を直接設定して、そのタイプを保存する必要があることが多い。一方、ビデオ変換フィルタ用に設定された CVideoTransformFilter クラスは、変更があったときにメディア タイプを保存する。詳細については、DirectShow 基底クラス ライブラリの CVideoTransformFilter::Receive のソース コードを参照すること。
場合によっては、QueryAccept 呼び出しをダウンストリームに渡した後、出力サンプルにメディア タイプをアタッチし、ダウンストリーム フィルタにフォーマットの変更を処理させることもある。