⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capturevideo.cpp

📁 source file for video managment application
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// CaptureVideo.cpp : implementation file
//
//--------------------------------------------------------------------------//
// Copyright DILLIP KUMAR KARA 2004
// You may do whatever you want with this code, as long as you include this
// copyright notice in your implementation files.
// Comments and bug Reports: codeguru_bank@yahoo.com
//--------------------------------------------------------------------------//

#include "stdafx.h"
#include "LiveVideo.h"
#include "CaptureVideo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


HRESULT SaveGraphFile(IGraphBuilder *pGraph, WCHAR *wszPath) ;
IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir);
HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate);

/////////////////////////////////////////////////////////////////////////////
// CCaptureVideo

CCaptureVideo::CCaptureVideo()
{
	// Initialization 
	m_hApp=NULL;
	m_dwGraphRegister=0;
	nAnalogCount =0; // Counting Analog devices
	m_pVW = NULL;
	m_pMC = NULL;
	m_pME = NULL;
	m_pGraph = NULL;  // IFilterGraph2 provides AddSourceFileForMoniker()
	m_pCapture = NULL;
	pSrcF = NULL ;
	
	/// For Webcam
	m_pVWMoniker = NULL;
	m_pMCMoniker = NULL;
	m_pMEMoniker = NULL;
	m_pCaptureMoniker = NULL; 
	m_pFilterGraph = NULL;

}

CCaptureVideo::~CCaptureVideo()
{
}


BEGIN_MESSAGE_MAP(CCaptureVideo, CWnd)
	//{{AFX_MSG_MAP(CCaptureVideo)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CCaptureVideo message handlers
HRESULT CCaptureVideo::InitializeVideo(HWND hWnd)
{
	HRESULT hr = NULL ;
	m_hApp = hWnd ;
	bDevCheck = FALSE;
	nVSourceCount =0;
	vType = 0;  
	
	//COM Library Intialization
	if(FAILED(CoInitialize(NULL)))	/*, COINIT_APARTMENTTHREADED)))*/
    {
        AfxMessageBox("CoInitialize Failed!\r\n");   
        return hr ;
    }
	
	return hr ;
}

void CCaptureVideo::UnIntializeVideo()
{
	if( vType == 1) // If WebCam
		CloseInterfacesMoniker();
	CloseInterfaces(); 
	CoUninitialize();
	bVideo = FALSE;
}


HRESULT CCaptureVideo::GetInterfaces()
{
    HRESULT hr;
	
	if(m_pGraph == NULL){
		// Create the filter graph
		hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
							   IID_IGraphBuilder, (void **) &m_pGraph);
		if (FAILED(hr))
			return hr;
	}
	else
		return E_FAIL ;

	if(m_pCapture == NULL) {
		// Create the capture graph builder
		hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
							   IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
		if (FAILED(hr))
			return hr;
	}
	else
		return E_FAIL ;
    
    // Obtain interfaces for media control and Video Window
    hr = m_pGraph->QueryInterface(IID_IMediaControl,(LPVOID *) &m_pMC);
    if (FAILED(hr))
        return hr;
	
    hr = m_pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW);
    if (FAILED(hr))
        return hr;
	
    hr = m_pGraph->QueryInterface(IID_IMediaEvent, (LPVOID *) &m_pME);
    if (FAILED(hr))
        return hr;
	
    // Set the window handle used to process graph events
    hr = m_pME->SetNotifyWindow((OAHWND)m_hApp, WM_GRAPHNOTIFY, 0);
	
    return hr;
}











