« VMR9&WMV サンプル | メイン | 再生が進まない »

2005年12月15日

吉里吉里 ムービー拡張日誌2:: DirectX VAを有効に

    

いろいろと思い出すために過去のエントリーを読んでいて、やはりDirectX VAなんとかならないかなぁと考えた。
で、ふとGraphEditでやったらどうなるのだろう? と見てみると、CPU負荷激減。
800*600 30fpsのWMVムービーをPen4 3GHz HTで再生すると10%~15%になった。
今までのYV12接続では30%~35%だった。
また、Windows Media Player 10でもほぼ同じ負荷。
WMPと同程度だったので、こんなものかと思っていたが、GraphEditの負荷を見ると明らかに異なる。
GraphEditでは、DirectX VAが使われている可能性が高い。
ちなみに、640*480 30fpsのWMVムービーで試すと10%程度だった。WMPでは20%~30%。
これはMPEG IをWMPで再生した時と同程度の負荷だ。
DirectX VAが使えたら、CPU負荷は半分以下になる可能性がある。
これはでかい。

GraphEditで接続情報を吐かせると、接続にはDXVA_ModeWMV9_Bが使われていた。
やはり、DirectX VAが使われている。
でも、どうやって?

動的フォーマット変更か?と思って試したが、違うようだ。

デバッガで追っていたら気になることがあった。
IPin::ReceiveConnectionの返り値がE_NOINTERFACEになっている。
普通、接続できない場合は「指定したメディア タイプは受け入れられない。(VFW_E_TYPE_NOT_ACCEPTED)」が返ってくる。
なのに、E_NOINTERFACEとはおかしい。
また、IAMVideoAccelerator でサポートしているGUIDを取得するとDXVA_ModeWMV9_Bが入っていた。
ネゴシエーションのプロセスが間違っているのではないか? と思いながら、VMRの入力ピンが要求しそうなインターフェイスを考える。
確か、IAMVideoAcceleratorはIAMVideoAcceleratorNotifyが必要になるはず。
IAMVideoAcceleratorの説明を見ると――
ビデオ デコーダ フィルタがこのインターフェイスのメソッドを呼び出す場合は、デコーダの出力ピンでIAMVideoAcceleratorNotifyインターフェイスをサポートしている必要がある
――出力ピンでIAMVideoAcceleratorNotifyインターフェイスをサポート?
ソースを見直すと、そんなことしていない。

そこで、IAMVideoAcceleratorNotifyが要求されたら、IWMReaderAcceleratorから取得して渡すようにした。
すると、今まで失敗していたIPin::ReceiveConnection呼び出しが成功した。
が、接続は失敗する。
CBaseOutputPin::CompleteConnect内で失敗しているようだ。
デバッガで追うとアロケーターのComitで失敗していた。
Commitのタイミングで、DecideBufferSize内でCommitするようにした。
が、やはりCommitのタイミングはここではないようだ。
とりあえず、ここのCommitをコメントアウトすると接続は完了するようになった。

でも、IWMReaderでは再生させる部分を完全には作っていないので再生しても何もでない。
また、Commitもきちんとしないといけない。
基底クラスのソースを見ると
CBaseRendererでは、PauseとRunでCommitをコールしていた。
CBaseOutputPinでは、Active内でCommitをコールしていた。
CBaseOutputPinは現在使用しているので、Commitは気にしなくても大丈夫だろうか?

ま、なんにしてもIWMReaderを使って再生できるようにしないと。
でも、そしたら今のやつとは全然違うものになってしまう。
今日公開したサンプルは意味なしかも・・・



投稿者 Takenori : 2005年12月15日 03:51




comments powered by Disqus
Total : Today : Yesterday : なかのひと