Sign in to follow this  

Problems with Video replay and Direct3d (IVMRSurfaceAllocator9, IVMRImagePresenter9)

This topic is 3855 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, i try to replay a video directly under Direct3D but somehow I don't get the code working. At the moment I'am stuck with an exception outside of my own code. Maybe some one can help me fix my problem. Thanks a lot guys. Code and example videos can be downloaded here Here is my code:
class VideoAllocatorPresenter
	: public IVMRSurfaceAllocator9,
	  public IVMRImagePresenter9
{
public:
	    STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { 
				dbglog() << "QueryInterface " << std::endl;
				*ppv = this;
				return S_OK; //GetOwner()->QueryInterface(riid,ppv);            
/*				ppv = NULL;
				return E_NOINTERFACE;*/
    };                                                          
    STDMETHODIMP_(ULONG) AddRef() { 
			  dbglog() << "AddRef" << std::endl;
        return 1 ;//GetOwner()->AddRef();                            
    };                                                          
    STDMETHODIMP_(ULONG) Release() {              
			  dbglog() << "Release" << std::endl;
        return 1;//GetOwner()->Release();                           
    };

		VideoAllocatorPresenter( IDirect3DDevice9* dev ):d3dDevice_(dev) {};
	
		virtual ~VideoAllocatorPresenter() {}; 
	
		/*virtual HRESULT */STDMETHODIMP AdviseNotify( IVMRSurfaceAllocatorNotify9*  lpIVMRSurfAllocNotify ) 
	  {
		  dbglog() << "AdviseNotify " << lpIVMRSurfAllocNotify << std::endl;

		  allocNotify_ = lpIVMRSurfAllocNotify;
		  return S_OK;
	  };

	
		/*virtual HRESULT */STDMETHODIMP GetSurface( DWORD_PTR  dwUserID, DWORD  SurfaceIndex, DWORD  SurfaceFlags,
											IDirect3DSurface9**  lplpSurface )
	  {
		  dbglog() << "GetSurface  " << SurfaceIndex << std::endl;
		  SurfaceIndex = 0;
		  *lplpSurface = &surfaces_[SurfaceIndex];
		  dbglog() << "GetSurface  done " << *lplpSurface << std::endl;
		  return S_OK;
	  };

	/*virtual HRESULT */STDMETHODIMP InitializeDevice( DWORD_PTR  dwUserID, VMR9AllocationInfo*  lpAllocInfo,
														DWORD*  lpNumBuffers )
	{
	
		dbglog() << "InitializeDevice " << allocNotify_ << std::endl;

		surfaces_ = (IDirect3DSurface9*) malloc(sizeof( IDirect3DSurface9) * (*lpNumBuffers) );
		 	IDirect3D9* iD3D9;
	  D3DDEVICE_CREATION_PARAMETERS params;  
  
	  DXUTGetD3DDevice()->GetCreationParameters(&params); 

	  DXUTGetD3DDevice()->GetDirect3D( &iD3D9 );
	  HMONITOR hMonitor = iD3D9->GetAdapterMonitor( params.AdapterOrdinal );
		HRESULT hr = allocNotify_->SetD3DDevice( d3dDevice_, hMonitor );
		if( FAILED( hr ) ) 
		{
			dbglog() << "SetD3DDevice: " << hr <<  std::endl;
		}
		//lpAllocInfo->dwFlags |= VMR9AllocFlag_TextureSurface;
		hr = allocNotify_->AllocateSurfaceHelper( lpAllocInfo, lpNumBuffers, &surfaces_ ); 
		if( FAILED( hr ) ) 
		{
			dbglog() << "AllocateSurfaceHelper: " << hr <<  std::endl;
		}
		dbglog() << "  number buffers: " << (*lpNumBuffers) << std::endl;
		return S_OK;
	};

	/*virtual HRESULT */STDMETHODIMP TerminateDevice( DWORD_PTR  dwID )
	{
		dbglog() << "TerminateDevice" << std::endl;
		return S_OK;
	};


	/*virtual HRESULT */STDMETHODIMP PresentImage( DWORD_PTR  dwUserID, VMR9PresentationInfo*  lpPresInfo )
	{
		dbglog() << "PresentImage" << std::endl;
		return S_OK;
	};

	/*virtual HRESULT */STDMETHODIMP StartPresenting( DWORD_PTR  dwUserID )
	{
	  dbglog() << "StartPresenting" << std::endl;
		return S_OK;
	};

	/*virtual HRESULT */STDMETHODIMP StopPresenting( DWORD_PTR  dwUserID )
	{
		dbglog() << "StopPresenting" << std::endl;
		return S_OK;
	};

private:
	IVMRSurfaceAllocatorNotify9* allocNotify_;
	IDirect3DSurface9* surfaces_;
	IDirect3DDevice9* d3dDevice_;

};
IMediaControl *m_pMediaControl;