HRESULT CCaptureVideo::FindCaptureDevice(IBaseFilter **ppSrcFilter)
{
	HRESULT hr;
    IBaseFilter * pSrc = NULL;
    CComPtr <IMoniker> pMoniker =NULL;
    ULONG cFetched;
	
    if (!ppSrcFilter)
        return E_POINTER;
	
    // Create the system device enumerator  
    CComPtr <ICreateDevEnum> pDevEnum =NULL;
	
    hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           IID_ICreateDevEnum, (void **) &pDevEnum);
    if (FAILED(hr))
    {
        DisplayMesg(TEXT("Couldn't create system enumerator!  hr=0x%x"), hr);
        return hr;
    }
	
    // Create an enumerator for the video capture devices
    CComPtr <IEnumMoniker> pClassEnum = NULL;
	
    hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
    if (FAILED(hr))
    {
        DisplayMesg(TEXT("Couldn't create class enumerator!  hr=0x%x"), hr);
        return hr;
    }
	
    // If there are no enumerators for the requested type, then 
    // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
    if (pClassEnum == NULL)
    {
	   //       MessageBox(m_hApp,TEXT("No video capture device was detected.\r\n\r\n")
	   //                TEXT("This sample requires a video capture device, such as a USB WebCam,\r\n")
	   //                TEXT("to be installed and working properly.  The sample will now close."),
	   //                TEXT("No Video Capture Hardware"), MB_OK | MB_ICONINFORMATION);
	   return E_FAIL;
    }
	
    // Use the first video capture device on the device list.
    // Note that if the Next() call succeeds but there are no monikers,
    // it will return S_FALSE (which is not a failure).  Therefore, we
    // check that the return code is S_OK instead of using SUCCEEDED() macro.
    
	//To Find the Analog Capture Devices....
	
	BOOL         Found ;
	IPin        *pP = 0;
	IEnumPins   *pins=0;
	ULONG        n;
	PIN_INFO     pinInfo;
	Found	= FALSE;
	IKsPropertySet *pKs=0;
	GUID guid;
	DWORD dw;
	BOOL fMatch = FALSE;
	
	//while(S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
	if(S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
	{	
		// Bind Moniker to a filter object
		hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
		if (FAILED(hr))
		{
			DisplayMesg(TEXT("Couldn't bind moniker to filter object!  hr=0x%x"), hr);
			return hr;
		}
			 if(SUCCEEDED(pSrc->EnumPins(&pins)))
				{     
				 while(!Found && (S_OK == pins->Next(1, &pP, &n)))
					{
					 	vType ++;
						if(S_OK == pP->QueryPinInfo(&pinInfo))
						{

							if(pinInfo.dir == PINDIR_INPUT)
							{
								// is this pin an ANALOGVIDEOIN input pin?
								if(pP->QueryInterface(IID_IKsPropertySet,
									(void **)&pKs) == S_OK)
								{
									if(pKs->Get(AMPROPSETID_Pin,
										AMPROPERTY_PIN_CATEGORY, NULL, 0,
										&guid, sizeof(GUID), &dw) == S_OK)
									{
										if(guid == PIN_CATEGORY_ANALOGVIDEOIN)
											fMatch = TRUE;
									}
									pKs->Release();
								}

								if(fMatch)
								{
									Found = TRUE;
									bDevCheck = Found;
									break;
								}
							}
							pinInfo.pFilter->Release();
						}
						pP->Release();
					}
					pins->Release();
				}
  			}
 
    // Copy the found filter pointer to the output parameter.
    // Do NOT Release() the reference, since it will still be used
    // by the calling function.
	pSrcF = pSrc;
    *ppSrcFilter = pSrc;
	
    return hr;
}





// @@@@@@@@@@@

HRESULT CCaptureVideo::FindCaptureDeviceAudio(IBaseFilter** ppSrcFilter)
{
	HRESULT hr;
    IBaseFilter * pSrc = NULL;
    CComPtr <IMoniker> pMoniker =NULL;
    ULONG cFetched;
	
    if (!ppSrcFilter)
        return E_POINTER;
	
    // Create the system device enumerator  
    CComPtr <ICreateDevEnum> pDevEnum =NULL;
	
    hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           IID_ICreateDevEnum, (void **) &pDevEnum);
    if (FAILED(hr))
    {
        DisplayMesg(TEXT("Couldn't create system enumerator!  hr=0x%x"), hr);
        return hr;
    }
	
    // Create an enumerator for the @Audio@ capture devices
    CComPtr <IEnumMoniker> pClassEnum = NULL;
	
    hr = pDevEnum->CreateClassEnumerator (CLSID_AudioInputDeviceCategory/*CLSID_VideoInputDeviceCategory*/, &pClassEnum, 0);
    if (FAILED(hr))
    {
        DisplayMesg(TEXT("Couldn't create class enumerator!  hr=0x%x"), hr);
        return hr;
    }
	pClassEnum->Reset();
    // If there are no enumerators for the requested type, then 
    // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
    if (pClassEnum == NULL)
    {
	   //       MessageBox(m_hApp,TEXT("No video capture device was detected.\r\n\r\n")
	   //                TEXT("This sample requires a video capture device, such as a USB WebCam,\r\n")
	   //                TEXT("to be installed and working properly.  The sample will now close."),
	   //                TEXT("No Video Capture Hardware"), MB_OK | MB_ICONINFORMATION);
	   return E_FAIL;
    }
	
    // Use the first video capture device on the device list.
    // Note that if the Next() call succeeds but there are no monikers,
    // it will return S_FALSE (which is not a failure).  Therefore, we
    // check that the return code is S_OK instead of using SUCCEEDED() macro.
    
	//To Find the Analog Capture Devices....
	
	BOOL         Found ;
	IPin        *pP = 0;
	IEnumPins   *pins=0;
	ULONG        n;
	PIN_INFO     pinInfo;
	Found	= FALSE;
	IKsPropertySet *pKs=0;
	GUID guid;
	DWORD dw;
	BOOL fMatch = FALSE;
	
	//while(S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
	if(S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
	{	
		// Bind Moniker to a filter object
		hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
		if (FAILED(hr))
		{
			DisplayMesg(TEXT("Couldn't bind moniker to filter object!  hr=0x%x"), hr);
			return hr;
		}
			 if(SUCCEEDED(pSrc->EnumPins(&pins)))
				{     
				 while(!Found && (S_OK == pins->Next(1, &pP, &n)))
					{
					 	vType ++;
						if(S_OK == pP->QueryPinInfo(&pinInfo))
						{
							TRACE(CString("Name : ")+   pinInfo.achName );
							TRACE1(" DIR : %d" , pinInfo.dir);

							if(pinInfo.dir == PINDIR_INPUT)
							{
								// is this pin an ANALOGVIDEOIN input pin?
								if(pP->QueryInterface(IID_IKsPropertySet,
									(void **)&pKs) == S_OK)
								{
									if(pKs->Get(AMPROPSETID_Pin,
										AMPROPERTY_PIN_CATEGORY, NULL, 0,
										&guid, sizeof(GUID), &dw) == S_OK)
									{
										if(guid == PIN_CATEGORY_ANALOGVIDEOIN)
											fMatch = TRUE;
									}
									pKs->Release();
								}

								if(fMatch)
								{
									Found = TRUE;
									bDevCheck = Found;
									break;
								}
							}
							pinInfo.pFilter->Release();
						}
						pP->Release();
					}
					pins->Release();
				}
  			}
 
    // Copy the found filter pointer to the output parameter.
    // Do NOT Release() the reference, since it will still be used
    // by the calling function.
	pSrcF = pSrc;
    *ppSrcFilter = pSrc;
	
    return hr;
}

















