www.pudn.com > 摄像头捕获C++类.rar > MyCapVideo.cpp


//MyCapVideo.cpp 
 
#include "stdafx.h" 
#include "MyCapVideo.h" 
#include  
 
#pragma  comment  (lib,  "Strmiids.lib")    
#pragma  comment  (lib,  "Quartz.lib")    
 
 
MyCapVideo::MyCapVideo() 
{ 
    CoInitialize(NULL); 
 
	pBuilder=NULL; 
	pFg=NULL; 
	pVCap=NULL; pACap=NULL; 
	pVCP=NULL ; pACP=NULL; //压缩 
	pAM=NULL; //Avi Muxer 
	pFW=NULL; //File Writter 
	pSink=NULL; 
 
	pRender=NULL; 
	pConfigAviMux=NULL; 
 
	pVW=NULL; 
	pMC=NULL; 
	pME=NULL; 
	pDF=NULL; 
	pVC=NULL; 
	pDlg=NULL; 
	pASC=NULL; // for audio cap 
	pVSC=NULL; // for video cap	  
 
	bGraphBuilt=false; 
 
	SetCapDevice(); 
	GetInterfaces(); 
} 
 
MyCapVideo::~MyCapVideo() 
{ 
 
	CloseInterfaces(); 
	CoUninitialize(); 
 
} 
 
HRESULT MyCapVideo::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))  
    { 
        // Use the ROTFLAGS_REGISTRATIONKEEPSALIVE to ensure a strong reference 
        // to the object.  Using this flag will cause the object to remain 
        // registered until it is explicitly revoked with the Revoke() method. 
        // 
        // Not using this flag means that if GraphEdit remotely connects 
        // to this graph and then GraphEdit exits, this object registration  
        // will be deleted, causing future attempts by GraphEdit to fail until 
        // this application is restarted or until the graph is registered again. 
        hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,  
                            pMoniker, pdwRegister); 
        pMoniker->Release(); 
    } 
 
    pROT->Release(); 
    return hr; 
} 
 
 
// Removes a filter graph from the Running Object Table 
void MyCapVideo::RemoveGraphFromRot(DWORD pdwRegister) 
{ 
    IRunningObjectTable *pROT; 
 
    if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))  
    { 
        pROT->Revoke(pdwRegister); 
        pROT->Release(); 
    } 
} 
 
void MyCapVideo::SetCapDevice() 
{ 
	this->pACap=NULL; 
	this->pACP=NULL; 
	this->pVCap=NULL; 
	this->pVCP=NULL; 
 
	EnumFilters(EnumAudioCapFilter,   SetAudioDevice); 
	EnumFilters(EnumAudioCompressFilter,   SetAudioCompress); 
 
	EnumFilters(EnumVideoCapFilter,   SetVideoDevice); 
	EnumFilters(EnumVideoCompressFilter,   SetVideoCompress); 
} 
 
bool SetAudioDevice(MyCapVideo *m_cap,IBaseFilter *pFilter,CString Name) 
{ 
	m_cap->pACap=pFilter; 
	return false; 
} 
 
bool SetAudioCompress(MyCapVideo *m_cap,IBaseFilter *pFilter,CString Name) 
{ 
	m_cap->pACP=pFilter; 
	 
	if(Name.Compare("MPEG Layer-3")==0) 
	{ 
		m_cap->pACP=pFilter; 
		return false; 
	} 
  
	if(Name.Compare("Windows Media Audio V2")==0) 
	{ 
		m_cap->pACP=pFilter; 
		return false; 
	} 
 
	return true; 
} 
 
bool SetVideoDevice(MyCapVideo *m_cap,IBaseFilter *pFilter,CString Name) 
{  
	m_cap->pVCap=pFilter; 
	return false; 
} 
 
bool SetVideoCompress(MyCapVideo *m_cap,IBaseFilter *pFilter,CString Name) 
{	 
	m_cap->pVCP=pFilter; 
 
	 
	if(Name.Left(4).Compare("DivX")==0) 
	{ 
		m_cap->pVCP=pFilter; 
		return false; 
	} 
 
	if(Name.Compare("ffdshow Video Codec")==0) 
	{ 
		m_cap->pVCP=pFilter; 
		return false; 
	} 
 
	if(Name.Compare("Microsoft Windows Media Video 9")==0) 
	{ 
		m_cap->pVCP=pFilter; 
		return false; 
	} 
 
	return true; 
} 
 
  
HRESULT MyCapVideo::GetInterfaces(void) 
{ 
 
	HRESULT hr; 
 
	bGraphBuilt=false; 
	CloseInterfaces(); 
 
	wCapFileSize=1;  //20M 
 
	// 创建CaptureGraphBuilder 
 	hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,  
        IID_ICaptureGraphBuilder2, (void **)&pBuilder); 
     
	if (FAILED(hr)) return hr; 
 
	//创建Filter Graph  
 	hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,  
        IID_IGraphBuilder, (void **)&pFg); 
 
	if (FAILED(hr)) return hr; 
 
	hr  = pBuilder->SetFiltergraph(pFg);	 
 
	if (FAILED(hr)) return hr; 
 
    //获得视频控制,窗口,事件接口 
    hr = pFg->QueryInterface(IID_IMediaControl,(LPVOID *) &pMC); 
    if (FAILED(hr))  return hr; 
 
    hr = pFg->QueryInterface(IID_IVideoWindow, (LPVOID *) &pVW); 
    if (FAILED(hr)) return hr; 
 
    hr = pFg->QueryInterface(IID_IMediaEvent, (LPVOID *) &pME); 
    if (FAILED(hr)) return hr; 
 
    // Set the window handle used to process graph events 
    //hr = g_pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0); 
 
    return hr;  
} 
  
 
void MyCapVideo::CloseInterfaces() 
{ 
 
	SAFE_RELEASE(pMC); 
    SAFE_RELEASE(pME); 
    SAFE_RELEASE(pVW); 
    SAFE_RELEASE(pFg); 
    SAFE_RELEASE(pBuilder); 
 
} 
 
 
HRESULT MyCapVideo::ConnectFilters(IBaseFilter* pUpFilter, IBaseFilter* pDownFilter) 
{ 
    if( !pUpFilter || !pDownFilter ) 
    { 
        return E_INVALIDARG; 
    } 
 
    // All the need pin & pin enumerator pointers 
    CComPtr  pEnumUpFilterPins ,  
                        pEnumDownFilterPins; 
 
    CComPtr   pUpFilterPin ,  
                    pDownFilterPin; 
  
 
    HRESULT hr = S_OK; 
 
    // Get the pin enumerators for both the filtera 
    hr = pUpFilter->EnumPins(&pEnumUpFilterPins);  
    if( FAILED( hr ) ) 
    { 
        return hr; 
    } 
 
    hr= pDownFilter->EnumPins(&pEnumDownFilterPins);  
    if( FAILED( hr ) ) 
    { 
        return hr; 
    } 
 
 
    // Loop on every pin on the Upstream Filter 
    BOOL bConnected = FALSE; 
    PIN_DIRECTION pinDir; 
    ULONG nFetched = 0; 
    //while(pUpFilterPin.Release( ), S_OK == pEnumUpFilterPins->Next(1, &pUpFilterPin, &nFetched) ) 
    while(S_OK == pEnumUpFilterPins->Next(1, &pUpFilterPin, &nFetched) ) 
    { 
        // Make sure that we have the output pin of the upstream filter 
        hr = pUpFilterPin->QueryDirection( &pinDir ); 
        if( FAILED( hr ) || PINDIR_INPUT == pinDir ) 
        { 
            continue; 
        } 
 
        // 
        // I have an output pin; loop on every pin on the Downstream Filter 
        // 
        //while(pDownFilterPin.Release( ), S_OK == pEnumDownFilterPins->Next(1, &pDownFilterPin, &nFetched) ) 
        while( S_OK == pEnumDownFilterPins->Next(1, &pDownFilterPin, &nFetched) ) 
        { 
            hr = pDownFilterPin->QueryDirection( &pinDir ); 
            if( FAILED( hr ) || PINDIR_OUTPUT == pinDir ) 
            { 
                continue; 
            } 
 
            // Try to connect them and exit if u can else loop more until you can 
            if(SUCCEEDED(pFg->ConnectDirect(pUpFilterPin, pDownFilterPin, NULL))) 
            { 
                bConnected = TRUE; 
                break; 
            } 
        } 
 
        hr = pEnumDownFilterPins->Reset(); 
        if( FAILED( hr ) ) 
        { 
            return hr; 
        } 
    } 
 
    if( !bConnected ) 
    { 
        return E_FAIL; 
    } 
 
    return S_OK; 
} 
  
int MyCapVideo::EnumFilters(EnumType enum_type, bool Visit(MyCapVideo *m_cap,IBaseFilter *,CString Name)) 
{ 
	HRESULT hr; 
    int nFilters=0; 
 
	ICreateDevEnum * m_pSysDevEnum=NULL; 
    IEnumMoniker *pEnumCat = NULL; 
    const CLSID *clsid; 
	IBaseFilter *pTmpFilter; 
 
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
                          CLSCTX_INPROC, IID_ICreateDevEnum,  
                          (void **)&m_pSysDevEnum); 
    if FAILED(hr) return nFilters; 
   
	switch(enum_type) 
	{ 
		case EnumAudioCapFilter: 
			clsid = &CLSID_AudioInputDeviceCategory; 
			break; 
		case EnumAudioCompressFilter: 
			clsid = &CLSID_AudioCompressorCategory; 
			break; 
		case EnumVideoCapFilter: 
			clsid = &CLSID_VideoInputDeviceCategory; 
			break; 
		case EnumVideoCompressFilter: 
			clsid = &CLSID_VideoCompressorCategory; 
			break; 
	} 
 
    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); 
    //ASSERT(SUCCEEDED(hr)); 
    if FAILED(hr) 
        return nFilters; 
 
    IMoniker *pMoniker; 
    ULONG cFetched; 
    VARIANT varName={0}; 
 
	// Enumerate all items associated with the moniker 
    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; 
 
        // Get filter name (converting BSTR name to a CString) 
        CString str(varName.bstrVal); 
        SysFreeString(varName.bstrVal); 
 
        // CLSID 没有用处都是一样的 
		/* 
        VARIANT varFilterClsid; 
        varFilterClsid.vt = VT_BSTR; 
		CLSID clsidFilter; 
 
        // Read CLSID string from property bag 
        hr = pPropBag->Read(L"CLSID", &varFilterClsid, 0); 
        if (FAILED(hr)) 
            continue; 
 
        if(CLSIDFromString(varFilterClsid.bstrVal, &clsidFilter) == S_FALSE) 
            continue; 
 
        CString clsid(varFilterClsid.bstrVal); 
        SysFreeString(varFilterClsid.bstrVal); 
		*/ 
 
        //得到Filter 
 		hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pTmpFilter); 
 
        if (FAILED(hr)) 
            continue; 
		 
        nFilters++; 
 
        // Cleanup interfaces 
        SAFE_RELEASE(pPropBag); 
        SAFE_RELEASE(pMoniker); 
 
		if(!Visit(this,pTmpFilter,str)) //=True 继续枚举 
		{ 
			return nFilters; 
		} 
		//if( MessageBox(0,str,"是否采用该音频输入设备",MB_YESNO|MB_ICONQUESTION)==IDYES) 
			//return nFilters; 
 
    } 
 
	return nFilters; 
} 
 
/* 
int MyCapVideo::EnumAudioCapFilters(IBaseFilter **pACap,CString &Name) 
{	HRESULT hr; 
    int nFilters=0; 
 
	ICreateDevEnum * m_pSysDevEnum=NULL; 
    IEnumMoniker *pEnumCat = NULL; 
    const CLSID *clsid; 
 
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
                          CLSCTX_INPROC, IID_ICreateDevEnum,  
                          (void **)&m_pSysDevEnum); 
    if FAILED(hr) return nFilters; 
   
    clsid = &CLSID_AudioInputDeviceCategory; 
   
    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); 
    ASSERT(SUCCEEDED(hr)); 
    if FAILED(hr) 
        return nFilters; 
 
    // Enumerate all filters using the category enumerator 
    //hr = EnumFilters(pEnumCat); 
 
    IMoniker *pMoniker; 
    ULONG cFetched; 
    VARIANT varName={0}; 
 
	// Enumerate all items associated with the moniker 
    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; 
 
        // Get filter name (converting BSTR name to a CString) 
        CString str(varName.bstrVal); 
        SysFreeString(varName.bstrVal); 
        nFilters++; 
		Name=str; 
 
 
	    VARIANT varFilterClsid; 
        varFilterClsid.vt = VT_BSTR; 
 
 		hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pACap); 
		 
        
        // Cleanup interfaces 
        SAFE_RELEASE(pPropBag); 
        SAFE_RELEASE(pMoniker); 
 
		if( MessageBox(0,str,"是否采用该音频输入设备",MB_YESNO|MB_ICONQUESTION)==IDYES) 
			return nFilters; 
 
    } 
 
    
	return nFilters; 
 
} 
 
int MyCapVideo::EnumAudioCompressFilters(IBaseFilter **pACP,CString &Name) 
{	HRESULT hr; 
    int nFilters=0; 
 
	ICreateDevEnum * m_pSysDevEnum=NULL; 
    IEnumMoniker *pEnumCat = NULL; 
    const CLSID *clsid; 
 
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
                          CLSCTX_INPROC, IID_ICreateDevEnum,  
                          (void **)&m_pSysDevEnum); 
    if FAILED(hr) return nFilters; 
   
    clsid = &CLSID_AudioCompressorCategory; 
   
    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); 
    ASSERT(SUCCEEDED(hr)); 
    if FAILED(hr) 
        return nFilters; 
 
    // Enumerate all filters using the category enumerator 
    //hr = EnumFilters(pEnumCat); 
 
    IMoniker *pMoniker; 
    ULONG cFetched; 
    VARIANT varName={0}; 
 
	// Enumerate all items associated with the moniker 
    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; 
 
        // Get filter name (converting BSTR name to a CString) 
        CString str(varName.bstrVal); 
        SysFreeString(varName.bstrVal); 
        nFilters++; 
		Name=str; 
 
 
	    VARIANT varFilterClsid; 
        varFilterClsid.vt = VT_BSTR; 
 
 		hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pACP); 
		 
        
        // Cleanup interfaces 
        SAFE_RELEASE(pPropBag); 
        SAFE_RELEASE(pMoniker); 
 
		if( MessageBox(0,str,"是否采用这种音频压缩方式",MB_YESNO|MB_ICONQUESTION)==IDYES) 
			return nFilters; 
 
    } 
 
    
	return nFilters; 
 
} 
 
 
 
 
int MyCapVideo::EnumVideoCapFilters(IBaseFilter **pVCap,CString &Name) 
{	HRESULT hr; 
    int nFilters=0; 
 
	ICreateDevEnum * m_pSysDevEnum=NULL; 
    IEnumMoniker *pEnumCat = NULL; 
    const CLSID *clsid; 
 
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
                          CLSCTX_INPROC, IID_ICreateDevEnum,  
                          (void **)&m_pSysDevEnum); 
    if FAILED(hr) return nFilters; 
   
    clsid = &CLSID_VideoInputDeviceCategory; 
   
    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); 
    ASSERT(SUCCEEDED(hr)); 
    if FAILED(hr) 
        return nFilters; 
 
    // Enumerate all filters using the category enumerator 
    //hr = EnumFilters(pEnumCat); 
 
    IMoniker *pMoniker; 
    ULONG cFetched; 
    VARIANT varName={0}; 
 
	// Enumerate all items associated with the moniker 
    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; 
 
        // Get filter name (converting BSTR name to a CString) 
        CString str(varName.bstrVal); 
        SysFreeString(varName.bstrVal); 
        nFilters++; 
		Name=str; 
 
 
	    VARIANT varFilterClsid; 
        varFilterClsid.vt = VT_BSTR; 
 
 		hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVCap); 
  
        // Cleanup interfaces 
        SAFE_RELEASE(pPropBag); 
        SAFE_RELEASE(pMoniker); 
 
		if( MessageBox(0,str,"是否采用该视频输入设备",MB_YESNO|MB_ICONQUESTION)==IDYES) 
			return nFilters; 
 
    } 
 
    
	return nFilters; 
 
} 
 
int MyCapVideo::EnumVideoCompressFilters(IBaseFilter **pVCP,CString &Name) 
{ 
	HRESULT hr; 
    int nFilters=0; 
 
	ICreateDevEnum * m_pSysDevEnum=NULL; 
    IEnumMoniker *pEnumCat = NULL; 
    const CLSID *clsid; 
 
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
                          CLSCTX_INPROC, IID_ICreateDevEnum,  
                          (void **)&m_pSysDevEnum); 
    if FAILED(hr) return nFilters; 
   
    clsid = &CLSID_VideoCompressorCategory; 
   
    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); 
    ASSERT(SUCCEEDED(hr)); 
    if FAILED(hr) 
        return nFilters; 
 
    // Enumerate all filters using the category enumerator 
    //hr = EnumFilters(pEnumCat); 
 
    IMoniker *pMoniker; 
    ULONG cFetched; 
    VARIANT varName={0}; 
 
	// Enumerate all items associated with the moniker 
    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; 
 
        // Get filter name (converting BSTR name to a CString) 
        CString str(varName.bstrVal); 
        SysFreeString(varName.bstrVal); 
        nFilters++; 
		Name=str; 
 
 
	    VARIANT varFilterClsid; 
        varFilterClsid.vt = VT_BSTR; 
 
 		hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVCP); 
		 
         
        // Cleanup interfaces 
        SAFE_RELEASE(pPropBag); 
        SAFE_RELEASE(pMoniker); 
		 
		if( MessageBox(0,str,"是否采用这种视频压缩方式",MB_YESNO |MB_ICONQUESTION)==IDYES) 
			return nFilters; 
 
    } 
 
    
	return nFilters; 
} 
*/ 
bool MyCapVideo::StopCapture() 
{ 
    if (pMC) 
        pMC->StopWhenReady(); 
 
	if (g_dwGraphRegister) 
        RemoveGraphFromRot(g_dwGraphRegister); 
 
    // Stop receiving events 
    //if (pME) 
       // pME->SetNotifyWindow(NULL, WM_GRAPHNOTIFY, 0); 
 
    // Relinquish ownership (IMPORTANT!) of the video window. 
    // Failing to call put_Owner can lead to assert failures within 
    // the video renderer, as it still assumes that it has a valid 
    // parent window. 
    if(pVW) 
    { 
        pVW->put_Visible(OAFALSE); 
        pVW->put_Owner(NULL); 
    } 
 
	return true; 
} 
 
