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

📄 capturevideo.cpp

📁 足球机器人功能demo
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-------------------------------------------------------------------
// CCaptureVideo视频捕捉类实现文件CaptureVideo.cpp
//-------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CaptureVideo.h"
#include <windows.h>
#include <io.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//CSampleGrabberCB mCB;


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCaptureVideo::CCaptureVideo()
{
    //COM Library Intialization
    if(FAILED(CoInitialize(NULL))) /*, COINIT_APARTMENTTHREADED)))*/
    {
		AfxMessageBox("COM初始化失败!\r\n"); 
		return;
    }
    m_hPreviewWnd = NULL;
    m_pVW = NULL;
    m_pMC = NULL;
    m_pGB = NULL;
    m_pCapture = NULL;
	m_bCapStatus = false;
	m_strVideoFile.Format(".\\video.avi");

	char *pbuff=new char[255];
	GetCurrentDirectory(255,pbuff);
	m_strBaseDir = pbuff;
	delete   []pbuff;
	pbuff = NULL;
}

CCaptureVideo::~CCaptureVideo()
{
    //停止回放
    if(m_pMC)m_pMC->Stop();
    if(m_pVW)
	{
    m_pVW->put_Visible(OAFALSE);
    m_pVW->put_Owner(NULL);
    }
	if(!m_bCapStatus)
		return;

	if (NULL!=m_pCapture)
	{	
		m_pCapture->Release();	
		m_pCapture = NULL;	
	}
	if (NULL!=m_pMC)
	{
		m_pMC->Release();	
		m_pMC = NULL;	
	}
	if (NULL!=m_pGB)
	{	
		m_pGB->Release();	
		m_pGB = NULL;	
	}
	if (NULL!=m_pBF)
	{	
		m_pBF->Release();	
		m_pBF = NULL;	
	}
	//CoUninitialize();
}

//枚举摄像设备,并将名称添加到list框里
int CCaptureVideo::EnumDevices(HWND hList)
{
    if(!hList)
    return -1;
    int id = 0;

    //枚举视频扑捉设备(这次枚举是为了往list框里添加名称,后边使用时得再次枚举)
    ICreateDevEnum *pCreateDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);

    if (hr != NOERROR)
		return -1;
    CComPtr<IEnumMoniker> pEm;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);

    if (hr != NOERROR)
		return -1;
    pEm->Reset();
    ULONG cFetched;
    IMoniker *pM;
    while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
    {
		IPropertyBag *pBag;
		hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
		if(SUCCEEDED(hr)) 
		{
			VARIANT var;
			var.vt = VT_BSTR;
			hr = pBag->Read(L"FriendlyName", &var, NULL);
			if (hr == NOERROR) 
			{
					TCHAR str[2048]; 
					id++;
					WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);
					::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);//向界面列表框添加视频设备
					SysFreeString(var.bstrVal);
			}
			pBag->Release();
		}
		pM->Release();
    }
    return id;
}