HRESULT CCaptureVideo::SetupVideoWindow()
{
    HRESULT hr;
	
    // Set the video window to be a child of the main window
    hr = m_pVW->put_Owner((OAHWND)m_hApp);
    if (FAILED(hr))
        return hr;
    
    // Set video window style
    hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
    if (FAILED(hr))
        return hr;
	
	hr = m_pVW->put_Width(320) ;
	hr = m_pVW->put_Height(240) ;
	
    // Use helper function to position video window in client rect 
    // of main application window
    ResizeVideoWindow();
	
    // Make the video window visible, now that it is properly positioned
    hr = m_pVW->put_Visible(OATRUE);
    if (FAILED(hr))
        return hr;
	hr = m_pVW->put_MessageDrain((OAHWND)m_hApp);
    
	return hr;
}

HRESULT CCaptureVideo::ChangePreviewState(int nShow)
{
	HRESULT hr=S_OK;
    
    // If the media control interface isn't ready, don't call it
    if (!m_pMC)
        return S_OK;
    
    if (nShow)
    {
        if (m_psCurrent != RUNNING)
        {
            // Start previewing video data
            hr = m_pMC->Run();
            m_psCurrent = RUNNING;
        }
    }
    else
    {
        // Stop previewing video data
        hr = m_pMC->StopWhenReady();
        m_psCurrent = STOPPED;
    }

    return hr;
}

HRESULT CCaptureVideo::HandleGraphEvent()
{
    LONG evCode, evParam1, evParam2;
    HRESULT hr=S_OK;

    if (!m_pME)
        return E_POINTER;

    while(SUCCEEDED(m_pME->GetEvent(&evCode, (LONG_PTR *) &evParam1, 
                   (LONG_PTR *) &evParam2, 0)))
    {
        //
        // Free event parameters to prevent memory leaks associated with
        // event parameter data.  While this application is not interested
        // in the received events, applications should always process them.
        //
        hr = m_pME->FreeEventParams(evCode, evParam1, evParam2);
    }

    return hr;
}

HRESULT CCaptureVideo::CaptureVideo()
{
	HRESULT hr;
    IBaseFilter *pSrcFilter=NULL;
	IBaseFilter *pSrcAudioFilter=NULL;

    // Get DirectShow interfaces
    hr = GetInterfaces();
    if (FAILED(hr))
    {
        DisplayMesg(TEXT("Failed to get video interfaces!  hr=0x%x"), hr);
        return hr;
    }

    // Attach the filter graph to the capture graph
    hr = m_pCapture->SetFiltergraph(m_pGraph);
    if (FAILED(hr))
    {
        DisplayMesg(TEXT("Failed to set capture filter graph!  hr=0x%x"), hr);
        return hr;
    }

    // Use the system device enumerator and class enumerator to find
    // a video capture/preview device, such as a desktop USB video camera.

	hr = FindCaptureDevice(&pSrcFilter);
    if (FAILED(hr))
    {
        // Don't display a message because FindCaptureDevice will handle it
        return hr;
    }




// @@@@ 
	//hr = FindCaptureDeviceAudio(&pSrcAudioFilter);
 //   if (FAILED(hr))
 //   {
	//	 return hr;
	//}






	if(nAnalogCount == 0)
		AfxMessageBox("Capture device is not detected.!") ;
   
	if( bDevCheck == FALSE)
	{
		return E_FAIL;
	}


    // Add Capture filter to our graph.
    hr = m_pGraph->AddFilter(pSrcFilter, L"Video Capture");
    if (FAILED(hr))
    {
        DisplayMesg(TEXT("Couldn't add the capture filter to the graph!  hr=0x%x\r\n\r\n") 
            TEXT("If you have a working video capture device, please make sure\r\n")
            TEXT("that it is connected and is not being used by another application.\r\n\r\n"), hr);
        pSrcFilter->Release();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -