您的位置:首页 > 其它

directshow 采集视频

2010-01-08 16:58 211 查看
Ps:只列主要的,一些执行错误等处理、内存释放 无

步骤一、CoInitialize(NULL); //初始化COM Library

步骤二、创建视频采集过滤器图表

//创建视频采集过滤器图表
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGraphBuilder);
//ICaptureGraphBuilder2接口
CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&m_pCaptureGraphBulid);
//过滤器图表添加到管理器中
m_pCaptureGraphBulid->SetFiltergraph(m_pGraphBuilder);
//媒体控制接口
m_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_pMediaCtl);
//视频显示窗口
m_pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **) &m_pMediaEvent);


步骤三、枚举并绑定设备

//设备枚举器Interface
CoCreateInstance(CLSID_SystemDeviceEnum, NULL,        CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
//名称枚举器
HRESULT hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
if (hr == NOERROR)
{
pEm->Reset();
}
//---------------------------------------------------------

ULONG cFetched;
IMoniker *pM = NULL;

int index = 0;
while(pEm->Next(1, &pM, &cFetched)==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)
{
if (index == 1)
{
//将视频设备绑定到基础过滤器上
pM->BindToObject(0, 0, IID_IBaseFilter, (void**)(&m_pBaseFilter));
}
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
index++;
}


步骤四、将Filter添加到过滤器图表中
m_pGraphBuilder->AddFilter(m_pBaseFilter, L"Capture");

步骤五、设置视频流属性

IAMStreamConfig *pAMStreamConfig=NULL;

m_pCaptureGraphBulid->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video, m_pBaseFilter,IID_IAMStreamConfig,(void **)&pAMStreamConfig);

//得到视频格式大小
AM_MEDIA_TYPE *pmt;
pAMStreamConfig->GetFormat(&pmt);
//设置视频格式
pmt->majortype = MEDIATYPE_Video;
if(nRGBBytes==24)
{
pmt->subtype = MEDIASUBTYPE_RGB24;
}
else if(nRGBBytes==32)
{
pmt->subtype = MEDIASUBTYPE_RGB32;
}
else if(nRGBBytes==15)
{
pmt->subtype = MEDIASUBTYPE_RGB555;
}
else if(nRGBBytes==16)
{
pmt->subtype = MEDIASUBTYPE_RGB565;
}
else
{
pmt->subtype = MEDIASUBTYPE_RGB32;
}
VIDEOINFOHEADER *pvih = reinterpret_cast<VIDEOINFOHEADER *>(pmt->pbFormat);
//设置回去
int nDefualWidth = pvih->bmiHeader.biWidth;
int nDefualHeight = pvih->bmiHeader.biHeight;

pvih->bmiHeader.biWidth = iWidth;
pvih->bmiHeader.biHeight = iHeight;
pvih->bmiHeader.biSizeImage = pmt->lSampleSize = iWidth*iHeight*pvih->bmiHeader.biPlanes*pvih->bmiHeader.biBitCount/8;
pvih->AvgTimePerFrame = (LONGLONG)(10000000/nFrameRate);

pAMStreamConfig->SetFormat(pmt);

m_pCaptureGraphBulid->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,m_pBaseFilter,NULL,NULL);

m_pCaptureGraphBulid->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,
m_pBaseFilter,IID_IVideoWindow,(void **)&m_pVideoWindow);


步骤六、设置视频窗口

if(m_pVideoWindow)
{
m_pVideoWindow->put_Owner((OAHWND)m_hWnd);
}
m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);

if (m_pVideoWindow)
{
CRect rc;
::GetClientRect(m_hWnd,&rc);
m_pVideoWindow->SetWindowPosition(0, 0, rc.right, rc.bottom);
}
m_pVideoWindow->put_Visible(OATRUE);


步骤七:预览视频

m_pMediaCtl->Run(); //开始

m_pMediaCtl->Stop(); //停止
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: