ビデオ処理を行っていない場合は、IDirect3DDeviceManager9
インターフェイスを実装および/または使用しても意味がありません。
Direct3Dデバイスの寿命を管理する独自の方法を実装するだけで、オブジェクト/スレッドがインターフェイスポインターを利用できるようになり、同期を行うことができます。Direct3Dデバイスは、オブジェクト/スレッド間でのみ共有できる魔法のようなものではありませんIDirect3DDeviceManager9
。他のリソースと同じです。また、正しく初期化すると、異なるスレッドから特定のメソッドを同時に呼び出すこともできます(つまり、別のスレッドによって変更される可能性のあるデバイスの状態に依存しないほとんどすべてのもの)。
インターフェイスポインタを使用可能にすることは、ポインタを保持するシングルトンを持つのと同じくらい簡単です。または、オブジェクト/スレッドがすでに何らかの方法でコラボレーションしている場合は、情報を交換するための何らかの手段がすでに必要です。したがって、オブジェクト/スレッドにDirect3Dデバイスへのアクセスを許可するためにすでに必要なものを拡張できるはずです。また、を使用して同期を簡単に行うことができますCRITICAL_SECTION
。
本当に使用したい場合はIDirect3DDeviceManager9
、私が理解している限り、にIMFGetService
アクセスするすべてのオブジェクトにインターフェイスを実装する必要がありますIDirect3DDeviceManager9
。/を要求されたときに、Direct3Dデバイスを管理するオブジェクトへのインターフェイスポインターを返すGetService
ように関数を実装します。MR_VIDEO_ACCELERATION_SERVICE
IDirect3DDeviceManager9
編集:コードサンプルについて:ここでの説明で十分だと思います。複数のスレッド間で何かを共有することは、短いコードサンプルで説明しようとはしません。マルチスレッドアプリケーションの作成方法を知っている場合、Direct3Dデバイスの使用は、他のリソースでの使用方法と同じです。また、マルチスレッドアプリケーションの作成方法がわからない場合、そのトピックは複雑すぎて、単一のスタックオーバーフローの答えにはなりません。
MSがなぜ使用を推奨するのかという質問に関してはIDirect3DDeviceManager9
...まあ、私はそのような一般的な推奨を知りません。ビデオ処理(DXVA、EVRなどを使用)を行う場合にのみお勧めします。またはもっと義務付けられたように; D3Dデバイスマネージャーを使用せずに、拡張ビデオレンダラーなどとD3Dデバイスを共有できるかどうかはわかりません。結局のところ、それがD3Dデバイスマネージャーのために作られたものです。VMR9でデバイスをレンダラーと共有することは、次の2つの方法でのみ可能でした。
文書化された方法: VMR9の「現在の」コールバックからのみデバイスにアクセスします。これはかなり制限されています-たとえば、ビデオのフレームレートに制限されています。
文書化されていない方法:IVMRFilterConfig9::SetNumberOfStreams
1つの入力ストリームのみを呼び出して接続しないでください。そうすれば、VMR9は「ミキサーモード」に切り替わりません。「ミキサーモード」でない場合、VMR9はデバイスの状態を変更しません。したがって、D3Dデバイスがマルチスレッドで初期化された場合、VMR9が同じデバイスを使用している間、D3Dデバイスを自由に使用できます。
また、VMR9では、D3Dデバイスを別のDirectShowフィルターで使用することはまったくできませんでした。D3Dデバイスマネージャーはそれを改善し、フィルターと独自のアプリケーションコードに、状態の変更を含むD3Dデバイスを使用する機能を提供します。ただし、D3Dデバイスを使用するすべてのコンポーネントを自分で実装する場合は、D3Dデバイスマネージャーを使用しても意味がありません。また、D3Dデバイスを必要とするサードパーティのコンポーネントを使用している場合でも、それらのコンポーネントがD3Dデバイスマネージャーをサポートしている場合にのみ、D3Dデバイスマネージャーを使用できます。それらのコンポーネントがたまたまDirectShowまたはMediaFoundationフィルター/コンポーネントでない限り、これはおそらく当てはまりません。