织梦CMS - 轻松建站从此开始!

罗索

windows dshow camera

jackyhwei 发布于 2011-07-07 17:05 点击:次 
在Windows下用DirectShow来进行视频采集的实现代码(包括直接保存采集到的YUV数据,及拍照截图成JPEG文件)
TAG:

#include "stdafx.h"
#include <windows.h>
#include <dshow.h>
#include <qedit.h>
#include <Ocidl.h>
#include <atlbase.h>
#include <ole2.h>

#define TS_CONST_VALUE    10000000

#define CHK( x ) do{ \
      lRet = x; \
      if( FAILED( lRet)) \
      { \
       DebugMsg(L"Error in line = %d\n", __LINE__); \
       goto exit; \
      } \
     } while( FALSE );

#define RELEASE( x ) { if (x){ x.Release();x=NULL; }}


static struct tagCAM_DATA
{
 BOOL      state;

 CComPtr<ICaptureGraphBuilder2> m_pCaptureGraphBuilder;
 CComPtr<IGraphBuilder>      m_pFilterGraph;
 CComPtr<IMediaControl>  m_pMediaControl;

 CComPtr<IBaseFilter>  m_pVideoCaptureFilter;
 CComPtr<IBaseFilter>  m_pPreviewRender;
 IVideoWindow*    m_piPreviewWin;

 CComPtr<IBaseFilter>  m_pCaptureRender;
 IVideoWindow*    m_piCaptureWin;

}camData;

#pragma comment(lib, "strmiids")

static HRESULT FindCAMVideoDevices(IBaseFilter **pVideoCaptureFilter)
{
    // Create the System Device Enumerator.
 IEnumMoniker *pEnum;
    ICreateDevEnum *pDevEnum;

    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

    if (SUCCEEDED(hr))
    {
        // Create an enumerator for the category.
        hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
        if (hr == S_FALSE)
        {
            hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
        }
        pDevEnum->Release();
    }
 if (SUCCEEDED(hr))
 {
  IMoniker *pMoniker = NULL;
  while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
  {
   IPropertyBag *pPropBag;
   HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
   if (FAILED(hr))
   {
    pMoniker->Release();
    continue; 
   }

   VARIANT var;
   VariantInit(&var);

   // Get description or friendly name.
   hr = pPropBag->Read(L"Description", &var, 0);
   if (FAILED(hr))
   {
    hr = pPropBag->Read(L"FriendlyName", &var, 0);
   }
   if (SUCCEEDED(hr))
   {
    if(wcscmp(var.bstrVal, L"IRiiiCH RC-V200 USB2.0 Scanner")==0)
    {
     hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)pVideoCaptureFilter);
    }
    //printf("%S\n", var.bstrVal);//Sunny HD WebCam(UVC 1.1)
    VariantClear(&var);
   }

   hr = pPropBag->Write(L"FriendlyName", &var);
   pPropBag->Release();
   pMoniker->Release();
  }
 }
 if(pEnum)
  pEnum->Release();
 if(*pVideoCaptureFilter == NULL)
  hr = E_FAIL;
    return hr;
}

BOOL CAMInit(HWND hPreviewWnd, HWND hCaptureWnd)
{
 HRESULT lRet = S_OK;

 RECT grc;
 memset(&camData, 0, sizeof(camData));
 CoInitialize( NULL );
 CHK(CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&camData.m_pCaptureGraphBuilder));
    CHK( CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&camData.m_pFilterGraph));
 CHK( camData.m_pCaptureGraphBuilder->SetFiltergraph( camData.m_pFilterGraph ));
 CHK(FindCAMVideoDevices(&camData.m_pVideoCaptureFilter));

 camData.m_pFilterGraph->AddFilter(camData.m_pVideoCaptureFilter, L"Capture Filter");
 
 CHK(camData.m_pPreviewRender.CoCreateInstance (CLSID_VideoRendererDefault));
 camData.m_pFilterGraph->AddFilter(camData.m_pPreviewRender, L"Preview Render Filter");
 CHK(camData.m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,camData.m_pVideoCaptureFilter, NULL,camData.m_pPreviewRender));
 
 CHK(camData.m_pFilterGraph->QueryInterface( IID_IVideoWindow, (void**)&camData.m_piPreviewWin));
 camData.m_piPreviewWin->put_Owner((OAHWND)hPreviewWnd);
 camData.m_piPreviewWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
 GetClientRect(hPreviewWnd, &grc);
 camData.m_piPreviewWin->SetWindowPosition(0, 0, grc.right, grc.bottom);

 CHK(camData.m_pCaptureRender.CoCreateInstance(CLSID_SampleGrabber));
 camData.m_pFilterGraph->AddFilter(camData.m_pCaptureRender, L"Capture render Filter");
 CHK(camData.m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_STILL, &MEDIATYPE_Video,camData.m_pVideoCaptureFilter, NULL, camData.m_pCaptureRender));

 /*CHK(camData.m_pFilterGraph->QueryInterface( IID_IVideoWindow, (void**)&camData.m_piCaptureWin));
 camData.m_piCaptureWin->put_Owner((OAHWND)hCaptureWnd);
 camData.m_piCaptureWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
 GetClientRect(hCaptureWnd, &grc);
 camData.m_piCaptureWin->SetWindowPosition(0, 0, grc.right, grc.bottom);
*/
 CHK(camData.m_pFilterGraph->QueryInterface( IID_IMediaControl, (void**)&camData.m_pMediaControl ));
 camData.state = FALSE;

 if(camData.m_pMediaControl)
 {
  camData.m_pMediaControl->Run();
  camData.state = TRUE;
 }

 return TRUE;
exit:
 CAMUninit();
 return FALSE; 
}

BOOL CAMRun()
{
 if(camData.state)
 {
  return TRUE;
 }
 if(camData.m_pMediaControl)
 {
  camData.m_pMediaControl->Run();
  camData.state = TRUE;
 }
 else
 {
  return FALSE;
 }
 return TRUE;
}

BOOL CAMStop()
{
 if(!camData.state)
 {
  return TRUE;
 }
 if(camData.m_pMediaControl)
 {
  camData.m_pMediaControl->Stop();
  camData.state = FALSE;
 }
 else
 {
  return FALSE;
 }
 return TRUE;
}

void WriteData(char* pBuffer, int nLen)
{
#if 1
FILE *file = fopen("2048X1536.yuv", "wb");
if (file)
{
fwrite(pBuffer, 1, nLen, file);
fclose(file);
}
#endif
}

BOOL  CAMCapturePhoto()
{
 HRESULT lRet = S_OK;
 IAMVideoControl*   pAMVidControl = NULL;
 IPin*      pPhotoPin = NULL;
 ISampleGrabber  *pGrab = NULL;
 IMediaEvent     *pEvent = NULL;
 //long evCode;

 if(!camData.state)
 {
  return TRUE;
 }
 CHK(camData.m_pCaptureRender->QueryInterface(IID_ISampleGrabber, (void **)&pGrab))
 pGrab->SetBufferSamples(TRUE);
 pGrab->SetOneShot(TRUE);

 CHK( camData.m_pCaptureGraphBuilder->FindPin( camData.m_pVideoCaptureFilter, PINDIR_OUTPUT, &PIN_CATEGORY_STILL, 0, FALSE, 0, &pPhotoPin));
 CHK( camData.m_pVideoCaptureFilter->QueryInterface(IID_IAMVideoControl, (void**)&pAMVidControl));
 CHK(pAMVidControl->SetMode(pPhotoPin, VideoControlFlag_Trigger));
 //lRet = pEvent->WaitForCompletion(INFINITE, &evCode);
 Sleep(2000);
 AM_MEDIA_TYPE MediaType;
 pGrab->GetConnectedMediaType(&MediaType);
 VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)MediaType.pbFormat;
 long nBufferSize = pVideoHeader->bmiHeader.biWidth*pVideoHeader->bmiHeader.biHeight*pVideoHeader->bmiHeader.biBitCount/8;
 void *pBuffer = malloc(nBufferSize);
 if(pBuffer)
 {
  pGrab->GetCurrentBuffer(&nBufferSize, (long *)pBuffer);
  WriteData((char*)pBuffer, nBufferSize);
  free(pBuffer);
 } 
exit:
 if(pAMVidControl)
  pAMVidControl->Release();
 if(pPhotoPin)
  pPhotoPin->Release();
 if(pGrab)
  pGrab->Release();
 if(lRet == S_OK)
  return TRUE;
 return FALSE;
}

void CAMUninit()
{
 CAMStop();
 if(camData.m_pMediaControl)
 {
  camData.m_pMediaControl.Release();
 }
 if(camData.m_piPreviewWin)
 {
  camData.m_piPreviewWin->put_Owner((OAHWND)NULL);
  camData.m_piPreviewWin->Release();
  camData.m_piPreviewWin = NULL;
 }
 if(camData.m_piCaptureWin)
 {
  camData.m_piCaptureWin->put_Owner((OAHWND)NULL);
  camData.m_piCaptureWin->Release();
  camData.m_piCaptureWin = NULL;
 }
 RELEASE(camData.m_pPreviewRender);
 RELEASE(camData.m_pCaptureRender);

 if(camData.m_pVideoCaptureFilter)
 {
  camData.m_pVideoCaptureFilter.Release();
 }
 if(camData.m_pFilterGraph)
 {
  camData.m_pFilterGraph.Release();
 }
 if(camData.m_pCaptureGraphBuilder)
 {
  camData.m_pCaptureGraphBuilder.Release();
 }
 memset(&camData, 0, sizeof(camData));
 CoUninitialize();
}

(carlsonlee_freec)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201107/14683.html]
本文出处:hi.baidu.com/carlsonlee_freec 作者:carlsonlee_freec
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容