プログラマのつれづれなるままにプログラマのつれづれなるままに音宮志久が思ったことなどをネタにします。プログラムネタ・数学ネタがメインです。(1)コメントを残す題名が面倒になってきたのでこの書き方で終わらせます。いうわけでやっとの事で入れるVMR9を使ってみるおよび実装してみます。Renderer9」の略語ですね。最後の9はDirectX9と密接に結びついている、という意味を表しています。途中でいきなりIDirect3DDevice9とかDirect3D9に関わるオブジェクトが登場することになります。しなくてもいい場合もありますが。それらはすでに作成済みということで了承しておいて下さい。あと、今回の説明ではVMR9をRenderlessとして扱います。このモードはビデオのデコードは行うがウィンドウへの描画を実装者が正しく描画するように、というモードです。Windowed(ウィンドウモード)やWindowless(ウィンドウレスモード)ではゲームとして使う分には汎用性に欠けるといわざるを得ない部分が大きいのでこちらで説明します。この両者を使うパターンの場合はサンプルをそのままコピペした方が早いです。いってもRenderlessのこのパターンでもVMR9Allocatorというサンプルパターンをちょっと変形して使用するだけです。そちらを見てわかる型はそちらを見ちゃった方が圧倒的に早いです。以下は必要な部分の実装の前に必要となる動作コード部分です。1.DirectShowの使用例にしたがってグラフを作って再生この部分は過去の記事にもありますので面倒なので伏せます。m_lpGraphBuilder->RenderFile(lpwFileName,NULL)のコメント行を置き換える形で行います。2.フィルタをCOMとして作成するVMR9のフィルタはCOMとしてシステムに登録されている(ことになっている)ので、作成にはCoCreateInstanceの力を借ります。CoCreateInstance(CLSID_VideoMixingRenderer9,0,CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**)&m_lpVMRFilter);ちょっと今までで見たことがない形になっているのは、作成しているのはVMR9のフィルタのはずなのに受け取っている変数はIBaseFilterのポインタになっています。これは、IVMRFilterみたいな型を標準で用意していない(というより必要ない)からで、この場合はただのベースフィルタとして扱ってよい、という意味になります。描画モードをレンダーレスモードへと移行させます。ついでにミキシングも停止して単一のストリームのみを受け付けるように指示します。モードの変更はフィルタからIVMRFilterConfig9を受け取ってそれを使います。変更したら役目が終わるのでさっさと解放します。**)&lpFilterConfig);lpFilterConfig->SetNumberOfStreams(1);lpFilterConfig->SetRenderingMode(VMR9Mode_Renderless);lpFilterConfig->Release();なお、ヘルプにもありますがSetRenderingModeを呼び出せるのは1回だけでそれ以降は受け入れを拒否されますので気をつけてください。4.VMR9にサーフェイスアロケータを設定するこの場合のサーフェイスアロケータとは以下のようなオブジェクトです。VMR9はレンダーレスモードとなっているため、画面へのレンダリングを行わない。そのかわり、実装者からビデオのレンダリング対象となるサーフェイスを提供してもらい、その部分にレンダリングを行い、その作業を持って1フレームの描画を完了したことにする。このとき、レンダリング対象となるサーフェイスを提供させるために実装者が実装するオブジェクトがサーフェイスアロケータである。これの実装は次回以降行います。これがまた大変です・・・。サーフェイスアロケータを呼び出してそれを設定することで処理を行います。lpSurfaceAllocNotify->Release();自前で実装したサーフェイスアロケータにDirect3DDeviceとSurfaceAllocatorNotify(サーフェイスの確保が必要なときの通知インターフェイス)を設定することで以降必要なタイミングでIVMRSurfaceAllocator9とIVMRImagePresenter9の機能が呼び出されて描画処理が行われます。ちなみに見てわかると思いますが、IVMRSurfaceAllocator9のAdviceNotifyは自前で実装するのですが、呼び出すのも実は自分です。システムが呼び出すわけではないです。5.グラフにVMR9を登録する準備が完了したらグラフにフィルタを登録して使ってもらえるようにしましょう。Renderer9");ちなみに、第二引数の文字列はデバッグ用の文字列で実際には何でもいいです。GraphEditやGraphStudioなどのDirectShowのフィルタのつながりを直接見るツールを使うとこの名前がそのまま表示されますので見苦しくならない程度にはちゃんとつけておいた方がいいと思います。埋め込むべきコードは紹介し終えたので後は普通に再生処理を行えます。それでは描画できません。描画にはサーフェイスアロケータ内でいろいろと処理が必要になります。ヘルプには「ファイルを読み込むときに~~~」とか難しい説明がありますが、基本的にはフィルタを登録した時点でそのフィルタを使える限りはできるだけ使うというIGraphBuilderのインテリジェント接続を利用することになるのでビデオラインがあればこれが使われるようになります。7.解放する前に使い終わったフィルタを解放する使い終わったらちゃんと解放しましょう。ないとフィルタの参照カウントが残ってしまいます。m_lpSurfaceAllocator->Release();m_lpVMRFilter->Release();一通りの流れを紹介しました。毎日書かないとアクセス数が保てないもんですね・・・。ないものではありますが・・・。コメントをキャンセルメールアドレスが公開されることはありません。志久プログラムネタや思いついたり世間で話題になっている数学ネタを解説したりしています。プログラマとしては今年度(つまり2020年3月)までの復帰となるか、完全復帰となるか、別の仕事に戻るかは運と実力次第。ちなみに教育系のプログラムでもOKです。アクセスカウンタアクセス数:スポンサーリンク。