VC6.0中處理攝像頭視頻監控問題


我寫了頭文件如下:
/*CaptureClass.h*/

#pragma once
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__
#include <windows.h>
#include <atlbase.h>
#include <DShow.h>
#include <qedit.h>//ISampleGrabber接口要求的 

#ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
#endif
class CCaptureClass
{
public:
CCaptureClass(void);
public:
~CCaptureClass(void);
int EnumDevices(HWND hList); 
//void SaveGraph(TCHAR *wFileName);       //保存濾波器鏈表
void ConfigCameraPin(HWND hwndParent);      //配置攝像頭的視頻格式
void ConfigCameraFilter(HWND hwndParent);     //配置攝像頭的圖像參數
HRESULT CaptureImages(CString inFileName);     //捕獲保存視頻
HRESULT PreviewImages(int iDeviceID , HWND hWnd);   //采集預覽視頻
private:
HWND m_hWnd;            //視頻顯示窗口的句柄
IGraphBuilder *m_pGB;          //濾波器鏈表管理器
ICaptureGraphBuilder2 *m_pCapture;       //增強型捕獲濾波器鏈表管理器
IBaseFilter *m_pBF;           //捕獲濾波器
IMediaControl *m_pMC;          //媒體控制接口
IVideoWindow *m_pVW;          //視頻顯示窗口接口
IBaseFilter *pMux;           //寫文件濾波器
protected:
bool BindFilter(int deviceId,IBaseFilter **pFilter); //把指定的設備濾波器捆綁到鏈表中
void ResizeVideoWindow();         //更改視頻顯示窗口
HRESULT SetupVideoWindow();         //設置視頻顯示窗口的特性
HRESULT InitCaptureGraphBuilder();       //創建濾波器鏈表管理器,查詢其各種控制接口
};

6 个解决方案

#1


實現文件:

/*CaptureClass.cpp*/

#include "StdAfx.h"
#include "CaptureClass.h"

/************************************************************************/
/* 類構造函數實現                                                       */
/************************************************************************/
CCaptureClass::CCaptureClass(void)
{
CoInitialize(NULL);   //COM庫初始化
m_hWnd = NULL;    //視頻顯示窗口的句柄
m_pVW = NULL ;    //視頻窗口接口指針清空
m_pMC = NULL ;    //媒體控制接口指針清空
m_pGB = NULL ;    //濾波器鏈表管理器接口指針清空
m_pBF = NULL ;    //捕獲濾波器接口指針清空
m_pCapture = NULL ;   //增強型捕獲濾波器鏈表管理器接口指針清空
}

/************************************************************************/
/* 析構函數                                                             */
/************************************************************************/
CCaptureClass::~CCaptureClass(void)
{
if(m_pMC) m_pMC ->Stop(); //首先停止媒體
if(m_pVW){
m_pVW->put_Visible(OAFALSE); //視頻窗口不可見
m_pVW->put_Owner(NULL);    //視頻窗口的父窗口清空
}
SAFE_RELEASE(m_pCapture);    //釋放增強型捕獲濾波器鏈表管理器接口
SAFE_RELEASE(m_pMC);     //釋放媒體控制接口
SAFE_RELEASE(m_pGB);     //釋放濾波器鏈表管理器接口
SAFE_RELEASE(m_pBF);     //釋放捕獲濾波器接口
CoUninitialize( );      //卸載COM庫
}

/************************************************************************/
/* 把指定采集設備與濾波器捆綁                                           */
/************************************************************************/
bool CCaptureClass::BindFilter(int deviceId,IBaseFilter **pFilter)
{
if( deviceId < 0) return false ;
//枚舉所有的視頻捕獲設備
ICreateDevEnum *pCreateDevEnum ;
//生成設備枚舉器pCreateDevEnum
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)&pCreateDevEnum);
if( hr != NOERROR ) return false ;
IEnumMoniker *pEm;
//創建視頻輸入設備類枚舉器
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm,0);
if( hr != NOERROR ) return false ;
pEm->Reset(); //復位該設備
ULONG cFetched;
IMoniker *pM;
int index = 0 ;
//獲取設備
while( hr = pEm->Next(1,&pM,&cFetched),hr == S_OK , index <= deviceId )
{
   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); //獲取FriendlyName形式的信息
    if( hr == NOERROR )
    {
     //采集設備與捕獲濾波器捆綁
     if( index == deviceId ) pM->BindToObject(0,0,IID_IBaseFilter,(void**)pFilter);
     SysFreeString(var.bstrVal);   //釋放二進制數據資源,必須釋放
    }
    pBag ->Release();
   }
   pM->Release();
   index++;
}
return true ;
}

/************************************************************************/
/* 設置視頻顯示窗口的特性                                               */
/************************************************************************/
HRESULT CCaptureClass::SetupVideoWindow()
{
HRESULT hr ;
//m_hWnd為類CCaptureClass的成員變量,在使用該函數前須初始化
hr = m_pVW->put_Visible(OAFALSE); //視頻窗口不可見
hr = m_pVW->put_Owner((OAHWND)m_hWnd); //窗口所有者:傳入的窗口句柄
if(FAILED(hr)) return hr ;
hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN); //窗口風格設置
if( FAILED(hr)) return hr ;
ResizeVideoWindow();   //更改窗口大小
hr = m_pVW->put_Visible(OATRUE); //視頻窗口可見
return hr ;
}

/************************************************************************/
/* 更改視頻窗口大小                                                     */
/************************************************************************/
void CCaptureClass::ResizeVideoWindow()
{
if( m_pVW ){
   //讓圖像充滿整個指定窗口
   CRect rc ;
   ::GetClientRect(m_hWnd,&rc); //獲取顯示窗口的客戶區
   m_pVW->SetWindowPosition(0,0,rc.right,rc.bottom); //設置視頻顯示窗口的位置
}
}

/************************************************************************/
/* 開始預覽視頻設備                                                     */
/************************************************************************/
HRESULT CCaptureClass::PreviewImages(int iDeviceID , HWND hWnd)
{
HRESULT hr ;
//初始化視頻捕獲濾波器鏈表管理器
hr = InitCaptureGraphBuilder();
if(FAILED(hr)){
   AfxMessageBox(_T("Failed to get video interfaces!"));
   return hr ;
}

//把指定采集設備與濾波器綁定
if( !BindFilter(iDeviceID,&m_pBF)) return S_FALSE;
//把濾波器添加到濾波器鏈表中
hr = m_pGB->AddFilter(m_pBF,L"Capture Filter");
//渲染媒體,把鏈表中的濾波器鏈接起來
hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,m_pBF,NULL,NULL);
if(FAILED(hr)){
   AfxMessageBox(_T("Can't build the graph"));
   return hr ;
}

//設置視頻顯示窗口
m_hWnd = hWnd; //初始化窗口句柄
SetupVideoWindow(); //設置顯示窗口

hr = m_pMC->Run();
if(FAILED(hr)){
   AfxMessageBox(_T("Couldn't run the graph!"));
   return hr ;
}
return S_OK ;
}

/************************************************************************/
/* 設置捕獲視頻的文件,開始捕捉視頻數據寫文件                           */
/************************************************************************/
HRESULT CCaptureClass::CaptureImages(CString inFileName)
{
HRESULT hr = 0 ;
m_pMC ->Stop(); //先停止視頻
//設置文件名,注意第二個參數的類型
hr = m_pCapture->SetOutputFileName(&MEDIASUBTYPE_Avi,inFileName.AllocSysString(),&pMux,NULL) ;
//渲染媒體,鏈接所有濾波器
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,m_pBF,NULL,pMux);
pMux->Release();
m_pMC->Run(); //回復視頻
return hr ;
}

int CCaptureClass::EnumDevices(HWND hList)
{
if (!hList)
   return -1;
int id = 0;

//枚舉視頻撲捉設備
ICreateDevEnum *pCreateDevEnum;            /*此接口生成一個特殊類別的設備枚舉器,The System Device Enumerator exposes this interface*/
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)return -1;

IEnumMoniker *pEm=0;              //此接口用來枚舉一個"名字"組件或者枚舉名字表中的名字
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);//CreateClassEnumerator方法為指定的設備類生成一個類枚舉器 

