我在SDK中直接显示时构建了AMCap示例。它能够处理2个或更多的网络摄像头,我如何修改程序让我同时使用它们...就像按下一个按钮,说'开始捕捉'并确保所有相机开始捕捉,一个按钮说'停止捕捉'来停止所有的相机。我希望来自不同相机的帧可以保存在不同的文件中。我是C++的新手,任何形式的帮助都会被赞赏!谢谢你的时间!AMCap中的多个网络摄像头
0
A
回答
0
使用GraphEdit工具。您可以在连接所有视频输入设备的情况下创建自己的图表。请参阅http://en.wikipedia.org/wiki/GraphEdit
0
如果您刚开始使用DirectShow编程,这可能有点爬山,但我希望这有些帮助,或者指向正确的方向。
M $ DN有一页描述how to select a capture device。这个例子很简单,所以我在下面提供了一个简单的实现。
理论是,您需要枚举CLSID_VideoInputDeviceCategory中的所有设备,并尝试为类别中的每个有效项目创建一个渲染图。
首先,我将向您展示用于迭代类别中设备名称的代码。下面是3个静态函数,您可以使用它们来迭代某个类别中的设备。一旦你已经添加了这些功能,你的项目,你可以通过调用下面的函数列出视频输入设备类别的设备:
ListDevicesInCategory(CLSID_VideoInputDeviceCategory);
好了,这里有三个功能。 ListDevicesInCategory()是工作发生的地方。它依赖于其他两种功能,FindDeviceInCategory()和CountDevicesInCategory()
#define RFAIL(x) { HRESULT hr = x; if(FAILED(hr)) {return hr;} }
static HRESULT FindDeviceInCategory(IBaseFilter** pSrc, const IID& cls, wstring& wFilterName,int devNum)
{
CComPtr<ICreateDevEnum> spDevEnum;
CComPtr<IEnumMoniker> spEnum;
int i;
RFAIL(spDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum));
RFAIL(spDevEnum->CreateClassEnumerator(cls, &spEnum, 0));
if(spEnum == 0)
return E_FAIL;
for(i = 0; i >= 0; i++)
{
CComPtr<IMoniker> spiMoniker;
if(spEnum->Next(1, &spiMoniker, 0) != S_OK)
return E_FAIL;
if(devNum == i)
{
CComVariant varName;
CComPtr<IPropertyBag> spiPropBag;
RFAIL(spiMoniker->BindToStorage(0, 0, IID_IPropertyBag,reinterpret_cast<void**>(&spiPropBag)));
RFAIL(spiPropBag->Read(L"FriendlyName", &varName, 0));
RFAIL(spiMoniker->BindToObject(0, 0, IID_IBaseFilter, reinterpret_cast<void**>(pSrc)));
wFilterName = V_BSTR(&varName);
varName.Clear();
return S_OK;
}
}
return E_FAIL;
}
static HRESULT CountDevicesInCategory(int *pCount, const IID& categoryClass)
{
// pass in a category class like CLSID_VideoInputDeviceCategory, writes the count of the number of filters in that category
// available on the local machine
HRESULT hr = S_OK;
CComPtr<ICreateDevEnum> spIDevEnum;
CComPtr<IEnumMoniker> spIEnum;
CComPtr<IMoniker> spIMoniker;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&spIDevEnum));
if(! SUCCEEDED(hr) || hr == S_FALSE)
{
*pCount = 0;
return hr;
}
hr = spIDevEnum->CreateClassEnumerator(categoryClass, &spIEnum, 0);
if(! SUCCEEDED(hr) || hr == S_FALSE)
{
*pCount = 0;
return hr;
}
if(spIEnum)
{
while(spIEnum->Next(1, &spIMoniker, 0) == S_OK)
{
(*pCount) ++;
spIMoniker.Detach();
}
}
return S_OK;
}
static HRESULT ListDevicesInCategory(const GUID & cls)
{
CComPtr<IBaseFilter> spSource;
wstring * psNextFilter = NULL;
int nDeviceNum = 0;
int nTotalNumDevices = 0;
HRESULT hr = S_OK;
bool bComplete = false;
DeviceNames CaptureDeviceNames;
if(FAILED(CountDevicesInCategory(&nTotalNumDevices, (IID)cls)))
bComplete = TRUE;
if(nTotalNumDevices == 0)
bComplete = TRUE;
while(! bComplete)
{
psNextFilter = new std::wstring;
hr = FindDeviceInCategory(&spSource, (IID)cls, *psNextFilter, nDeviceNum++);
if(SUCCEEDED(hr) && spSource )
{
if (*psNextFilter)
{
wcout << *psNextFilter << endl;
delete *psNextFilter;
psNextFilter = NULL;
}
spSource.Release();
spSource = NULL;
}
else
bComplete = TRUE;
}
return S_OK;
}
一旦你确定了你所感兴趣的类别的项目,您可以用IGraphBuilder::AddFilter通话将其添加到图。
要为图表添加过滤器,您首先需要获得一个IBaseFilter *到该过滤器。我还有一个功能可以让你做到这一点。
定义一个IBaseFilter智能指针:
CComPtr<IBaseFilter> spSource;
连接到过滤器:
m_spSource.Attach(
GetFilter(CLSID_VideoInputDeviceCategory, CComBSTR(L"Osprey-450e Video Device 1A"))
);
下面是最后一个功能 - 用getFilter:
static IBaseFilter * GetFilter(REFCLSID clsidDeviceClass, CComBSTR & sName)
{
HRESULT hr;
IBaseFilter * pRetFilter = NULL;
ICreateDevEnum * pSysDevEnum = NULL;
IEnumMoniker * pEnum = NULL;
IMoniker * pMoniker = NULL;
int nSameSrcCounter = 0;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);
if(pSysDevEnum)
hr = pSysDevEnum->CreateClassEnumerator(clsidDeviceClass, &pEnum, 0);
if (hr != S_OK)
return NULL;
USES_CONVERSION;
while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
{
IPropertyBag *pPropBag = NULL;
VARIANT var;
VariantInit(&var);
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
if (SUCCEEDED(hr))
{
if(sName == OLE2T(var.bstrVal))
{
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pRetFilter);
if (FAILED(hr))
pRetFilter = NULL;
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
break;
}
}
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
}
pSysDevEnum->Release();
pEnum->Release();
return pRetFilter;
}
相关问题
- 1. AS3多个网络摄像头不显示第3个网络摄像头
- 2. 网络摄像头流对等网络
- 3. 网络摄像头捕捉
- 4. iPhone网络摄像头Feed
- 5. 网络摄像头校准
- 6. 网络摄像头问题与jQuery网络摄像头在Internet Explorer中
- 7. VB.net中的网络摄像头接口
- 8. JavaApplet中的网络摄像头
- 9. OpenCV Python和一个网络摄像头
- 10. 使用iPhone摄像头作为PC上的网络摄像头
- 11. 在mvc3中集成网络摄像头
- 12. 检查网络摄像头摄像头设备GNOME库
- 13. 作为网络摄像头访问手机摄像头C++
- 14. 在网站集成网络摄像头
- 15. 从网络摄像头图像保存
- 16. 从网络摄像头捕捉图像
- 17. 从网络摄像头捕捉图像
- 18. 从网络摄像头捕获图像
- 19. capDlgVideoSource多个网络摄像头的问题
- 20. 高效的网络摄像头库
- 21. 网络摄像头与Arduino的接口
- 22. 来自网络摄像头的bytearray
- 23. 网络摄像头解析检测
- 24. 网络摄像头“仍销”捕获
- 25. 从网络摄像头获取输入
- 26. 显示网络摄像头蟒蛇
- 27. C#控制网络摄像头#
- 28. 设置网络摄像头属性
- 29. 访问网络摄像头使用vb.net
- 30. 网络摄像头流和OpenCV - 蟒蛇
的GraphEdit是创建一个良好的原型开发工具图表,但我认为OP想要在代码中实现这一点。 GraphStudio是GraphEdit的更好选择;)http://blog.monogram.sk/janos/tools/monogram-graphstudio/ – 2010-11-29 21:46:45