DirectShow访问USB摄像头Demo

时间:2025-04-10 09:20:24
  • /************************************************************************************
  • 功能: 打开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;
  • }