DMO介绍:

DirectX媒体对象(DirectX Media Objects,简称DMOs),是微软提供的一种流数据处理COM组件。与DirectShowfilter相比,DMO有很多相似之处。DMO结构简单、易于创建和使用。

DMO使用方式:

1.是应用程序直接使用DMO

2.在DirectShow filter中的应用。这个比较简单,只是使用了一个DMO wrapper filter。在DirectShow应用程序中,DMO是对用户透明的,所有使用DMO的工作均由DMO wrapper filter来完成(本文主要阐述此种运用方式)。

 

工程目的:

在DirectShowFilter Graph中使用DMO播放wma文件

 

相关代码:

//初始化COM组件
CoInitialize(NULL) ;
 
HRESULT  hr = S_FALSE
 
//创建Filter Graph
IGraphBuilder *  pGraphBuilder = NULL
Hr = ::CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void**)&pGraphBuilder);
ASSERT(SUCCEEDED(hr)) ;
 
//创建DMO wrapper filter
IBaseFilter *  pDmoFilter = NULL
hr = ::CoCreateInstance(CLSID_DMOWrapperFilter,NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pDmoFilter);
ASSERT(SUCCEEDED(hr)) ;
 
//获取IID_IDMOWrapperFilter接口
IDMOWrapperFilter *  pDmoWrapperFilter= NULL
hr =  pDmoFilter->QueryInterface(IID_IDMOWrapperFilter,(void**)&pDmoWrapperFilter);
 
ASSERT(SUCCEEDED(hr)) ;
 
//初始化DMO Wrapper Filter
hr =  pDmoWrapperFilter->Init(CLSID_WMAudioDecoderDMO,DMOCATEGORY_AUDIO_DECODER) ;
ASSERT(SUCCEEDED(hr)) ;
 
//将DMOWrapperFilter添加到FilterGraph
pGraphBuilder->AddFilter(pDmoFilter,L"WMA Decoder DMO") ;
 
//采用智能连接直接播放
hr =  pGraphBuilder->RenderFile(L"D:\\江南.wma",NULL);
 
IMediaControl *  pMediaControl = NULL
hr =  pGraphBuilder->QueryInterface(IID_IMediaControl,(void**)&pMediaControl);
 
//hr返回值为S_FALSE,但是仍然可以播放,暂时不知道原因
hr = pMediaControl->Run() ;
 
//释放COM组件
::CoUninitialize() ;

备注:

hr = pMediaControl->Run() ;//hr返回值为S_FALSE,但是仍然可以播放,暂时不知道原因

 

 

CLSID_WMAudioDecoderDMO 定义为
const GUID  CLSID_WMAudioDecoderDMO
与CWMADecMediaObject的UUID定义一致,本想直接使用CLSID_CWMADecMediaObject,无奈找不到相关lib,不知道此两个CLSID之间有什么联系,待研究
class  DECLSPEC_UUID("2eeb4adf-4578-4d10-bca7-bb955f56320a")
CWMADecMediaObject;
#endif


#ifndef  UNICODE
#define  UNICODE
#endif
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <streams.h>

#include <dmo.h>
#include <dmodshow.h>
#pragma comment(lib,"dmoguids.lib") 

//void main(int n, TCHAR **argv) 
void _tmain(int n, TCHAR **argv) 
{ 
	if(n!=2)
	{
		printf("No file input!\n"); 
		return;
	}
	/*
    IGraphBuilder *pGraph = NULL; 
    IMediaControl *pControl = NULL; 
    IMediaEvent   *pEvent = NULL;

    // Initialize the COM library. 
    HRESULT hr = CoInitialize(NULL); 
    if (FAILED(hr)) 
    { 
        printf("ERROR - Could not initialize COM library"); 
        return; 
    }

    // Create the filter graph manager and query for interfaces. 
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&pGraph); 
    if (FAILED(hr)) 
    { 
        printf("ERROR - Could not create the Filter Graph Manager."); 
        return; 
    }

    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); 
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

    // Build the graph. IMPORTANT: Change this string to a file on your system. 
    hr = pGraph->RenderFile(argv[1], NULL);  //L"C:Example.avi", NULL); 
	//hr = pGraph->RenderFile(L"C:\\DX90SDK\\Samples\\Media\\CLOCKTXT.avi", NULL); 
    if (SUCCEEDED(hr)) 
    { 
        // Run the graph. 
        hr = pControl->Run(); 
        if (SUCCEEDED(hr)) 
        { 
            // Wait for completion. 
            long evCode; 
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it 
            // can block indefinitely. 
        } 
    } 
    pControl->Release(); 
    pEvent->Release(); 
    pGraph->Release(); 
    CoUninitialize(); 
	*/

	//
	//初始化COM组件
    HRESULT hr = CoInitialize(NULL); 
    if (FAILED(hr)) 
    { 
        printf("ERROR - Could not initialize COM library"); 
        return; 
    }

	//创建Filter Graph
	IGraphBuilder * pGraphBuilder = NULL ;
	hr = ::CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void**)&pGraphBuilder);
    if (FAILED(hr)) 
    { 
        printf("ERROR - Could not create the Filter Graph Manager."); 
        return; 
    }

//创建DMO wrapper filter
IBaseFilter * pDmoFilter = NULL ;
hr = ::CoCreateInstance(CLSID_DMOWrapperFilter,NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pDmoFilter);
ASSERT(SUCCEEDED(hr)) ;
//获取IID_IDMOWrapperFilter接口
IDMOWrapperFilter * pDmoWrapperFilter= NULL ;
hr = pDmoFilter->QueryInterface(IID_IDMOWrapperFilter,(void**)&pDmoWrapperFilter);
ASSERT(SUCCEEDED(hr)) ;
//初始化DMO Wrapper Filter
const GUID CLSID_WMAudioDecoderDMO = {0x2EEB4ADF, 0x4578,0x4D10, {0xBC, 0xA7, 0xBB, 0x95, 0x5F, 0x56, 0x32, 0x0A}};
hr = pDmoWrapperFilter->Init(CLSID_WMAudioDecoderDMO,DMOCATEGORY_AUDIO_DECODER) ;
ASSERT(SUCCEEDED(hr)) ;
//将DMOWrapperFilter添加到FilterGraph
pGraphBuilder->AddFilter(pDmoFilter,L"WMA Decoder DMO") ;

//采用智能连接直接播放
hr = pGraphBuilder->RenderFile(argv[1],NULL);
	IMediaControl * pMediaControl = NULL ;
	IMediaEvent   *pEvent = NULL;
    if (SUCCEEDED(hr)) 
    { 

		hr = pGraphBuilder->QueryInterface(IID_IMediaControl,(void**)&pMediaControl);
		hr = pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

		//hr返回值为S_FALSE,但是仍然可以播放,暂时不知道原因
		hr = pMediaControl->Run() ; 

        if (SUCCEEDED(hr)) 
        { 
            // Wait for completion. 
            long evCode; 
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it 
            // can block indefinitely. 
        } 
    } 


    pMediaControl->Release(); 
    pEvent->Release(); 
    pGraphBuilder->Release(); 
    CoUninitialize(); 

//释放COM组件
::CoUninitialize() ;
}