bool MyCapVideo::CaptureToFile(LPTSTR AviFileName)  
{ 
	HRESULT hr; 
 
	if(!szCaptureFile) 
		return false; 
 
	if(!pVCap && !pACap) 
		return false; 
 
	if(!bGraphBuilt) 
	{ 
		//创建Avi Mux Filter 
 		hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC,  
			IID_IBaseFilter, (void **)&pAM); 
		hr = pFg->AddFilter(pAM, L"Avi Mixer Filter"); 
 
		//新建一个FileWriter 
 		hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC,  
			IID_IBaseFilter, (void **)&pFW); 
		hr = pFg->AddFilter(pFW, L"FileWriter Filter"); 
 
		pFW->QueryInterface(IID_IFileSinkFilter,(void **)&pSink); 
 
		//得到当前的Captuer Filter 
		pMC->Stop();	 
		hr = AddGraphToRot(pFg, &g_dwGraphRegister); 
 
		if(pVCap) hr = pFg->AddFilter(pVCap, L"Capture Filter"); 
		if(pVCP)  hr = pFg->AddFilter(pVCP, L"Compress Filter"); 
 		if(pACap) hr = pFg->AddFilter(pACap, L"Audio Capture Filter"); 
		if(pACP)  hr = pFg->AddFilter(pACP, L"Audio Compress Filter"); 
 
		//CFileDialog  dlg1(1); 
		//int ret=dlg1.DoModal(); 
		//CString f1=dlg1.GetPathName() ;	 
 
		if(pVCap && pVCP)	hr = ConnectFilters(pVCap,pVCP); 
		if(pVCP && pAM)		hr = ConnectFilters(pVCP,pAM); 
		if(pACap && pACP)	hr = ConnectFilters(pACap,pACP); 
		if(pACP && pAM)		hr = ConnectFilters(pACP,pAM); 
		if(pAM && pFW)		hr = ConnectFilters(pAM,pFW); 
 
	} 
 
	if(AviFileName) 
	{ 
		wsprintf(szCaptureFile,"%s",AviFileName); 
		WCHAR wach[_MAX_PATH]; 
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szCaptureFile, -1, wach,_MAX_PATH); 
 
		pSink->SetFileName(wach,NULL); 
	} 
 
	bGraphBuilt=true; 
   	pMC->Run(); 
	 
 	return true;	/* 
	//设置文件,分配文件空间 
 
 	 CFileDialog  dlg1(1); 
	 int ret=dlg1.DoModal(); 
	 CString f1=dlg1.GetPathName() ;	 
	//CString f1="d:\\test.avi"; 
 	if(!f1.IsEmpty()) 
	{ 
		wsprintf(szCaptureFile,"%s",f1.GetBuffer(f1.GetLength())); 
		WCHAR wach[_MAX_PATH]; 
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szCaptureFile, -1,	wach, _MAX_PATH); 
		if (pBuilder->AllocCapFile(wach,wCapFileSize*100) != NOERROR)  
			MessageBoxA( "Failed to pre-allocate capture file space", "Error",	MB_OK | MB_ICONEXCLAMATION); 
		else 
			TRACE("分配文件空间 Ok %s!\r\n",szCaptureFile); 
 
	} 
	else 
	{ 
		return; 
	} 
 
 
	//保存到文件 
  
 
	//建立Graph的渲染部分,并告诉他写文件(用先前决定的文件) 
	//strcpy(szCaptureFile,"d:\\test.avi"); 
 	WCHAR wach[_MAX_PATH]; 
	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szCaptureFile, -1, wach,_MAX_PATH); 
	GUID guid = MEDIASUBTYPE_Avi; 
	hr = pBuilder->SetOutputFileName(&guid, wach, &pAM,NULL); 
	 
	if (hr != NOERROR)  
	{ 
		AfxMessageBox("Error %x: Cannot set output file", hr); 
	} 
	else 
		TRACE("SetOutputFileName Ok %s!\r\n",szCaptureFile); 
 
	pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pVCap,NULL,pAM); 
 
	//pMux->Release(); 
	*/ 
 
}