www.pudn.com > VideoSender.rar > Video.cpp


// Video.cpp: implementation of the CVideo class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "VideoSender.h" 
#include "Video.h" 
#pragma comment (lib ,"Quartz.lib") 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
#include  
#include  
 
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; } 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
//{CE3B76CB-9540-48FA-9974-69A625D478E3} 
DEFINE_GUID(CLSID_NetSource, 
0xCE3B76CB,0x9540,0x48FA,0x99,0x74,0x69,0xa6,0x25,0xd4,0x78,0xe3); 
DEFINE_GUID(CLSID_Divx, 
0x78766964,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71); 
//{D76E2820-1563-11CF-AC98-00AA004C0FA9}{D76E2820-1563-11CF-AC98-00AA004C0FA9} 
DEFINE_GUID(CLSID_EDivx, 
0xD76E2820,0x1563,0x11CF,0xAC,0x98,0x00,0xAA,0x00,0x4C,0x0F,0xA9); 
 
DEFINE_GUID(CLSID_IPMulticastSendProppage, 
0x3ec9c19, 0x13c4, 0x43d7, 0xb1, 0x83, 0x89, 0x5c, 0xb8, 0x9e, 0x76, 0x1c); 
//{0x1CB42CC8,0xD32C,0x4f73,{0x92,0x67,0xC1,0x14,0xDA,0x47,0x03,0x78}}; 
//DEFINE_GUID(IID_IVideoWindow, 
//0x56a868b4,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70); 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
DEFINE_GUID(CLSID_AVIDecopress, 
0xCF49D4E0, 0x1115, 0x11CE, 0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); 
//{CF49D4E0-1115-11CE-B03A-0020AF0BA770} 
DEFINE_GUID(CLSID_device, 
0x17CCA71B, 0xECD7, 0x11D0, 0xb9, 0x08, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96); 
//{17CCA71B-ECD7-11D0-B908-00A0C9223196} 
 
DEFINE_GUID(CLSID_DDivx, 
0x78766964,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71); 
//{CC58E280-8AA1-11D1-B3F1-00AA003761C5} 
DEFINE_GUID(CLSID_SMartTree, 
0xCC58E280,0x8AA1,0x11D1,0xb3,0xf1,0x00,0xAA,0x00,0x37,0x61,0xc5); 
 
//{D76E2820-1563-11CF-AC98-00AA004C0FA9} 
DEFINE_GUID(CLSID_Divx_4_Encoder, 
0xD76E2820,0x1563,0x11CF,0xAC,0x98,0x00,0xAA,0x00,0x4c,0x0f,0xa9); 
 
CVideo::CVideo() 
{ 
 
} 
 
CVideo::~CVideo() 
{ 
	RemoveGraphFromRot(dwRegister); 
} 
 
 
BOOL CVideo::Init() 
{ 
	HRESULT hr; 
	hr=CoInitialize(NULL); 
	if(S_OK!=hr) 
		return FALSE; 
	return TRUE; 
} 
 
BOOL CVideo::Run() 
{ 
	HRESULT hr; 
	hr=InitCaptureGraphBuilder(&pGraph,&pBuilder); 
	if(FAILED(hr)) return false; 
	ICreateDevEnum *pSysDevEnum=NULL; 
	hr=CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void **)&pSysDevEnum); 
	if(FAILED(hr)) 
		return false; 
	hr=AddGraphToRot(pGraph,&dwRegister); 
	IEnumMoniker *pEnumCat=NULL; 
	hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumCat,0); 
	if(hr==S_OK) 
	{ 
		IMoniker *pMoniker=NULL; 
		ULONG cFetched; 
		while(pEnumCat->Next(1,&pMoniker,&cFetched)==S_OK) 
		{ 
			IPropertyBag *pPropBag; 
			hr=pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void **)&pPropBag); 
			if(SUCCEEDED(hr)) 
			{ 
				VARIANT varName; 
				VariantInit(&varName); 
				hr=pPropBag->Read(L"FriendlyName",&varName,0); 
				if(SUCCEEDED(hr)) 
				{ 
		 
					//desplay the name 
				} 
				VariantClear(&varName); 
				hr=pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(void **)&Device); 
				pGraph->AddFilter(Device,L"video source"); 
				pPropBag->Release(); 
			} 
			pMoniker->Release(); 
		} 
		pEnumCat->Release(); 
	} 
	pSysDevEnum->Release(); 
 
///	IBaseFilter *avicompress,*Render,*DDcoder,*Tree,*DivxEncorder4; 
/*	hr=AddFilterByCLSID(pGraph,CLSID_AVIDecopress,L"AVI COMPRESS",&avicompress); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"add avi filter"); 
		return false; 
	} 
	hr=AddFilterByCLSID(pGraph,CLSID_VideoRenderer,L"Video Renderer",&Render); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"添加播放视频滤镜失败"); 
		return FALSE; 
	}*/ 
/*	IBaseFilter *te; 
	hr=AddFilterByCLSID(pGraph,CLSID_EDivx,L"Divx Video Codec V3",&te); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"add Encoder filter"); 
		return false; 
	} 
	SetDivxCompressorProp(te); 
/*	hr=AddFilterByCLSID(pGraph,CLSID_SMartTree,L"SMart Tree",&Tree); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"add Encoder filter"); 
		return false; 
	} 
*/ 
	hr=AddFilterByCLSID(pGraph,CLSID_NetSource,L"Divx Multicast Sender",&Sender); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"add sender filter"); 
		return false; 
	} 
/*	hr=AddFilterByCLSID(pGraph,CLSID_DDivx,L"Divx Decorder",&DDcoder); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"add sender filter"); 
		return false; 
	} 
*/	hr=AddFilterByCLSID(pGraph,CLSID_Divx_4_Encoder,L"Divx-4 Encorder",&ECoder); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"add sender filter"); 
		return false; 
	} 
	SetDivxCompressorProp(ECoder); 
//TEST 5.10 
 /*           IAMStreamConfig *pSC; 
                hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, 
                    &MEDIATYPE_Interleaved, gcap.pVCap, 
                    IID_IAMStreamConfig, (void **)&pSC); 
 
                if(hr != NOERROR) 
                    hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, 
                        &MEDIATYPE_Video, gcap.pVCap, 
                        IID_IAMStreamConfig, (void **)&pSC); 
 
                ISpecifyPropertyPages *pSpec; 
                CAUUID cauuid; 
 
                hr = pSC->QueryInterface(IID_ISpecifyPropertyPages, 
                    (void **)&pSpec); 
 
                if(hr == S_OK) 
                { 
                    hr = pSpec->GetPages(&cauuid); 
                    hr = OleCreatePropertyFrame(ghwndApp, 30, 30, NULL, 1, 
                        (IUnknown **)&pSC, cauuid.cElems, 
                        (GUID *)cauuid.pElems, 0, 0, NULL); 
 
                    // !!! What if changing output formats couldn't reconnect 
                    // and the graph is broken?  Shouldn't be possible... 
 
                    if(gcap.pVSC) 
                    { 
                        AM_MEDIA_TYPE *pmt; 
                        // get format being used NOW 
                        hr = gcap.pVSC->GetFormat(&pmt); 
 
                        // DV capture does not use a VIDEOINFOHEADER 
                        if(hr == NOERROR) 
                        { 
                            if(pmt->formattype == FORMAT_VideoInfo) 
                            { 
                                // resize our window to the new capture size 
                                ResizeWindow(HEADER(pmt->pbFormat)->biWidth, 
                                    abs(HEADER(pmt->pbFormat)->biHeight)); 
                            } 
                            DeleteMediaType(pmt); 
                        } 
                    } 
 
                    CoTaskMemFree(cauuid.pElems); 
                    pSpec->Release(); 
                } 
 
                pSC->Release(); 
	 
	IAMVfwCaptureDialogs *pvfdia=NULL; 
	hr=Device->QueryInterface(IID_IAMVfwCaptureDialogs,(void **)&pvfdia); 
	if(SUCCEEDED(hr)) 
	{ 
		hr=pvfdia->ShowDialog(VfwCaptureDialog_Source,NULL); 
	} 
	 
	 
	if(IsWDMCard(Device)) 
	{//vdm card 
		IAMStreamConfig *pConfig=NULL; 
		AfxMessageBox("vdm"); 
	} 
	else 
	{//vfm card 
		AfxMessageBox("vfm"); 
	} 
 
*/ 
	hr=ConnectFilters(pGraph,Device,ECoder); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"connect device and Tree"); 
		return false; 
	} 
//	hr=ConnectFilters(pGraph,Tree,ECoder); 
//	if(FAILED(hr)) 
//	{ 
//		ShowErrMsg(hr,"connect Tree and ECoder"); 
//		return false; 
//	} 
//	hr=ConnectFilters(pGraph,avicompress,DDcoder); 
//	if(FAILED(hr)) 
//	{ 
//		ShowErrMsg(hr,"connect ECoder and Sender"); 
//		return false; 
//	}	 
//	hr=ConnectFilters(pGraph,DDcoder,avicompress); 
//	if(FAILED(hr)) 
//	{ 
//		ShowErrMsg(hr,"connect Tree and avicompress"); 
//		return false; 
//	} 
	hr=ConnectFilters(pGraph,ECoder,Sender); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"connect avicompress and Render"); 
		return false; 
	} 
 
	DisplayPropertyPage("Divx Multicast Sender",false); 
	hr=pGraph->QueryInterface(IID_IMediaControl,(void **)&pControl); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"播放控制滤镜加载失败");		 
		return FALSE; 
	} 
	hr=pControl->Pause (); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"control filter run"); 
		return false; 
	} 
	return TRUE; 
} 
 
HRESULT CVideo::AddFilterByCLSID(IGraphBuilder *pGraph,const GUID &clsid,LPCWSTR wszName,IBaseFilter **ppF) 
{ 
	if(!pGraph ||!ppF) return E_POINTER; 
	*ppF=0; 
	IBaseFilter *pF=0; 
	HRESULT hr=CoCreateInstance(clsid,0,CLSCTX_INPROC_SERVER,IID_IBaseFilter,reinterpret_cast(&pF)); 
	if(SUCCEEDED(hr)) 
	{ 
		hr=pGraph->AddFilter(pF,wszName); 
		if(SUCCEEDED(hr)) 
			*ppF=pF; 
		else 
			pF->Release(); 
	} 
	return hr; 
} 
 
HRESULT CVideo::GetUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin) 
{ 
	*ppPin=0; 
	IEnumPins *pEnum=0; 
	IPin *pPin=0; 
	HRESULT hr=pFilter->EnumPins(&pEnum); 
	if(FAILED(hr))return hr; 
	while(pEnum->Next(1,&pPin,NULL)==S_OK) 
	{ 
		PIN_DIRECTION ThisPinDir; 
 
		pPin->QueryDirection(&ThisPinDir); 
		if(ThisPinDir==PinDir) 
		{ 
			IPin *pTmp=0; 
			hr=pPin->ConnectedTo(&pTmp); 
			if(SUCCEEDED(hr)) 
				pTmp->Release(); 
			else 
			{ 
				pEnum->Release(); 
				*ppPin=pPin; 
				return S_OK; 
			} 
		} 
		pPin->Release(); 
	} 
	pEnum->Release(); 
	return E_FAIL; 
} 
 
HRESULT CVideo::ConnectFilters(IGraphBuilder *pGraph, IPin *pOut, IBaseFilter *pDest) 
{ 
	if((pGraph==NULL)||(pOut==NULL)||(pDest==NULL)) return E_POINTER; 
	IPin *pIn=0; 
	HRESULT hr=GetUnconnectedPin(pDest,PINDIR_INPUT,&pIn); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"df"); 
		return hr; 
	} 
	PIN_INFO pof,pif; 
	pOut->QueryPinInfo(&pof); 
	pIn->QueryPinInfo(&pif); 
	hr=pGraph->Connect(pOut,pIn); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"df"); 
		return hr; 
	} 
	pIn->Release(); 
	return hr; 
} 
 
HRESULT CVideo::ConnectFilters(IGraphBuilder *pGraph, IBaseFilter *pSrc, IBaseFilter *pDest) 
{ 
	if((pGraph==NULL)||(pSrc==NULL)||(pDest==NULL)) return E_POINTER; 
	IPin *pOut=0; 
	HRESULT hr=GetUnconnectedPin(pSrc,PINDIR_OUTPUT,&pOut); 
	if(FAILED(hr)) 
		return hr; 
/*	//test begin 
	PIN_INFO pin_info; 
	FILTER_INFO filter_info; 
	pOut->QueryPinInfo(&pin_info); 
	CString msg,str1,str2; 
	str1.Format("Source Pin%s",pin_info.achName); 
	pDest->QueryFilterInfo(&filter_info); 
	str2.Format("connect with filter:%s",filter_info.achName); 
	msg=str1+str2; 
	AfxMessageBox(msg); 
	//test end 
*/	hr=ConnectFilters(pGraph,pOut,pDest); 
	if(FAILED(hr)) 
	{ 
		ShowErrMsg(hr,"df"); 
		return hr; 
	} 
	pOut->Release(); 
	return hr; 
} 
 
 
void CVideo::ShowProperPage() 
{ 
	DisplayPropertyPage("Divx Multicast Sender",false); 
} 
 
HRESULT CVideo::SetDivxCompressorProp(IBaseFilter *pFilter) 
{ 
/*	HRESULT hr = S_OK; 
	ISpecifyPropertyPages *pProp = NULL; 
	hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pProp); 
    if (SUCCEEDED(hr))  
    { 
        // Get the filter's name and IUnknown pointer. 
        FILTER_INFO FilterInfo; 
        hr = pFilter->QueryFilterInfo(&FilterInfo);  
        IUnknown *pFilterUnk; 
        pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk); 
 
        // Show the page.  
        CAUUID caGUID; 
        pProp->GetPages(&caGUID); 
        pProp->Release(); 
        OleCreatePropertyFrame( 
            NULL,                   // Parent window 
            0, 0,                   // Reserved 
            FilterInfo.achName,     // Caption for the dialog box 
            1,                      // Number of objects (just the filter) 
            &pFilterUnk,            // Array of object pointers.  
            caGUID.cElems,          // Number of property pages 
            caGUID.pElems,          // Array of property page CLSIDs 
            0,                      // Locale identifier 
            0, NULL                 // Reserved 
        ); 
 
        // Clean up. 
        pFilterUnk->Release(); 
        FilterInfo.pGraph->Release();  
        CoTaskMemFree(caGUID.pElems); 
	} 
	return hr; 
	*/ 
/*	IAMVfwCompressDialogs *pDivxSet; 
	HRESULT hr = pFilter->QueryInterface(IID_IAMVfwCompressDialogs, (void **)&pDivxSet); 
 
	hr =pDivxSet->ShowDialog(VfwCompressDialog_Config,NULL); 
	if(FAILED(hr)) 
		AfxMessageBox("falild"); 
	pDivxSet->Release();  
 
	 
	IAMVideoCompression *pVideoCom; 
	WCHAR ver[20]; 
	int version; 
	WCHAR pDescription[40]; 
	int de; 
	long Keframrate; 
	long dkeframrate; 
	double qulity; 
	long capli; 
	HRESULT hr=pFilter->QueryInterface(IID_IAMVideoCompression,(void **)&pVideoCom); 
	if(SUCCEEDED(hr)) 
	{ 
			hr=pVideoCom->GetInfo(ver,&version,pDescription,&de,&Keframrate,&dkeframrate,&qulity,&capli); 
			 
 
	} 
	else 
	{ 
		ShowErrMsg(hr,"sow"); 
	} 
	return hr; 
 
 
  */ 
	IEnumPins *pEnum=NULL; 
	IPin *pPin=NULL; 
	HRESULT hr; 
	IAMVideoCompression *pCompress=NULL; 
	pFilter->EnumPins(&pEnum); 
	while(S_OK==pEnum->Next(1,&pPin,NULL)) 
	{ 
		hr = pPin->QueryInterface(IID_IAMVideoCompression, (void**)&pCompress); 
		pPin->Release(); 
		if (SUCCEEDED(hr)) // Found the interface. 
		{ 
			 break; 
		} 
	} 
	if(SUCCEEDED(hr)) 
	{ 
		long ICap; 
		long IKeyFrame,IPFrame; 
		double m_Quality; 
		long IKeyFrameDef,IPFrameDef; 
		double QualityDef; 
 
		hr = pCompress->GetInfo(0, 0, 0, 0, &IKeyFrameDef, &IPFrameDef, 
              &QualityDef, &ICap); 
		 if (SUCCEEDED(hr)) 
		 { 
			 if (ICap & CompressionCaps_CanKeyFrame) 
			 { 
				 hr = pCompress->get_KeyFrameRate(&IKeyFrame); 
				 if (FAILED(hr) || IKeyFrame < 0) 
					 IKeyFrame = IKeyFrameDef; 
				 hr=pCompress->put_KeyFrameRate(5); 
			 } 
			 if (ICap & CompressionCaps_CanBFrame) 
			 { 
				 hr = pCompress->get_PFramesPerKeyFrame(&IPFrame); 
				 if (FAILED(hr) || IPFrame < 0) 
					 IPFrame = IPFrameDef; 
			 } 
			 if (ICap & CompressionCaps_CanQuality) 
			 { 
				 hr = pCompress->get_Quality(&m_Quality); 
				 if (FAILED(hr) || m_Quality < 0) 
					 m_Quality = QualityDef; 
			 } 
		 } 
	} 
	return hr; 
} 
IBaseFilter* CVideo::FindFilterFromName(const char *pszFilterName) 
{ 
    IEnumFilters    *pEnum      = NULL; 
    IBaseFilter     *pFilter    = NULL; 
    ULONG           cFetched; 
    bool            bFound      = false; 
    DWORD hr; 
    hr=pGraph->EnumFilters(&pEnum); 
    if(FAILED(hr)) return NULL; 
    while((pEnum->Next(1, &pFilter, &cFetched) == S_OK) && (!bFound)) 
    { 
        FILTER_INFO FilterInfo; 
        char szName[_MAX_PATH]; 
        hr=pFilter->QueryFilterInfo(&FilterInfo); 
        if(FAILED(hr)) 
        { 
            pFilter->Release(); 
            pEnum->Release(); 
            return NULL; 
        } 
        WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName, -1, szName, _MAX_PATH, 0, 0); 
        if(! lstrcmp(szName, pszFilterName)) 
            bFound = true; 
 
        FilterInfo.pGraph->Release(); 
        if(!bFound) 
            pFilter->Release(); 
        else 
            break; 
    } 
    pEnum->Release(); 
    return (bFound ? pFilter : NULL); 
} 
 
 
bool CVideo::DisplayPropertyPage(const char *pszFilterName, bool test) 
{ 
    HRESULT                 hr; 
    IBaseFilter             * pFilter = NULL; 
    ISpecifyPropertyPages   * pSpecify; 
    bool                    bReturn = false; 
    pFilter = FindFilterFromName(pszFilterName); 
    if(!pFilter) 
        return false; 
    hr=pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void**) &pSpecify); 
    if(SUCCEEDED(hr)) 
    { 
        bReturn = true; 
        do 
        { 
            FILTER_INFO FilterInfo; 
            hr=pFilter->QueryFilterInfo(&FilterInfo); 
            if(FAILED(hr)) 
            { 
                bReturn = false; 
                break; 
            } 
            CAUUID caGUID; 
            hr=pSpecify->GetPages(&caGUID); 
            if(FAILED(hr)) 
            { 
                bReturn = false; 
                break;           
            } 
            pSpecify->Release(); 
            if(test==false) 
            { 
                HWND  m_hWnd= GetForegroundWindow(); 
                CString str; 
				str="IDS_STRING_PROPERTY_TITLE"; 
                SetActiveWindow(m_hWnd); 
 
                OleCreatePropertyFrame( 
                    m_hWnd,    //NULL,// Parent window 
                    0,                      // (Reserved) 
                    0,                      // (Reserved) 
                    CComBSTR(str),//FilterInfo.achName,     // Caption for the dialog box 
                    1,                      // Number of filters 
                    (IUnknown**)&pFilter,   // Pointer to the filter 
                    1,//caGUID.cElems, //         // Number of property pages 
                    caGUID.pElems,          // Pointer to property page CLSIDs 
                    0,                      // Locale identifier 
                    0,                      // Reserved 
                    NULL                    // Reserved 
                ); 
            } 
            CoTaskMemFree(caGUID.pElems); 
            FilterInfo.pGraph->Release(); 
        }while(0); 
    } 
    pFilter->Release(); 
    return bReturn; 
} 
void CVideo::ShowErrMsg(HRESULT hr,CString str) 
{ 
	TCHAR szErr[256]; 
	CString msg,errmsg; 
    DWORD res = AMGetErrorText(hr, szErr, 256); 
    if (res == 0) 
    { 
        AfxMessageBox(szErr); 
    } 
  	errmsg.Format("错误原因为:%s",szErr); 
	msg=str+errmsg; 
	AfxMessageBox(msg); 
} 
 
void CVideo::Unload() 
{ 
	CoUninitialize(); 
} 
 
void CVideo::RunVideo() 
{ 
	pControl->Run(); 
} 
void CVideo::OnSelchangeListDevices()  
{ 
    HRESULT hr;     
    IEnumMoniker *pEnumCat = NULL; 
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
                          CLSCTX_INPROC, IID_ICreateDevEnum,  
                          (void **)&m_pSysDevEnum); 
    if FAILED(hr) 
    { 
        CoUninitialize(); 
        return ; 
    } 
    hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); 
    ASSERT(SUCCEEDED(hr)); 
    if FAILED(hr) 
        return; 
    hr = EnumFilters(pEnumCat); 
 
} 
 
 
HRESULT CVideo::EnumFilters(IEnumMoniker *pEnumCat) 
{ 
    HRESULT hr=S_OK; 
    IMoniker *pMoniker; 
    ULONG cFetched; 
    VARIANT varName={0}; 
    int nFilters=0; 
    if (!pEnumCat) 
    { 
         return S_FALSE; 
    } 
    while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) 
    { 
        IPropertyBag *pPropBag; 
        ASSERT(pMoniker); 
        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,  
                                    (void **)&pPropBag); 
        ASSERT(SUCCEEDED(hr)); 
        ASSERT(pPropBag); 
        if (FAILED(hr)) 
            continue; 
        varName.vt = VT_BSTR; 
        hr = pPropBag->Read(L"FriendlyName", &varName, 0); 
        if (FAILED(hr)) 
            continue; 
        CString str(varName.bstrVal); 
        SysFreeString(varName.bstrVal); 
        nFilters++; 
 
        VARIANT varFilterClsid; 
        varFilterClsid.vt = VT_BSTR; 
        hr = pPropBag->Read(L"CLSID", &varFilterClsid, 0); 
        if(SUCCEEDED(hr)) 
        { 
            CLSID clsidFilter; 
            if(CLSIDFromString(varFilterClsid.bstrVal, &clsidFilter) == S_OK) 
            { 
				IBaseFilter *temp,*Render,*avi; 
				hr=AddFilterByCLSID(pGraph,CLSID_device,L"source",&temp); 
				hr=AddFilterByCLSID(pGraph,CLSID_AVIDecopress,L"Divx Multicast Sender",&avi); 
				hr=AddFilterByCLSID(pGraph,CLSID_VideoRenderer,L"Video Renderer",&Render); 
				hr=ConnectFilters(pGraph,temp,avi); 
				hr=ConnectFilters(pGraph,avi,Render); 
            } 
 
            SysFreeString(varFilterClsid.bstrVal); 
        } 
        SAFE_RELEASE(pPropBag); 
        SAFE_RELEASE(pMoniker); 
    } 
 
    return hr; 
} 
 
 
BOOL CVideo::IsWDMCard(IBaseFilter *pDeviceFilter) 
{ 
	IAMVfwCaptureDialogs *pVfw=NULL; 
	HRESULT hr=pDeviceFilter->QueryInterface(IID_IAMVfwCaptureDialogs,(void **)&pVfw); 
	if(SUCCEEDED(hr)) 
	{ 
		pVfw->Release(); 
		return false; 
	} 
	else 
	{ 
		IAMAnalogVideoDecoder *pWdm=NULL; 
		pDeviceFilter->QueryInterface(IID_IAMAnalogVideoDecoder,(void **)&pWdm); 
		if(SUCCEEDED(hr)) 
		{ 
			pWdm->Release(); 
			return true; 
		} 
		else 
		{ 
			return false; 
		} 
	} 
	return false; 
} 
HRESULT CVideo::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
{ 
    IMoniker * pMoniker; 
    IRunningObjectTable *pROT; 
    WCHAR wsz[128]; 
    HRESULT hr; 
 
    if (!pUnkGraph || !pdwRegister) 
        return E_POINTER; 
 
    if(FAILED(GetRunningObjectTable(0, &pROT))) 
        return E_FAIL; 
 
    wsprintfW(wsz, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph,  
        GetCurrentProcessId()); 
 
    hr = CreateItemMoniker(L"!", wsz, &pMoniker); 
    if(SUCCEEDED(hr)) 
    { 
        hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,  
                            pMoniker, pdwRegister); 
        pMoniker->Release(); 
    } 
 
    pROT->Release(); 
    return hr; 
} 
void CVideo::RemoveGraphFromRot(DWORD pdwRegister) 
{ 
    IRunningObjectTable *pROT; 
 
    if(SUCCEEDED(GetRunningObjectTable(0, &pROT))) 
    { 
        pROT->Revoke(pdwRegister); 
        pROT->Release(); 
    } 
} 
HRESULT CVideo::InitCaptureGraphBuilder(IGraphBuilder **ppGraph,ICaptureGraphBuilder2 **ppBuild) 
{ 
	if(!ppGraph ||!ppBuild) 
		return E_POINTER; 
	IGraphBuilder *pGraph=NULL; 
	ICaptureGraphBuilder2 *pBuild=NULL; 
	HRESULT	hr=CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC_SERVER,IID_ICaptureGraphBuilder2,(void**)&pBuild); 
	if(SUCCEEDED(hr)) 
	{ 
		hr=CoCreateInstance(CLSID_FilterGraph,0,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void**)&pGraph); 
		if(SUCCEEDED(hr)) 
		{ 
			pBuild->SetFiltergraph(pGraph); 
			*ppBuild=pBuild; 
			*ppGraph=pGraph; 
			return S_OK; 
		} 
		else 
		{ 
			pBuild->Release(); 
		} 
	} 
	return hr; 
} 
 
void CVideo::ShowPinProperty() 
{ 
	IAMStreamConfig *pSC; 
	pControl->Stop(); 
	HRESULT hr = pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, 
                    &MEDIATYPE_Interleaved, Device, 
                    IID_IAMStreamConfig, (void **)&pSC); 
	if(FAILED(hr)) 
	{ 
		hr = pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, 
                        &MEDIATYPE_Video, Device, 
                        IID_IAMStreamConfig, (void **)&pSC); 
		ISpecifyPropertyPages *pSpec; 
        CAUUID cauuid; 
 
        hr = pSC->QueryInterface(IID_ISpecifyPropertyPages, 
            (void **)&pSpec); 
 
        if(hr == S_OK) 
        { 
            hr = pSpec->GetPages(&cauuid); 
            hr = OleCreatePropertyFrame(NULL, 30, 30, NULL, 1, 
                (IUnknown **)&pSC, cauuid.cElems, 
                (GUID *)cauuid.pElems, 0, 0, NULL); 
		} 
		CoTaskMemFree(cauuid.pElems); 
            pSpec->Release(); 
				pSC->Release(); 
	} 
	else 
	{ 
		ShowErrMsg(hr,"show pin properpage"); 
		pControl->Run(); 
		return ; 
	} 
//	pControl->Run(); 
} 
 
void CVideo::ShowFilterProperty() 
{ 
	ISpecifyPropertyPages *pSpec; 
	CAUUID cauuid; 
	pControl->Stop(); 
	HRESULT hr=Device->QueryInterface(IID_ISpecifyPropertyPages,(void**)&pSpec); 
	if(SUCCEEDED(hr)) 
	{ 
		hr=pSpec->GetPages(&cauuid); 
		hr=OleCreatePropertyFrame(NULL,20,20,NULL,1,(IUnknown **)&Device,cauuid.cElems, 
				(GUID *)cauuid.pElems,0,0,NULL); 
		CoTaskMemFree(cauuid.pElems); 
                    pSpec->Release(); 
	} 
//	pControl->Run(); 
} 
 
void CVideo::Pause() 
{ 
	pControl->Pause(); 
} 
 
void CVideo::ShowSenderProperty() 
{ 
	DisplayPropertyPage("Divx Multicast Sender",false); 
}