Microsoft DirectX 8.0 |
このトピックでは、アプリケーションからビデオをフルスクリーン モードでレンダリングするように指示されたときにデフォルトの IVideoWindow PID で使用されるロジックについて説明する。代替レンダラ フィルタは、IVideoWindow PID を使用してアプリケーションとやり取りできる。代替レンダラの開発者は、フルスクリーン モードでのレンダリングが要求されたときに、フルスクリーン ビデオを表現するための最良の手段をこの PID がフィルタ グラフからどのように検索するかを、知っておく必要がある。
このトピックは、以下のセクションを含んでいる。
Microsoft® DirectShow® は、利用可能なハードウェア リソースの種類に応じて、いくつかの方法でフルスクリーン サポートを実装する。アプリケーションは、フィルタ グラフ マネージャによって提供される IVideoWindow インターフェイスを通じてフルスクリーン ビデオ再生をサポートできる。アプリケーションは、フルスクリーン再生に対して独自の実装を持つこともできるが、多くの場合 IVideoWindow 実装を使用したほうがリソースの使用効率が良い。
アプリケーションがフルスクリーン モードを要求すると、IVideoWindow PID はフルスクリーン サポートを実装するために、3 つの異なるオプションを試す。通常このオプションは、フィルタ グラフが最初にフルスクリーン モードに入るときに選択される。フルスクリーン モードの間は、IVideoWindow メソッドが呼び出されることはない (フルスクリーン プロパティへのアクセスを除いて)。呼び出そうとすると、VFW_E_IN_FULLSCREEN_MODE メッセージが返される。PID は、IVideoWindow をサポートして以下のいずれかの特性を持つフィルタを、次の順序で検索する。
この 3 つのオプションのいずれも見つからない場合は、デフォルトとして、IVideoWindow をサポートするフィルタのビデオを単純にフルスクリーンに伸長する。パフォーマンス ペナルティは考慮されない。
最初のオプションは、フルスクリーン モードを直接サポートするフィルタをフィルタ グラフから検索することである。フルスクリーン モードへの移行を指示されると、IVideoWindow PID はまずフィルタ グラフ内で IVideoWindow をサポートするフィルタをすべてスキャンする。PID は各フィルタ上で IVideoWindow::get_FullScreenMode を呼び出す。フィルタが E_NOTIMP (デフォルト) を返した場合、PID はそのフィルタにはフルスクリーン再生の固有サポートがないと仮定する。フィルタがそれ以外の値を返した場合は、フルスクリーン再生の候補フィルタとなる。すなわち、フルスクリーン モードをオンまたはオフにするためのフィルタ グラフ マネージャへの呼び出しは、その候補フィルタに直接送られる。このメカニズムにより、フィルタがフルスクリーン モードを直接サポートするように拡張できる。通常の Windows ベースのレンダラのほとんどは、この機能をサポートする必要がない。
フルスクリーン レンダリング フィルタが見つからない場合、PID は IVideoWindow インターフェイスをサポートするフィルタのうち、そのウィンドウがペナルティなしでフルスクリーンに伸長できるものを検索する。そのために PID は、フィルタ グラフ内で IVideoWindow をサポートするフィルタのリストをスキャンする。見つかった各フィルタに対して、PID は IVideoWindow::GetMaxIdealImageSize を呼び出す。フィルタがそのウィンドウがコストなしでフルスクリーンに伸長できることを示していれば、そのフィルタが候補フィルタになる。
その候補フィルタに対してフルスクリーンでのレンダリングが要求されると、PID はフィルタの IVideoWindow プロパティのいくつかをリセットして、ウィンドウをフルスクリーンに伸長する。これは通常、所有者を NULL に設定し、ウィンドウのスタイルを境界またはキャプションを表示しないように変更し、ウィンドウの位置を現在の表示サイズに一致するように更新することを意味する。フルスクリーン モードがオフになると、フィルタのプロパティはフルスクリーン モードに入る前の状態に戻る。
IVideoWindow をサポートするビデオ レンダラのほとんどは、アクティブ (ポーズまたは実行中) になったときに初めてリソースを割り当てるので、それまでの間は理想的な最大イメージ サイズを返すことができない。そのため、フィルタ グラフが停止状態のときにフィルタのリストをスキャンする場合、PID は IVideoWindow::GetMaxIdealImageSize を呼び出す前に各フィルタをポーズする。このメソッドを呼び出した後、フィルタはもう一度停止される。
ここまでのオプションがいずれも失敗した場合、PID はフィルタ グラフ内で IVideoWindow インターフェイスをサポートする最初のフィルタを検索し、それが現在のビデオ レンダリング フィルタであると仮定する。
IVideoWindow をサポートするフィルタがない場合、フルスクリーン モードに変更するための呼び出しは VFW_E_NO_FULLSCREEN を返す。フルスクリーン モードへの変更を要求されると、PID は現在のレンダラに対してフルスクリーン モードを効率的にサポートできるかどうかを問い合わせる。効率的にサポートできる場合、グラフに変更は加えられない。それができない場合には、PID はフィルタ グラフが停止されていなければそれを停止し、現在のレンダラを切り離し、その代わりに DirectShow フルスクリーン レンダラを再接続して、終了後に元のフィルタ グラフを復元する。フルスクリーン モードから出るときには、これと逆の手順を踏む。すなわち、フルスクリーン レンダラが切り離され、元のフィルタが再接続される。フィルタ グラフの状態は同様に復元される。フルスクリーン レンダラは、Microsoft® DirectDraw® によって提供される表示変更機能を使用した特別なレンダラである。たとえば、1024 × 768 からフルスクリーン表示を 320 × 240 に切り替えたりできる。低い解像度のモードに変更することにより、イメージを伸長することなく低コストでフルスクリーン レンダリングを実装できる。
フルスクリーン レンダラは現在、320 × 200 × 8/16 ビット/ピクセル、320 × 240 × 8/16、640 × 400 × 8/16、640 × 400 × 8/16、640 × 480 × 8/16、800 × 600 × 8/16、1024 × 768 × 8/16、1152 × 864 × 8/16、1280 × 1024 × 8/16 の各表示モードを実装している。モード X レンダラは IFullScreenVideo インターフェイスをサポートする。モード X レンダラを接続すると、このレンダラは DirectDraw によって利用可能になった表示モードをロードする。利用可能なモードの数は、IFullScreenVideo::CountModes によって取得できる。各モードに関する情報は、IFullScreenVideo::GetModeInfo および IFullScreenVideo::IsModeAvailable を呼び出すことで得られる。アプリケーションは、OATRUE または OAFALSE で SetEnabled フラグを呼び出すことにより、各モードを有効または無効にできる。現在の値は、IFullScreenVideo::IsModeEnabled で照会できる。
モードを有効にするもう 1 つの方法は、クリップ消失係数を使用することである。これは、使用する表示モードを決定する際に失われる可能性のあるビデオの量を定義する。デコーダがビデオを圧縮できないと仮定した場合、たとえば 352 × 288 ピクセルの MPEG ファイルを 320 × 200 表示で再生すると、イメージの 40 パーセント以上が失われる。クリップ消失係数は、許容されるクリップ消失の上限を指定する。標準的な MPEG ビデオを 320 × 200 で再生できるように、デフォルトは 50 パーセントになっている。クリップ消失係数は IFullScreenVideo::SetClipFactor で設定できる。
最初の 3 つのオプションを試みた後は、フルスクリーン サポートを実装するための最後のオプションとして、IVideoWindow によって有効にされた任意のフィルタを使用し、そのウィンドウをフルスクリーンに伸長する。これは、結果のパフォーマンスの良し悪しに関係なく行われる。基本的に、フィルタ グラフ内で IVideoWindow インターフェイスによって有効にされた最初のフィルタが、候補フィルタとなる。このフィルタは、パフォーマンスを犠牲にせずにフルスクリーン伸長できるフィルタと、まったく同じように使用される (すなわち、所有者がリセットされ、スタイルが変更され、ウィンドウ位置は表示範囲に合わせて変更される)。
暗黙のパフォーマンス ペナルティがある場合にウィンドウをフルスクリーンに伸長するコストは、現在の表示解像度によって異なる。最悪のケースは、ユーザーが比較的高い解像度 (たとえば、1024 × 768) を使用し、レンダラが GUI を使ってイメージを伸長しなければならない場合である。この場合、フレーム スループットが非常に低くなるため、最後の手段としてのみ使用する。
アプリケーションに公開されるインターフェイスは比較的単純であるが、その基盤となる実装は複雑になる場合がある。フルスクリーン レンダラには、アプリケーション開発者が注意しなければならない特別な属性がある。特に、レンダラが表示モードを変更するのはアクティブな間 (ポーズ中または実行中) だけであることに注意する。したがって、フルスクリーン モードへの切り替え時にフィルタ グラフが停止していた場合には、フィルタ グラフが再び開始されるまで目に見える変更は行われない。フィルタ グラフが実行されると、表示モードが変更され、フルスクリーン レンダリングが開始される。
ウィンドウがフルスクリーンに伸長される場合 (すなわち、フルスクリーン レンダラを使用しない場合) は、状態に関係なく、フルスクリーン モードが設定された時点で変更が表示される。フルスクリーン再生がフィルタ グラフ内のフィルタによって直接サポートされる場合は、フルスクリーン レンダラの動作に準じて、アクティブな間にしかフルスクリーンに切り替えないこともある。フルスクリーン再生をサポートするフィルタがそのように動作するのは、フルスクリーン再生に必要なリソースがその時点まで利用できない場合があるためである。したがって、アプリケーションは停止中にフルスクリーン モードを設定することは避けたほうがよい。
これはユーザー インターフェイスのコンテキストにも同様に当てはまる。なぜなら、フィルタ グラフの停止中にフルスクリーン モードを設定すると、ユーザーはフルスクリーン モードから出る (すなわち元のアプリケーションに戻る) まで、グラフの実行を開始できない可能性がある。
IVideoWindow を実装するレンダラはすべて、そのウィンドウがアクティブになったとき、または非アクティブになったときに、フィルタ グラフ マネージャにイベント コードを送信する。フルスクリーン モードの間、PID はこれらのイベント コードを監視する。フルスクリーンにしたウィンドウが非アクティブになったことを検出すると、自動的にフルスクリーンモードを終了し、アプリケーション イベント キューに EC_FULLSCREEN_LOST 通知を送信する。これは PID によって行われる唯一の介入である。このトピックで説明したとおり、その他すべてのユーザー インターフェイスはアプリケーションに公開されている。
フルスクリーン再生で最も重要な点の 1 つは、フルスクリーン モードの間、フルスクリーン ウィンドウの上に他のウィンドウを表示できないことである。実際、フルスクリーン レンダラが表示モードを切り替えると、他のアプリケーションに対する GDI 出力がすべて無効にされるため、フルスクリーン ウィンドウの上にウィンドウを表示することは実際に不可能である。ユーザーがコンピュータにアクセスするには、ホット キーを使用する必要がある。
PID は、フルスクリーン再生の実装のために最終的にどのようなメカニズムを使用する場合でも、再生を実行するウィンドウで常にメッセージ ドレーン プロパティが設定されるようにする (メッセージ ドレーンは、レンダラに送信されるすべての Windows® メッセージが転送されるウィンドウを指定する)。そのため、フルスクリーン レンダラが使用される場合でも、フィルタ グラフ マネージャの IVideoWindow インターフェイスでメッセージ ドレーンが設定されている限り、すべてのメッセージがそのレンダラに渡される。
メッセージ ドレーンが適切なウィンドウに設定されているため、アプリケーションは、フルスクリーン モードを実装するフィルタに関係なく、フルスクリーン モードにおいてすべてのマウスおよびキーボード メッセージを受信できる。アプリケーションはそれに基づき、シークなどに対してホット キー サポートを実装することができる。ただし、プロパティはフルスクリーン モードでないときにしか設定できないので、アプリケーションがフルスクリーン モードの間しかメッセージを捕捉する必要がない場合、フルスクリーン モードをオンにする前にメッセージ ドレーンを設定しなければならない。同様に、メッセージ ドレーンのリセットは、フルスクリーン モードをオフにした後でなければ行えない。
アプリケーションについて考慮すべきもう 1 つの点は、フルスクリーン モードの間、IBasicVideo で設定した転送元矩形および転送先矩形が適用されないということである。PID はフルスクリーン モードに切り替える際にこれらの矩形をリセットする。これは、フルスクリーン サポートを実装するすべてのフィルタが同様に IBasicVideo をサポートすることが保証できないからである。