if (hr != NOERROR)return -1;

pEm->Reset();                //由於IEnumMoniker接口有一個標准的參考計數,pEm->Release(),一定要釋放此接口
ULONG cFetched;

IMoniker *pM;                //此接口包含允許你使用“名字”對象的方法,而名字對象包含能唯一確定COM對象的方法
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)       //返回枚舉器隊列中指定數目的條款,下“1”個
{
   IPropertyBag *pBag;              //接口IPropertyBag提供一個有屬性包的對象,對象可以在包里存儲它的特征
   hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);   //返回包含被“moniker”確定的對象的存儲位置的接口指針
   if(SUCCEEDED(hr)) 
   {
    VARIANT var;              //VARIANT結構體包括很多類型
    var.vt = VT_BSTR;             //vt, describes which of the union members is valid,bstrVal是有效的
    hr = pBag->Read(L"FriendlyName", &var, NULL);      //Asks the property bag to read the named 

    //property into a caller-initialized VARIANT,var接收
    if (hr == NOERROR) 
    {
     //CP_ACP:The current system Windows "ANSI" code page
     //var.bstrVal被轉化的
     //-1表示長度被自動計算;str表示轉化侯接收目標的地方;兩個NULL使函數更快
     id++;
    
     //此函數處理指定的消息,hList窗口的句柄,此窗口處理此消息;CB_ADDSTRING要處理的消息
     ::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)var.bstrVal);
    
     SysFreeString(var.bstrVal);
    }
    pBag->Release();
   }
   pM->Release();
}
return id;
}

HRESULT CCaptureClass::InitCaptureGraphBuilder()
{
HRESULT hr ;
//創建IGraphBuilder接口
hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void**)&m_pGB);
if(FAILED(hr)) return hr ;
//創建ICaptureGraphBuilder2接口
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC,IID_ICaptureGraphBuilder2,(void**)&m_pCapture) ;
if(FAILED(hr)) return hr ;
//初始化濾波器鏈表管理器IGraphBuilder
m_pCapture->SetFiltergraph(m_pGB);
//查詢媒體控制接口
hr = m_pGB->QueryInterface(IID_IMediaControl,(void**)&m_pMC);
if(FAILED(hr)) return hr ;
//查詢視頻窗口接口
hr = m_pGB -> QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);
if(FAILED(hr)) return hr ;
return hr ;
}

//////////////////////////////////////////////////////////////////////////
//配置攝像頭數據源格式:分辨率、RGB/I420等
void CCaptureClass::ConfigCameraPin(HWND hwndParent)
{
HRESULT hr ;    //返回值
IAMStreamConfig *pSC ; //流配置接口
ISpecifyPropertyPages *pSpec ; //屬性頁接口
//只有停止后,才能進行引腳屬性的設置
m_pMC ->Stop();
//首先查詢捕獲CAPTURE、視頻VIDEO接口
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,m_pBF,IID_IAMStreamConfig,(void**)&pSC);
CAUUID cauuid ;   //所有屬性頁結構體
hr = pSC->QueryInterface(IID_ISpecifyPropertyPages,(void**)&pSpec);
if( hr == S_OK ){
   hr = pSpec->GetPages(&cauuid); //獲取所有屬性頁
   //顯示屬性頁
   hr = OleCreatePropertyFrame(hwndParent,30,30,NULL,1,(IUnknown**)&pSC,cauuid.cElems,(GUID*)cauuid.pElems,0,0,NULL);
   //釋放內存、資源
   CoTaskMemFree(cauuid.pElems);
   pSpec->Release();
   pSC->Release();
}

//回復運行
m_pMC->Run();
}

//////////////////////////////////////////////////////////////////////////
//配置圖像參數:亮度、色度、飽和度等
void CCaptureClass::ConfigCameraFilter(HWND hwndParent)
{
HRESULT hr = 0 ;
ISpecifyPropertyPages *pProp ;
hr = m_pBF->QueryInterface(IID_ISpecifyPropertyPages,(void**)&pProp);
if(SUCCEEDED(hr))
{
   //獲取濾波器名稱和IUnknown接口指針
   FILTER_INFO FilterInfo ;
   hr = m_pBF->QueryFilterInfo(&FilterInfo);
   IUnknown *pFilterUnk ;
   m_pBF->QueryInterface(IID_IUnknown,(void**)&pFilterUnk);
   //顯示該頁
   CAUUID caGUID ;
   pProp ->GetPages(&caGUID);
   OleCreatePropertyFrame(
    hwndParent,
    0,0,
    FilterInfo.achName,
    1,
    &pFilterUnk,
    caGUID.cElems,
    caGUID.pElems,
    0,
    0,NULL
   );
   //釋放內存、資源
   CoTaskMemFree(caGUID.pElems);
   pFilterUnk->Release();
   FilterInfo.pGraph ->Release();
   pProp->Release();
}
m_pMC->Run();
}

#2


我已經安裝了Microsoft Platform SDK for Windows Server 2003 SP1,已經安裝相關要求設置好了路徑,但是為什么為出錯呢?
報錯如下:
d:\program files\microsoft platform sdk\include\mmstream.h(100) : error C2065: 'DWORD_PTR' : undeclared identifier
d:\program files\microsoft platform sdk\include\mmstream.h(100) : error C2146: syntax error : missing ')' before identifier 'dwParam'
d:\program files\microsoft platform sdk\include\mmstream.h(100) : error C2165: 'left-side modifier' : cannot modify pointers to data
d:\program files\microsoft platform sdk\include\mmstream.h(100) : error C2071: 'PAPCFUNC' : illegal storage class
d:\program files\microsoft platform sdk\include\mmstream.h(100) : error C2059: syntax error : ')'
d:\program files\microsoft platform sdk\include\mmstream.h(669) : error C2061: syntax error : identifier 'DWORD_PTR'
d:\program files\microsoft platform sdk\include\mmstream.h(810) : error C2061: syntax error : identifier 'DWORD_PTR'
d:\program files\microsoft platform sdk\include\qedit.h(8159) : error C2061: syntax error : identifier 'LONG_PTR'
d:\program files\microsoft platform sdk\include\qedit.h(8695) : error C2061: syntax error : identifier 'LONG_PTR'
d:\vc lab\draw\captureclass.h(31) : error C2143: syntax error : missing ';' before '*'
d:\vc lab\draw\captureclass.h(31) : error C2501: 'ICaptureGraphBuilder2' : missing storage-class or type specifiers
d:\vc lab\draw\captureclass.h(31) : error C2501: 'm_pCapture' : missing storage-class or type specifiers
D:\VC LAB\Draw\CaptureClass.cpp(17) : error C2065: 'm_pCapture' : undeclared identifier
D:\VC LAB\Draw\CaptureClass.cpp(30) : error C2227: left of '->Release' must point to class/struct/union
D:\VC LAB\Draw\CaptureClass.cpp(129) : error C2227: left of '->RenderStream' must point to class/struct/union
D:\VC LAB\Draw\CaptureClass.cpp(155) : error C2227: left of '->SetOutputFileName' must point to class/struct/union
D:\VC LAB\Draw\CaptureClass.cpp(157) : error C2227: left of '->RenderStream' must point to class/struct/union
D:\VC LAB\Draw\CaptureClass.cpp(220) : error C2065: 'CLSID_CaptureGraphBuilder2' : undeclared identifier
D:\VC LAB\Draw\CaptureClass.cpp(220) : error C2065: 'IID_ICaptureGraphBuilder2' : undeclared identifier
D:\VC LAB\Draw\CaptureClass.cpp(223) : error C2227: left of '->SetFiltergraph' must point to class/struct/union
D:\VC LAB\Draw\CaptureClass.cpp(243) : error C2227: left of '->FindInterface' must point to class/struct/union

#3


求達人解釋~~~救急啊~~~~

#4


頭文件搜索路徑的次序是否設置對了?

#5


你看看找不到的變量在哪個.h文件中

#6


好像缺少lib文件,你把dx sdk2005中的baseclass編譯后的lib包含進去試試

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com