/************************************************************************************
功能: 打开USB摄像头
参数: index - 输入,摄像头序号
bDisplayProperties - 输入,指示是否自动弹出摄像头属性页
nWidth - 输入,宽度,输入不为0,并且在bDisplayProperties为false时有效
nHeight - 输入,高度,输入不为0,并且在bDisplayProperties为false时有效
返回: true-成功,false-失败
*************************************************************************************/
bool CCameraDS::OpenCamera(int nCamID, bool bDisplayProperties,int nWidth,int nHeight)
{
HRESULT hr = S_OK;
CoInitialize(NULL);
// Create the Filter Graph Manager.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&m_pGraph);
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (LPVOID *)&m_pSampleGrabberFilter);
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **) &m_pMediaControl);
hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **) &m_pMediaEvent);
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (LPVOID*) &m_pNullFilter);
hr = m_pGraph->AddFilter(m_pNullFilter, L"NullRenderer");
hr = m_pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&m_pSampleGrabber);
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
= MEDIATYPE_Video;
= MEDIASUBTYPE_RGB24;
= FORMAT_VideoInfo;
hr = m_pSampleGrabber->SetMediaType(&mt);
MYFREEMEDIATYPE(mt);
m_pGraph->AddFilter(m_pSampleGrabberFilter, L"Grabber");
// Bind Device Filter. We know the device because the id was passed in
BindFilter(nCamID, &m_pDeviceFilter);
m_pGraph->AddFilter(m_pDeviceFilter, NULL);
CComPtr<IEnumPins> pEnum;
m_pDeviceFilter->EnumPins(&pEnum);
hr = pEnum->Reset();
hr = pEnum->Next(1, &m_pCameraOutput, NULL);
pEnum = NULL;
m_pSampleGrabberFilter->EnumPins(&pEnum);
pEnum->Reset();
hr = pEnum->Next(1, &m_pGrabberInput, NULL);
pEnum = NULL;
m_pSampleGrabberFilter->EnumPins(&pEnum);
pEnum->Reset();
pEnum->Skip(1);
hr = pEnum->Next(1, &m_pGrabberOutput, NULL);
pEnum = NULL;
m_pNullFilter->EnumPins(&pEnum);
pEnum->Reset();
hr = pEnum->Next(1, &m_pNullInputPin, NULL);
//SetCrossBar();
//add by chengs 20160617
if (nWidth>0 && nHeight>0)
{
SetCaps(nWidth,nHeight);
}
if (bDisplayProperties)
{
CComPtr<ISpecifyPropertyPages> pPages;
HRESULT hr = m_pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages);
if (SUCCEEDED(hr))
{
PIN_INFO PinInfo;
m_pCameraOutput->QueryPinInfo(&PinInfo);
CAUUID caGUID;
pPages->GetPages(&caGUID);
OleCreatePropertyFrame(NULL, 0, 0,
L"Property Sheet", 1,
(IUnknown **)&(m_pCameraOutput.p),
,
,
0, 0, NULL);
CoTaskMemFree();
->Release();
}
}
hr = m_pGraph->Connect(m_pCameraOutput, m_pGrabberInput);
hr = m_pGraph->Connect(m_pGrabberOutput, m_pNullInputPin);
if (FAILED(hr))
{
switch(hr)
{
case VFW_S_NOPREVIEWPIN :
break;
case E_FAIL :
break;
case E_INVALIDARG :
break;
case E_POINTER :
break;
}
}
m_pSampleGrabber->SetBufferSamples(TRUE);
m_pSampleGrabber->SetOneShot(TRUE);
hr = m_pSampleGrabber->GetConnectedMediaType(&mt);
if(FAILED(hr))
return false;
VIDEOINFOHEADER *videoHeader;
videoHeader = reinterpret_cast<VIDEOINFOHEADER*>();
m_nWidth = videoHeader->;
m_nHeight = videoHeader->;
m_bConnected = true;
return true;
}
/************************************************************************
功能: 获取一帧视频流数据
参数:
返回: 一帧视频流数据
*************************************************************************/
unsigned char* CCameraDS::QueryFrame()
{
long evCode;
long size = 0;
m_pMediaControl->Run();
m_pMediaEvent->WaitForCompletion(5000, &evCode); //INFINITE
m_pSampleGrabber->GetCurrentBuffer(&size, NULL);
if (size == 0)
{
return NULL;
}
//if the buffer size changed
if (size != m_nBufferSize)
{
if (m_pFrame)
free(m_pFrame);
m_nBufferSize = size;
m_pFrame = (unsigned char*)malloc(m_nWidth*m_nHeight*3);
}
if (m_pFrame == NULL)
{
return NULL;
}
m_pSampleGrabber->GetCurrentBuffer(&m_nBufferSize, (long*)m_pFrame);
ImrotateVertical_RGB(m_pFrame, m_nWidth, m_nHeight);
return m_pFrame;
}