locked
About MFT_MESSAGE_SET_D3D_MANAGER. RRS feed

  • Question

  • Hi all!

    Please give me some pieces of advice on  MFT_MESSAGE_SET_D3D_MANAGER.

    Although I set the MF_SA_D3D_AWARE in the argument at the GETAttributes(IMFAttributes** pAttribute) of myMFT,
    the MF didn't notify myMFT of MFT_MESSAGE_SET_D3D_MANAGER.
    I describe my testcode in the following.


     HRESULT myMFT::GetAttributes(IMFAttributes** pAttributes)
     {
         HRESULT hr = MFCreateAttributes(pAttributes, 1);
         if( SUCCEEDED(hr) )
         {
             hr = (*pAttributes)->SetUINT32(MF_SA_D3D_AWARE, TRUE);
         }

         return hr;
     }


    Of course the category of myMFT is VIDEO_DECODER and myMFT is connected to EVR directly.


    Please tell me the reason why the MF does not notify myMFT about MFT_MESSAGE_SET_D3D_MANAGER?
    How can I get that message from the MF?

    My Best Regards.

    Monday, October 23, 2006 11:18 AM

Answers

  • All right, here's how you do that:

    Implement IMFTopoLoader (details on your implementation below) as a CoClass.

    In the pConfiguration argument to MFCreatePMPMediaSession, set the attribute MF_SESSION_TOPOLOADER to the CLSID of the topoloader you implemented.

    Your topoloader implementation is fairly straightforward.  Here's the general idea for what the Load() method would do:

    • MFCreateTopoLoader() to create the MF-provided implementation of the topoloader
    • Do the things I described above on pInputTopo, i.e. get the D3D manager from the output node's object, give your MFT the D3D manager, and mark the node as MF_TOPONODE_D3DAWARE
    • Pass the topology onto the MF-provided topoloader's Load() so that it can do the rest.
    • Be prepared to handle failures from the MF-provided topoloader.  If it fails, then you might want to try undoing what you did and try the Load() again without D3D.

     

    Thursday, October 26, 2006 4:02 PM

All replies

  • The reason this isn't happening for you is that you inserted the decoder in the topology yourself.  Nothing wrong with that, of course, but the MF topology loader's D3D setup logic kicks in only if it inserts the decoder.

    So you have two options:

    Option#1: Register your MFT and the types it handles via MFTRegister.  Do not insert this node in the topology when building your partial topology (i.e. the topology you pass to IMFMediaSession::SetTopology); instead, just connect source node to sink node (each one advertising the correct media types, of course).  The MF topoloader will find your decoder through MFTEnum, instantiate it, and do all this stuff.

    Option#2: Insert the decoder yourself and do the D3D setup by hand.  Fortunately, there are only a couple steps to this, assuming your pipeline runs in the same process (i.e. you're not playing protected content):

    • Make sure that the output (EVR) node has as its object the EVR's IMFStreamSink, rather than an IMFActivate for the EVR. 
      • If you have an IMFActivate, just do an ActivateObject(), get the IMFMediaSink, get the MF_TOPONODE_STREAMID attribute, and call pMediaSink->GetStreamSinkById; if that fails (which I believe it can on the EVR), do a pMediaSink->AddStreamSink, and then do pNode->SetObject.
    • Call MFGetService on the IMFStreamSink with guidService = MR_VIDEO_ACCELERATION_SERVICE and riid = IID_IDirect3DDeviceManager9.  Now you have the D3D manager.
    • Call pMFT->ProcessMessage( MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR) pD3DManager ) on your MFT.
    • Set the MFT_TOPONODE_D3DAWARE attribute to 1 on your MFT node (not on the MFT itself).

    Note that now that you have set up D3D, your topology load might fail because of it if the media types aren't handled.  So you'll need to be prepared to undo this and try the load again.  Undoing is a matter of doing the pMFT->ProcessMessage with a value of 0, and setting the MF_TOPONODE_D3DAWARE attribute value to 0.

    If you plan to make this work with protected content as well, the application will need to do a bit more to make all this happen in the mfpmp.exe process (but it's not that much harder).  The main idea in this case is that the above logic will need to take place in the mfpmp process, so you will need to provide a CoCreate-able IMFTopoLoader implementation that essentially wraps MF's implementation plus does this stuff.  Happy to write out more details if you need them; let me know.

    Hope that all helps!

    Tuesday, October 24, 2006 3:44 PM
  • Hi Becky!

    Thank you for the answer.

    I really want  to know the details for Protected Environment.

    So, Would you please show me how to implement the CoCreate-able IMFTopoloder and so on?

    My best regards.

    Wednesday, October 25, 2006 7:19 AM
  • All right, here's how you do that:

    Implement IMFTopoLoader (details on your implementation below) as a CoClass.

    In the pConfiguration argument to MFCreatePMPMediaSession, set the attribute MF_SESSION_TOPOLOADER to the CLSID of the topoloader you implemented.

    Your topoloader implementation is fairly straightforward.  Here's the general idea for what the Load() method would do:

    • MFCreateTopoLoader() to create the MF-provided implementation of the topoloader
    • Do the things I described above on pInputTopo, i.e. get the D3D manager from the output node's object, give your MFT the D3D manager, and mark the node as MF_TOPONODE_D3DAWARE
    • Pass the topology onto the MF-provided topoloader's Load() so that it can do the rest.
    • Be prepared to handle failures from the MF-provided topoloader.  If it fails, then you might want to try undoing what you did and try the Load() again without D3D.

     

    Thursday, October 26, 2006 4:02 PM
  • Hi Becky!

     

    Thank you for the answer!

    I appreciate your advice.

    Monday, October 30, 2006 10:00 AM