std::string getMediaError(HRESULT hr)
{
    if (FAILED(hr))
    {
        TCHAR szErr[MAX_ERROR_TEXT_LEN];
        DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
				std::stringstream result;
        if (res == 0)
        {
   				  result << "Unknown Error: " << hr << " ";
        } else
				{
   				result << szErr;
				}
				return result.str();
    }
		return "";
}

void initVideoRendering()
{
  CoInitializeEx( NULL, 0 );
	static VideoAllocatorPresenter allocPresent( DXUTGetD3DDevice() );

	//create graph manager	
	dbglog() << "Step 0" << std::endl;
	IGraphBuilder *m_pGraph;
	
	HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGraph);
	if FAILED( hr )
		dbglog() << "failure 1 " << getMediaError( hr ) << std::endl;
	
	// BUILD the VMR9
	IBaseFilter*				m_pVMRBaseFilter;
	hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**) &m_pVMRBaseFilter);
	if FAILED( hr )
		dbglog() << "failure 2 " << getMediaError( hr ) << std::endl;
	
	// ADD the VMR9 to the graph
	hr = m_pGraph->AddFilter(m_pVMRBaseFilter, L"VMR9");
	if FAILED( hr )
		dbglog() << "failure 3 " << getMediaError( hr ) << std::endl;
	
	IVMRFilterConfig9*			m_pVMRFilterConfig;
	hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRFilterConfig9, (void**) &m_pVMRFilterConfig);
  if FAILED( hr )
		dbglog() << "failure 4 " << getMediaError( hr ) << std::endl;

	dbglog() << "Step 1" << std::endl;	

	//m_pVMRFilterConfig->SetNumberOfStreams(2);

	hr = m_pVMRFilterConfig->SetRenderingMode(VMR9Mode_Renderless);
	if FAILED( hr )
		dbglog() << "failure 5 " << getMediaError( hr ) << std::endl;

	IVMRSurfaceAllocatorNotify9 *surfaceNotify;
	hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRSurfaceAllocatorNotify9, (void**) &surfaceNotify);
  if FAILED( hr )
		dbglog() << "failure 6 " << getMediaError( hr ) << std::endl;

	D3DDEVICE_CREATION_PARAMETERS params;  
  
	DXUTGetD3DDevice()->GetCreationParameters(&params);      // Get parameters of D3D  
  
  IDirect3D9* iD3D9;
  DXUTGetD3DDevice()->GetDirect3D( &iD3D9 );
	HMONITOR hMonitor = iD3D9->GetAdapterMonitor( params.AdapterOrdinal );
	hr = surfaceNotify->SetD3DDevice( DXUTGetD3DDevice(), hMonitor );
	if FAILED( hr )
		dbglog() << "failure 7 " << getMediaError( hr ) << std::endl;
	
	hr = surfaceNotify->AdviseSurfaceAllocator( 42,static_cast<IVMRSurfaceAllocator9*>(&allocPresent) );
	if FAILED( hr )
		dbglog() << "failure 8 " << getMediaError( hr ) << std::endl;
	
	hr = allocPresent.AdviseNotify( surfaceNotify );
	if FAILED( hr )
		dbglog() << "failure 9 " << getMediaError( hr ) << std::endl;	
	
	//hr = m_pGraph->RenderFile(L"test_cinepak.avi",L"");	
	hr = m_pGraph->RenderFile(L"test_divx6.avi",L"");	
	if FAILED( hr )
		dbglog() << "failure 10 " << getMediaError( hr ) << std::endl;
	
	hr = m_pGraph->QueryInterface(IID_IMediaControl, (void**)&m_pMediaControl);	
	if FAILED( hr )
		dbglog() << "failure 11 " << getMediaError( hr ) << std::endl;
	
	IMediaEvent *m_pMediaEvent;
  
	dbglog() << "Step 2" << std::endl;

	hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void**)&m_pMediaEvent);	
	if FAILED( hr )
		dbglog() << "failure 12 " << getMediaError( hr ) << std::endl;

	hr =	m_pMediaControl->Run();
	if FAILED( hr )
		dbglog() << "failure 13 " << getMediaError( hr ) << std::endl;

	long evCode;
	m_pMediaEvent->WaitForCompletion(INFINITE,  &evCode );
  dbglog() << "Step done" << std::endl;
}

//--------------------------------------------------------------------------------------
// Rejects any devices that aren't acceptable by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                  D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
{
    // Typically want to skip backbuffer formats that don't support alpha blending
    IDirect3D9* pD3D = DXUTGetD3DObject(); 
    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
        return false;

    return true;
}


//--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
{
    return true;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;
		static bool firstCall = true;

		if( firstCall )
		{
			firstCall = false;
			initVideoRendering();
		}

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"VideoTutorial" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}

And here my Debug-Output:
25.5.2007-12:6:6
Step 0
Step 1
AddRef
QueryInterface 
QueryInterface 
QueryInterface 
AdviseNotify 00F90250
InitializeDevice 00F90250
  number buffers: 1
GetSurface  0
GetSurface  done 001B2D80
Step 2
GetSurface  43056640
GetSurface  done 001B2D80

Share this post


Link to post
Share on other sites

This topic is 3855 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this