6

Direct3D アプリケーションの複数のスレッドとオブジェクト間で 1 つの Direct3D デバイスを共有したいと考えています。ビデオ処理やビデオ アクセラレーションは行っていませんが、Direct3D デバイス マネージャーを見つけました 。 v=vs.85).aspx

私のコードでは、次のことを行っています。

  // Create the device manager
  UINT resetToken = 0;
  IDirect3DDeviceManager9* deviceManager = NULL;
  if (FAILED(DXVA2CreateDirect3DDeviceManager9(&resetToken, &deviceManager)))
    return false;

  // Add the device to the device manager
  if (FAILED(deviceManager->ResetDevice(device, resetToken)))
    return false;

  deviceManager->AddRef();

私の質問は、Direct3D デバイス マネージャーを作成した後、デバイス マネージャーへのポインターを渡すことなく、direct3d デバイス マネージャーを他のオブジェクトと共有するにはどうすればよいかということです。マイクロソフトは具体的に次のことを行うように言っていますが、次のことが実際に何を意味するのかわかりません。

デバイスの所有者は、他のオブジェクトが IDirect3DDeviceManager9 インターフェイスへのポインターを取得する方法を提供する必要があります。標準のメカニズムは、IMFGetService インターフェイスを実装することです。サービス GUID は MR_VIDEO_ACCELERATION_SERVICE です。

IMFGetService インターフェイスを使用してデバイス マネージャーを共有する方法を誰か教えてもらえますか?

4

1 に答える 1

4

ビデオ処理を行っていない場合は、IDirect3DDeviceManager9インターフェイスを実装および/または使用しても意味がありません。

Direct3Dデバイスの寿命を管理する独自の方法を実装するだけで、オブジェクト/スレッドがインターフェイスポインターを利用できるようになり、同期を行うことができます。Direct3Dデバイスは、オブジェクト/スレッド間でのみ共有できる魔法のようなものではありませんIDirect3DDeviceManager9。他のリソースと同じです。また、正しく初期化すると、異なるスレッドから特定のメソッドを同時に呼び出すこともできます(つまり、別のスレッドによって変更される可能性のあるデバイスの状態に依存しないほとんどすべてのもの)。

インターフェイスポインタを使用可能にすることは、ポインタを保持するシングルトンを持つのと同じくらい簡単です。または、オブジェクト/スレッドがすでに何らかの方法でコラボレーションしている場合は、情報を交換するための何らかの手段がすでに必要です。したがって、オブジェクト/スレッドにDirect3Dデバイスへのアクセスを許可するためにすでに必要なものを拡張できるはずです。また、を使用して同期を簡単に行うことができますCRITICAL_SECTION

本当に使用したい場合はIDirect3DDeviceManager9、私が理解している限り、にIMFGetServiceアクセスするすべてのオブジェクトにインターフェイスを実装する必要がありますIDirect3DDeviceManager9。/を要求されたときに、Direct3Dデバイスを管理するオブジェクトへのインターフェイスポインターを返すGetServiceように関数を実装します。MR_VIDEO_ACCELERATION_SERVICEIDirect3DDeviceManager9


編集:コードサンプルについて:ここでの説明で十分だと思います。複数のスレッド間で何かを共有することは、短いコードサンプルで説明しようとはしません。マルチスレッドアプリケーションの作成方法を知っている場合、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フィルター/コンポーネントでない限り、これはおそらく当てはまりません。

于 2012-10-23T03:37:50.030 に答える