HRESULT CCaptureVideo::Create(int iDeviceID, CStatic* inpPrev , int nMode)
{
	if (inpPrev != NULL)
	{
		m_hPreviewWnd = inpPrev->GetSafeHwnd();
	}

	if (nMode == 1)
	{
		SetCurrentDirectory(m_strBaseDir);
		SetCurrentDirectory(m_strCurDir);
		//确定视频捕捉文件名
		char FileBuf[20];
		for(int i=0;i<65535;i++)
		{	//试探是否已存在捕捉文件
			sprintf(FileBuf,"Video%05d.AVI",i);
			if((access(FileBuf,0)) == -1)
			break;
		}
		m_strVideoFile = FileBuf;
	}

	//使用m_bCapStatus标记防止重复初始化出错,true表示曾经初始化
	if(m_bCapStatus)
		return NULL;

	//初始化CaptureGraph
	HRESULT hr;
    hr = InitCaptureGraphBuilder();   
    if (FAILED(hr))
	{
		AfxMessageBox("获取视频捕捉接口失败!");
		return hr;
    }

    //将m_pBF绑定到摄像头设备上,添加到graph里
    if(!BindFilter(iDeviceID, &m_pBF))
	{
		AfxMessageBox("绑定视频设备失败!");
		return S_FALSE;
	}

    hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");
	if (FAILED(hr))
	{
		AfxMessageBox("Capture Filter添加失败!");
	}

    //创建一个sample grabber
    hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
    if( !m_pGrabber )
	{
        AfxMessageBox("创建SampleGrabber Filter失败,请确认qedit.dll是否已注册");
        return hr;
    }
	//将指针转化到标准参数
    CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber );

    //设置视频格式
    AM_MEDIA_TYPE mt; 
    ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype = MEDIATYPE_Video;
    mt.subtype = MEDIASUBTYPE_RGB24;
	//将媒体格式设置到m_pGrabber
    hr = m_pGrabber->SetMediaType(&mt);

    if( FAILED( hr ) )
	{
        AfxMessageBox("设置媒体类型失败");
        return hr;
    }

	//往graph添加grabberfilter,截图
    hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
    if( FAILED( hr ) )
	{
        AfxMessageBox("尝试将grabberfilter加入Graph失败!");
        return hr;
    }

	/*/枚举系统中的压缩编码filter
	CComPtr <IBaseFilter> pCompFilter;
	GetCompFilter(&pCompFilter);
	if (!pCompFilter)
		return false;
	
	//向graph中添加压缩编码filter
	hr = m_pGB->AddFilter( pCompFilter, L"Compress" );
	if( FAILED( hr ) )
	{
        return false;
	}*/

	//AVI文件filter
	CComPtr< IBaseFilter > pMux;
    CComPtr< IFileSinkFilter > pSink;
    USES_CONVERSION;
	if (nMode)
	{
		hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,  T2W( m_strVideoFile.GetBuffer(m_strVideoFile.GetLength()) ), 
		&pMux, &pSink );
		if( FAILED( hr ) )
		 {
			AfxMessageBox( TEXT("创建Mux and Writer Filter失败!"));
			return false;
		 }
	}

    //智能连接preview pin
    hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
    if( FAILED( hr ) )
	{
		AfxMessageBox("Preview Pin连接失败!");
		return hr;
	}

	//根据模式标记进行Capture Pin 的连接
	switch(nMode)
	{
	case 0:
		break;
	case 1:
		hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,NULL,pMux);
		break;
	case 2:
		//hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pCompFilter,pMux); 
		break;
	default :
		break;
	}
    
    if( FAILED( hr ) )
	{
        AfxMessageBox("Capture Pin 连接失败!");
            return hr;
    }
    
	//从Grabber提取媒体格式
    hr = m_pGrabber->GetConnectedMediaType( &mt );
    if ( FAILED(hr) )
	{
        AfxMessageBox("Grabber Filter获取视频参数失败!");
        return hr;
    }

	//设置截图缓冲区大小
    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;	
    mCB.lWidth = vih->bmiHeader.biWidth;
    mCB.lHeight = vih->bmiHeader.biHeight;
    FreeMediaType(mt);
	
    hr = m_pGrabber->SetBufferSamples( FALSE );//不再另外开辟单桢缓冲区
    hr = m_pGrabber->SetOneShot( FALSE );//截图后继续运行graph
    hr = m_pGrabber->SetCallback( &mCB, 1 );////设置回调函数,0=SampleCb,1=BufferCb

    //设置视频预览窗口
	if (m_hPreviewWnd != NULL)
	{		
		SetupVideoWindow();
	}
	
	//开始运行
    hr = m_pMC->Run();

	HWND h;
	h = ::FindWindow(NULL,"XviD Status");
	::PostMessage(h,WM_CLOSE,NULL,NULL);
	
    if(FAILED(hr))
	{
		AfxMessageBox("启动graph失败!");
		return hr;
	}
    return S_OK;
}

bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter)	//参数一是枚举到的序号,参数二是要绑定的指针
{
    if (deviceId < 0)
    return false;

    //枚举视频输入设备
    CComPtr<ICreateDevEnum> pCreateDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
    if (hr != NOERROR)
    {
        return false;
    }
    CComPtr<IEnumMoniker> pEm;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
    if (hr != NOERROR) 
    {
        return false;
    }

⌨️ 快捷键说明

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