Windows下網路攝影機採集驅動(DirectShow)

來源:互聯網
上載者:User

出處:http://blog.csdn.net/chenice9999/article/details/6968957 


枚舉網路攝影機裝置(不論裝置能否被使用都會被枚舉出來):

int EnumDevices()

 int id = 0; 
 
 //枚舉視頻撲捉裝置 
 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); //you can get other info by first parame
   if (hr == NOERROR) 
   { 

        id++; 
        SysFreeString(var.bstrVal); 
   } 
   
   pBag->Release(); 
  } 
  
  pM->Release(); 
 } 
 
 return id; 
}

 

啟動網路攝影機:

HWND m_hWnd; 
IGraphBuilder *m_pGB; 
ICaptureGraphBuilder2* m_pCapture; 
IBaseFilter* m_pBF; 
IMediaControl* m_pMC; 
IVideoWindow* m_pVW; 
CComPtr<ISampleGrabber> m_pGrabber;

1.初始化GraphBuilder

CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB); 
CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **) &m_pCapture);  
m_pCapture->SetFiltergraph(m_pGB); 
m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);  
m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW); 

2.綁定一個裝置到InputFilter

CComPtr<ICreateDevEnum> pCreateDevEnum; 
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);  
CComPtr<IEnumMoniker> pEm; 
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0); 

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) 
   { 
    pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter); 
    SysFreeString(var.bstrVal); 
   } 
   pBag->Release(); 
  }
  pM->Release(); 
 }

3.建立一個OutputFilter

m_pGrabber.CoCreateInstance( CLSID_SampleGrabber ); 
CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber );

4.設定SampleGrabber的視頻格式

AM_MEDIA_TYPE mt; 
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); 
mt.majortype = MEDIATYPE_Video; 
mt.subtype = MEDIASUBTYPE_RGB24; //這裡只是設定輸出的映像資料類型(24bit,32bit,...),directshow會對自動的對採集到的映像資料做轉換
m_pGrabber->SetMediaType(&mt);

5.將2個Filter添加到GraphBuilder

m_pGB->AddFilter(m_pBF, L"Capture Filter"); 
m_pGB->AddFilter( pGrabBase, L"Grabber" );

6.嘗試去RenderStream,失敗則表示該裝置無法使用(比如被其他應用程式所佔用)

hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL); 
 if( FAILED( hr ) ) 
  hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL); 
 if( FAILED( hr ) )
 { 
  AfxMessageBox(L"Can’t build the graph"); 
  return hr; 
 }

7.配置SampleGrabber

m_pGrabber->SetBufferSamples( FALSE ); //如果設定true,SampleGrabber會建立一個內部的buffer,可以通過GetCurrentBuffer獲得當前幀資料
m_pGrabber->SetOneShot( FALSE ); //如果設定成true,表示只會進入callback函數一次
m_pGrabber->SetCallback( &mCB, 1 );//設定callback,第2個參數如果設定成0,則第一個參數必須是IMediaSample指標

8.開始視頻捕獲

m_pMC->Run();

 

枚舉,設定InputFilter的資料格式:

CComPtr<IAMStreamConfig> pam;
m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,    m_pBF, IID_IAMStreamConfig, reinterpret_cast<void**>(&pam));
int nCount = 0;
int nSize = 0;
pam->GetNumberOfCapabilities(&nCount, &nSize);

AM_MEDIA_TYPE* pmmt = NULL;
VIDEO_STREAM_CONFIG_CAPS scc;

if (sizeof(VIDEO_STREAM_CONFIG_CAPS) == nSize) {
  for (int i=0; i<nCount; i++) {
   pmmt = NULL;

   hr = pam->GetStreamCaps(i, &pmmt, reinterpret_cast<BYTE*>(&scc));
   if (FAILED(hr))
   {
    continue;
   }

   if ( pmmt->majortype == MEDIATYPE_Video && pmmt->formattype == FORMAT_VideoInfo )
   {
    pam->SetFormat(pmmt);

    break;
   }
  }
 }

 

釋放AM_MEDIA_TYPE類型資源:

void FreeMediaType(AM_MEDIA_TYPE& mt) 

 if (mt.cbFormat != 0) 
 { 
  CoTaskMemFree((PVOID)mt.pbFormat); 
  
  // Strictly unnecessary but tidier 
  mt.cbFormat = 0; 
  mt.pbFormat = NULL; 
 } 
 
 if (mt.pUnk != NULL) 
 {
  mt.pUnk->Release(); 
  mt.pUnk = NULL; 
 } 
}

 

綁定視頻輸出視窗:

建立一個picture空間,設定其屬性(Type: Rectangle,Color:Gray)

m_pVW->put_Owner((OAHWND)m_hWnd);  
m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);  
 Rect rc; 
::GetClientRect(m_hWnd,&rc); 
float fk = (float)mCB.lWidth / (float)mCB.lHeight;
long rw = fk * rc.bottom;
int off_x = (rc.right - rw)/2;
m_pVW->SetWindowPosition(off_x, 0, rw, rc.bottom);//讓捕獲到的視頻置中顯示
m_pVW->put_Visible(OATRUE);

 

解除綁定視頻輸出視窗:

m_pVW->put_Visible(OAFALSE);
m_pVW->put_Owner(NULL);

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.