使用DirectShow枚举设备及播放的问题

死亡幻影 2006-01-12 01:58:32
在我用DirectShow枚举视频采集设备时,发现两个设备同时使用同一个Dll,(两个设备:一个是一般摄像头,一个是专用摄像头)。在两个设备同时插上的时候(都使用USB,专用摄像头有一个采集卡?或者是转换卡?),只能显示一般摄像头(家用摄像头),当把一般摄像头拔去时,能显示专用摄像头。
请问如何解决同时显示这个两个设备?
...全文
365 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhaojian999 2006-01-13
  • 打赏
  • 举报
回复
可以使用数组 这样看起来是一个 其实是两个了
ablewindy 2006-01-13
  • 打赏
  • 举报
回复
两个设备需要同时控制时(有可能一个在运行,一个停止),需要创建两个Graph,因为在一个Graph里面没有两个Control

你要验证能枚举几个设备,只要在GraphEdit中看看就知道了!
jemyzhang 2006-01-12
  • 打赏
  • 举报
回复
看你怎么做了,可以在一个graph里面加入两个source,建立两条链,这种情况必须使用两个renderer,而且要分别处理窗口消息。
简单一点的方法就是用两个graph。
死亡幻影 2006-01-12
  • 打赏
  • 举报
回复
由于自己一时大意,没有将列表框的下拉列表范围弄出来,搞出这样的问题,谢谢你的帮助,顺便问一下,是不是需要两个ISampleGrabberCB,如果两个设备需要同时控制时(有可能一个在运行,一个停止),是不是需要创建两个Graph?
死亡幻影 2006-01-12
  • 打赏
  • 举报
回复
我的意思是已经采用了上述的枚举过程,但是枚举中只出现了一个设备,而且不管是同时插上两个摄像头还是只插其中任何一个,都显示相同的设备名称,何如解决这个问题,能让插了这两个摄像头后同时显示两路视频信号。
zhaojian999 2006-01-12
  • 打赏
  • 举报
回复
如何选择一个视频捕捉设备,可以采用系统设备枚举,详细资料参见Using the System Device Enumerator 。enumerator可以根据filter的种类返回一个设备的monikers。Moniker是一个com对象,可以参见IMoniker的SDK。
对于捕捉设备,下面两种类是相关的。
CLSID_AudioInputDeviceCategory 音频设备
CLSID_VideoInputDeviceCategory 视频设备
下面的代码演示了如何枚举一个视频捕捉设备


ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
// Create the System Device Enumerator.
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr))
{
//创建一个枚举器,枚举视频设备
hr = pDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory,
&pEnum, 0);
}

IEnumMoniker接口pEnum返回一个IMoniker接口的列表,代表一系列的moniker,你可以显示所有的设备,然后让用户选择一个。
采用IMoniker::BindToStorage方法,返回一个IPropertyBag接口指针。然后调用IPropertyBag::Read读取moniker的属性。下面看看都包含什么属性
1 FriendlyName 是设备的名字
2 Description 属性仅仅适用于DV和D-VHS/MPEG摄象机,如果这个属性可用,这个属性更详细的描述了设备的资料
3DevicePath 这个属性是不可读的,但是每个设备都有一个独一无二的。你可以用这个属性来区别同一个设备的不同实例
下面的代码演示了如何显示遍历设备的名称 ,接上面的代码

HWND hList; // Handle to the list box.
IMoniker *pMoniker = NULL;
while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void**)(&pPropBag));
if (FAILED(hr))
{
pMoniker->Release();
continue; // Skip this one, maybe the next one will work.
}
// Find the description or friendly name.
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"Description", &varName, 0);
if (FAILED(hr))
{
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
}
if (SUCCEEDED(hr))
{
// Add it to the application's list box.
USES_CONVERSION;
(long)SendMessage(hList, LB_ADDSTRING, 0,
(LPARAM)OLE2T(varName.bstrVal));
VariantClear(&varName);
}
pPropBag->Release();
pMoniker->Release();
}

如果用户选中了一个设备调用IMoniker::BindToObject为设备生成filter,然后将filter加入到graph中。

IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
if (SUCCEEDED(hr))
{
hr = m_pGraph->AddFilter(pCap, L"Capture Filter");
}
3预览视频(Previewing Video)

为了创建可以预览视频的graph,可以调用下面的代码

ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder
// Initialize pBuild (not shown).
IBaseFilter *pCap; // Video capture filter.
/* Initialize pCap and add it to the filter graph (not shown). */
hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pCap, NULL, NULL);

2,553

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