📄 cvcam.cpp
字号:
/*M////////////////////////////////////////////////////////////////////////////////////////// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.//// By downloading, copying, installing or using the software you agree to this license.// If you do not agree to this license, do not download, install,// copy or use the software.////// Intel License Agreement// For Open Source Computer Vision Library//// Copyright (C) 2000, Intel Corporation, all rights reserved.// Third party copyrights are property of their respective owners.//// Redistribution and use in source and binary forms, with or without modification,// are permitted provided that the following conditions are met://// * Redistribution's of source code must retain the above copyright notice,// this list of conditions and the following disclaimer.//// * Redistribution's in binary form must reproduce the above copyright notice,// this list of conditions and the following disclaimer in the documentation// and/or other materials provided with the distribution.//// * The name of Intel Corporation may not be used to endorse or promote products// derived from this software without specific prior written permission.//// This software is provided by the copyright holders and contributors "as is" and// any express or implied warranties, including, but not limited to, the implied// warranties of merchantability and fitness for a particular purpose are disclaimed.// In no event shall the Intel Corporation or contributors be liable for any direct,// indirect, incidental, special, exemplary, or consequential damages// (including, but not limited to, procurement of substitute goods or services;// loss of use, data, or profits; or business interruption) however caused// and on any theory of liability, whether in contract, strict liability,// or tort (including negligence or otherwise) arising in any way out of// the use of this software, even if advised of the possibility of such damage.////M*///#include "windows.h"//#include "AFXPRIV.H"#include "highgui.h"#include <streams.h>#include <initguid.h>#include "iProxyTrans.h"#include "ProxyTransuids.h"#include "iSyncFilter.h"#include "syncfilteruids.h"#include <windows.h>#include <objbase.h>#include "afxres.h"#include "resource.h"#include "cvcamavi.h"#include "cvcam.h"#include <vector>using namespace std;#define WM_GRAPHNOTIFY WM_USER+13struct _cam_properties{ int _enabled; int render; int window; void* callback; int rndwidth; int rndheight; int srcwidth; int srcheight; _cam_properties() : _enabled(0), render(1), window(0), callback(0), rndwidth(0), rndheight(0), srcwidth(0), srcheight(0) {};};static void* stereo2_callback;static void* stereo3_callback;static void* stereo4_callback;static vector<_cam_properties> cvcam_properties;class SafeMoniker : public SafePointer<IMoniker>{public: SafeMoniker(const SafeMoniker& p) { m_pointer = p.m_pointer;m_pointer->AddRef(); }; SafeMoniker(IMoniker* p) { m_pointer = p; }};class SafeUnknown : public SafePointer<IUnknown>{public: SafeUnknown(const SafeUnknown& p) { m_pointer = p.m_pointer; if(m_pointer) { m_pointer->AddRef(); } }; SafeUnknown(IUnknown* p) { m_pointer = p; }};static IMoniker* _cvcamMon = 0;static IBindCtx* _cvcamBCtx=0;static SafePointer<ICreateDevEnum> _cvcamCreateDevEnum(NULL);static SafePointer<IEnumMoniker> _cvcamEnumMon(NULL);static vector<SafeMoniker> _cvcamMonikers;typedef SafePointer<IBaseFilter> SafeFilter;static vector<SafeFilter> _cvcamSource(NULL);static SafePointer<IProxyTransform> _cvcamProxyTrans(NULL);static SafePointer<ISyncFilter> _cvcamCvSync(NULL);static SafePointer<IGraphBuilder> _cvcamGraphBuilder(NULL);static SafePointer<IMediaControl> _cvcamMediaControl(NULL);static SafePointer<IMediaEventEx> _cvcamMediaEventEx(NULL);static SafePointer<IVideoWindow> _cvcamVideoWindow(NULL);static SafePointer<IVideoWindow> _cvcamVideoWindow2(NULL);static SafePointer<IVideoWindow> _cvcamVideoWindow3(NULL);static SafePointer<ICaptureGraphBuilder2> _cvcamCapGraphBuilder(NULL);static short nb_cameras = 1;static int camera_index = -1;static cvcamAVIs theAvis;static char errorText[100];/* Resets all the filters */static void _cvcamReset(){ _cvcamSource.clear(); _cvcamProxyTrans = NULL; _cvcamMediaControl = NULL; _cvcamMediaEventEx = NULL; _cvcamVideoWindow = NULL; _cvcamVideoWindow2 = NULL; _cvcamVideoWindow3 = NULL; _cvcamCvSync = NULL; _cvcamGraphBuilder = NULL; _cvcamCapGraphBuilder = NULL;}HINSTANCE DLLhinst;BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to the DLL module DWORD fdwReason, // reason for calling function LPVOID lpvReserved // reserved ){ DLLhinst = hinstDLL; switch( fdwReason ) { case DLL_PROCESS_ATTACH: CoInitialize(0); break; case DLL_PROCESS_DETACH: CoUninitialize(); } return TRUE;}static int _cvcamInitVideoSource(IBaseFilter** filter);static int _cvcamInitSeveralCams();static int cvcamAVISetProperty(int camera, const char* property, void* value);static int cvcamAVIGetProperty(int camera, const char* property, void* value);static int _cvcamNumberOfEnabled(){ int j = 0; for(uint i = 0; i < cvcam_properties.size(); i++) { if(cvcam_properties[i]._enabled) j++; } return j;}static IPin* get_source_pin( IBaseFilter* pFilter, PIN_DIRECTION dir ){ ICaptureGraphBuilder2* cgb2; IPin* pPin =0; if(FAILED(CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&cgb2 ))) { return 0; } cgb2->FindPin(pFilter, dir, &PIN_CATEGORY_CAPTURE , &MEDIATYPE_Video, FALSE, 0, &pPin); cgb2->Release(); return pPin;}IPin* get_pin( IBaseFilter* pFilter, PIN_DIRECTION dir ){ IEnumPins* pEnumPins = 0; IPin* pPin = 0; if( pFilter ) { pFilter->EnumPins( &pEnumPins ); if( pEnumPins != 0 ) { for(;;) { ULONG cFetched = 0; PIN_DIRECTION pinDir = PIN_DIRECTION(-1); pPin = 0; pEnumPins->Next( 1, &pPin, &cFetched ); if( cFetched == 1 && pPin != 0 ) { pPin->QueryDirection( &pinDir ); if( pinDir == dir ) break; pPin->Release(); } else if(cFetched == 0) { return 0; } } pEnumPins->Release(); } } return pPin;}static void _cvcamDisconnectAllFilter(IBaseFilter *pf){ IPin *pP, *pTo; ULONG u; IEnumPins *pins = NULL; PIN_INFO pininfo; HRESULT hr = pf->EnumPins(&pins); pins->Reset(); while(hr == NOERROR) { hr = pins->Next(1, &pP, &u); if(hr == S_OK && pP) { pP->ConnectedTo(&pTo); if(pTo) { hr = pTo->QueryPinInfo(&pininfo); if(hr == NOERROR) { if(pininfo.dir == PINDIR_INPUT) { _cvcamDisconnectAllFilter(pininfo.pFilter); _cvcamGraphBuilder->Disconnect(pTo); _cvcamGraphBuilder->Disconnect(pP); _cvcamGraphBuilder->RemoveFilter(pininfo.pFilter); } pininfo.pFilter->Release(); } pTo->Release(); } pP->Release(); } } if(pins) pins->Release();}//Put everything back to its initial state(before cvcamInit was called)static void _cvcamTearDownGraph(){ cvcamStop(); if(_cvcamVideoWindow.is_valid() ) { _cvcamVideoWindow->put_Visible(OAFALSE); _cvcamVideoWindow->put_Owner(NULL); _cvcamVideoWindow = NULL; } if(_cvcamVideoWindow2.is_valid() ) { _cvcamVideoWindow2->put_Visible(OAFALSE); _cvcamVideoWindow2->put_Owner(NULL); _cvcamVideoWindow2 = NULL; } if(_cvcamVideoWindow3.is_valid() ) { _cvcamVideoWindow3->put_Visible(OAFALSE); _cvcamVideoWindow3->put_Owner(NULL); _cvcamVideoWindow3 = NULL; } _cvcamMediaControl = NULL; _cvcamMediaEventEx = NULL; // disconnect the graph and release all filter, except _cvcamSource anyway for(uint i = 0; i < _cvcamSource.size(); i++) if(_cvcamSource[i].is_valid()) _cvcamDisconnectAllFilter(_cvcamSource[i].value());}// Make a builder graph objectstatic int _cvcamMakeGraph(){ HRESULT hr; // we have one already if(_cvcamGraphBuilder.is_valid()) return 1; hr = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&_cvcamGraphBuilder ); if(hr == S_OK) hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&_cvcamCapGraphBuilder); if(hr == S_OK) hr = _cvcamCapGraphBuilder->SetFiltergraph(_cvcamGraphBuilder.value()); return (hr == NOERROR) ? 1 : 0;}//connect source filter and add it to graph builder so we are ready to call the video source Property Pagestatic int _cvcamInitCapFilters(int camera){ HRESULT hr; IAMStreamConfig* pVSC; IBaseFilter* filter; AM_MEDIA_TYPE *pmt = NULL; wchar_t filterName[30]; //camera_index will point to the last source filter camera_index = camera; if(!_cvcamMakeGraph()) return -1; hr = _cvcamMonikers[camera]->BindToObject(0, 0, IID_IBaseFilter, (void **)&filter); if(hr == S_OK) _cvcamSource[camera]=filter; else { cvcam_properties[(uint)camera]._enabled = 0; return -2; } swprintf(filterName, L"Video Source %d", camera); hr = _cvcamGraphBuilder->AddFilter(_cvcamSource[camera].value(), filterName);//L"Video Source"); if(hr != NOERROR) return -3; hr = _cvcamCapGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, _cvcamSource[camera].value(), IID_IAMStreamConfig, (void **)&pVSC); if(hr != NOERROR) return -4; pVSC->GetFormat(&pmt); VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat); cvcam_properties[(uint)camera].srcwidth = pVih->bmiHeader.biWidth; cvcam_properties[(uint)camera].srcheight = abs(pVih->bmiHeader.biHeight); DeleteMediaType(pmt); pVSC->Release(); return 1;}/* The function creates a video source enumerator */static int _cvcamInitVideoSourceEnum(){ vector<SafeUnknown> _objects; if(FAILED(CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&_cvcamCreateDevEnum )) || !_cvcamCreateDevEnum.is_valid()) { return -1; } return 0;}/* The function iterates through all video sources and returns the number of them;if the input argument is nonzero, returns the pointer to IBaseFilter of the sourcethat was selected previously. If no source has been selected, selects the first one.The interface that is returned, should not be released by the user; it will be releasedautomatically.*/static int _cvcamInitVideoSource(IBaseFilter** filter){ if(!_cvcamCreateDevEnum.is_valid()) { int ret = _cvcamInitVideoSourceEnum(); if(ret < 0) return ret; } ASSERT(_cvcamCreateDevEnum.is_valid()); /* Create capture device enumerator*/ if(!_cvcamEnumMon.is_valid()) { HRESULT hr = _cvcamCreateDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &_cvcamEnumMon, 0); if( hr != NOERROR) return -1; } //called from cvcamGetCamerasCount for first time if(!_cvcamSource.size()) { uint count = cvcam_properties.size(); if(cvcam_properties.size() == 0) { /* Count the capture devices */ unsigned long fetched = 1; for(count = 0; fetched != 0; count++) { _cvcamEnumMon->Next(1, &_cvcamMon, &fetched); if(fetched) { _cvcamMonikers.push_back(_cvcamMon); SafePointer<IBaseFilter> pIBF(NULL); _cvcamSource.push_back(pIBF); } } count--; _cam_properties prop; cvcam_properties.assign(count, prop); } if(filter) { // find the user's camera selection for(uint i = 0; i < cvcam_properties.size(); i++) { if(cvcam_properties[i]._enabled) { camera_index = i; } } if(camera_index < 0) { /* select a video source and return a pointer to it */ for(uint i = 0; i < count; i++) { _cvcamMonikers[i]->BindToObject(0, 0, IID_IBaseFilter, (void **)filter); if(filter) { cvcam_properties[i]._enabled = 1; _cvcamSource[i]=*filter; camera_index = i; return count; } } } else { _cvcamMonikers[(uint)camera_index]->BindToObject(0, 0, IID_IBaseFilter, (void **)filter); if(filter) { _cvcamSource[(uint)camera_index]=*filter; } } *filter = 0; return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -