📄 cvcam.cpp
字号:
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 source
that 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 released
automatically.*/
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;
}
return count;
}
else
{
//called from cvcamGetCamerasCount for second time and more
if(!filter)
return cvcam_properties.size();
for(uint i = 0; i < cvcam_properties.size(); i++)
{
if(cvcam_properties[i]._enabled)
{
/* Initialize the camera */
_cvcamMonikers[i]->BindToObject(0, 0, IID_IBaseFilter, (void **)filter);
if(filter)
{
_cvcamSource[i]=*filter;
camera_index = i;
return i;
}
}
}
/* No camera has been selected */
*filter = 0;
return -1;
}
}
/* Creates a window for DS rendering */
HWND _cvcamCreateWindow()
{
cvNamedWindow("cvcam window", 0);
return (HWND)cvGetWindowHandle("cvcam window");
}
/* Returns the actual number of currently available cameras */
CVCAM_API int cvcamGetCamerasCount()
{
int n = _cvcamInitVideoSource(0);
return (n>0)?n:0;
}
/* Summons the video format property page */
static void _cvcamSummonPinPropPage(int camera)
{
if(!cvcam_properties[camera]._enabled)
return;
//Find the output pit that is connected to the next filter...
CAUUID uuID;
ISpecifyPropertyPages* pspp = 0;
int fcvcamInit = 0;
OAFilterState state = State_Stopped;
//if _cvcamMediaControl is valid, it means Graph has already been builded
//therefore we have to disconnect all filters first
if(_cvcamMediaControl.is_valid())
{
fcvcamInit = 1;
//keep graph state before disconnect it, os we can restart from current state
_cvcamMediaControl->GetState(0, &state);
//disconnect graph
_cvcamTearDownGraph();
}
IBaseFilter* filter = _cvcamSource[camera].value();
IPin* pPin = get_source_pin(_cvcamSource[camera].value(), PINDIR_OUTPUT);
if(!pPin)
pPin=get_pin(filter, PINDIR_OUTPUT);
if(!pPin)
return;
pPin->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pspp);
if(!pspp)
return;
pspp->GetPages(&uuID);
pspp->Release();
OleCreatePropertyFrame(NULL, 0, 0, L"Video Source", 1,
(IUnknown**)&pPin, uuID.cElems, uuID.pElems,
0, 0, NULL);
CoTaskMemFree(uuID.pElems);
pPin->Release();
//store this video source resolution
IAMStreamConfig* pVSC;
AM_MEDIA_TYPE *pmt = NULL;
_cvcamCapGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, _cvcamSource[camera].value(),
IID_IAMStreamConfig, (void **)&pVSC);
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();
// take them back to where they were before this function was called
if(fcvcamInit)
{
cvcamInit();
if(state == State_Running)
cvcamStart();
}
}
static void _cvcamSetVideoFormat(int camera, void* value)
{
if(!cvcam_properties[camera]._enabled)
return;
VidFormat* vidFmt = (VidFormat*)value;
int fcvcamInit = 0;
OAFilterState state = State_Stopped;
if(_cvcamMediaControl.is_valid())
{
fcvcamInit = 1;
_cvcamMediaControl->GetState(0, &state);
_cvcamTearDownGraph();
}
IAMStreamConfig* pVSC;
AM_MEDIA_TYPE *pmt = NULL;
_cvcamCapGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, _cvcamSource[camera].value(),
IID_IAMStreamConfig, (void **)&pVSC);
VIDEO_STREAM_CONFIG_CAPS scc;
int piCount, piSize;
HRESULT hr = pVSC->GetNumberOfCapabilities(&piCount, &piSize);
if(hr == S_OK)
{
for(int i = 0; i < piCount; i++)
{
pVSC->GetStreamCaps(i, &pmt, reinterpret_cast<BYTE*>(&scc));
VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat);
if(pVih->bmiHeader.biWidth == vidFmt->width && pVih->bmiHeader.biHeight == vidFmt->height)
{
if( vidFmt->framerate > 0 )
pVih->AvgTimePerFrame = (LONGLONG)(10000000 / vidFmt->framerate);
pVSC->SetFormat(pmt);
cvcam_properties[(uint)camera].srcwidth = pVih->bmiHeader.biWidth;
cvcam_properties[(uint)camera].srcheight = abs(pVih->bmiHeader.biHeight);
DeleteMediaType(pmt);
break;
}
DeleteMediaType(pmt);
}
}
pVSC->Release();
// take them back to where they were before this function was called
if(fcvcamInit)
{
cvcamInit();
if(state == State_Running)
cvcamStart();
}
}
/* Summons the video format property page */
static void _cvcamSummonFilterPropPage(int camera)
{
if(!cvcam_properties[camera]._enabled)
return;
//Find the output pit that is connected to the next filter...
CAUUID uuID;
ISpecifyPropertyPages* pspp = 0;
//IBaseFilter* filter =_cvcamSource[camera].value();
//IMoniker* mon = _cvcamMonikers[camera].value();
//_cvcamProxyTrans->QueryInterface(IID_IBaseFilter, (void**)&filter);
//IPin* pProxyPin = get_pin(filter, PINDIR_INPUT);
//pProxyPin->Disconnect();
//_cvcamMonikers[0]->BindToObject(0, 0, IID_IBaseFilter, (void **)&filter);
//IMoniker* mon = _cvcamMonikers[camera].value();
//IMoniker* pmon;
//_cvcamMonikers[camera]->QueryInterface(IID_IMoniker,(void**)&pmon);
//pmon->BindToStorage(0,0,IID_IBaseFilter, (void **)&filter);
//BindMoniker(mon,0,IID_IBaseFilter,(void **)&filter);
//filter= _cvcamSource.value;
/*
IPropertyBag *pBag;
HRESULT hr = mon->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
pBag->Release();
}
*/
//BindMoniker(mon,0,IID_IBaseFilter,(void **)&filter);
//mon->BindToObject(0,0,IID_IBaseFilter, (void **)&filter);
//IPin* pPin = get_source_pin(_cvcamSource[camera].value(), PINDIR_OUTPUT);
//IPin* pPin = get_source_pin(filter, PINDIR_OUTPUT);
//if(!pPin)
// pPin=get_pin(filter, PINDIR_OUTPUT);
//if(!pPin)
// return;
IBaseFilter* bf = _cvcamSource[camera].value();
// IUnknown** ppobject = (IUnknown**)&pPin;
bf->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pspp);
if(!pspp)
return;
pspp->GetPages(&uuID);
pspp->Release();
/* Disconnect the pin to enable possible changes in the output format... */
OAFilterState state = State_Stopped;
if(_cvcamMediaControl.is_valid())
_cvcamMediaControl->GetState(0, &state);
// if(state != State_Stopped)
// cvcamStop();
/*
IPin* pTempPin =
if(pPin)
*/
// pPin->Disconnect();
//IBaseFilter* pFilter;
//_cvcamProxyTrans->QueryInterface(IID_IBaseFilter, (void**)&pFilter);
//IPin* pProxyPin = get_pin(pFilter, PINDIR_INPUT);
// pProxyPin->Disconnect();
OleCreatePropertyFrame(NULL, 0, 0, L"Video Source", 1,
(IUnknown**)&bf, uuID.cElems, uuID.pElems,
0, 0, NULL);
//_cvcamGraphBuilder->Connect(pSPin, pProxyPin);
// if(state == State_Running)
//_cvcamMediaControl->Run();
// cvcamStart();
}
#define CHECK_CAMERA(p) if((p) >= cvcam_properties.size()) return -1;
#define CHECK_ZERO if(!value) return -1;
#define CHECK_POSITIVE(p) if((p) < 0) return -1;
/* get/set the property of the camera. returns 0 if the property is not supported */
CVCAM_API int cvcamGetProperty(int camera, const char* property, void* value)
{
if (camera>=AVIS_START)
{
return cvcamAVIGetProperty(camera,property,value);
}
CHECK_CAMERA((uint)camera);
if(strcmp(property, CVCAM_PROP_ENABLE) == 0)
{
CHECK_ZERO(value);
*(int*)value = cvcam_properties[(uint)camera]._enabled;
return 0;
}
else if(strcmp(property, CVCAM_PROP_RENDER) == 0)
{
CHECK_ZERO(value);
*(int*)value = cvcam_properties[(uint)camera].render;
return 0;
}
else if(strcmp(property, CVCAM_PROP_WINDOW) == 0)
{
CHECK_ZERO(value);
*(int*)value = cvcam_properties[(uint)camera].window;
return 0;
}
else if (strcmp(property, CVCAM_RNDWIDTH) == 0)
{
CHECK_ZERO(value);
*(int*)value = cvcam_properties[(uint)camera].rndwidth;
return 0;
}
else if (strcmp(property, CVCAM_RNDHEIGHT) == 0)
{
CHECK_ZERO(value);
*(int*)value = cvcam_properties[(uint)camera].rndheight;
return 0;
}
else if (strcmp(property, CVCAM_SRCWIDTH) == 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -