Direct Show 驱动摄像头,棘手(高手进)

chenice9999 2011-10-28 04:42:31
我用DirectShow进行对摄像头的驱动遇到一个问题,假如PC机上有摄像头A、摄像头B、摄像头C,摄像头A被其他应用程序给占用了,其他两个摄像头处于闲置的状态,我的程序功能是开打一个可用的摄像头,根据日志,程序对于设备的遍历顺序是A->B->C,发现B始终无法成功打开,C可以成功被使用。可以保证所有的设备都是正常的,并且当PC机上只存在单独摄像头的时候,都是可以正常工作的。
我找不到原因来解决上述问题,检查代码并没有发现什么问题。

代码如下:
BOOL CCameraDS::CameraOpenUsable()
{
if ( m_enable )
{
return m_enable;
}

int num = 0;
CComPtr<ICreateDevEnum> pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if ( hr != S_OK )
{
return m_enable;
}

CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
if ( hr != S_OK )
{
return m_enable;
}

ULONG cFetched;
IMoniker* pM = NULL;
pEm->Reset();

IPropertyBag* pPropBag = NULL;

while( pEm->Next(1, &pM, &cFetched) == S_OK )
{
num++;

SAFE_RELEASE( pPropBag );
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag );
if ( SUCCEEDED(hr) )
{
CameraResRelease();

hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_sourceBaseFilter);
if ( FAILED(hr) )
{
continue;
}

if ( !CameraResInitialize() )
{
continue;
}
else if ( !CameraSetMediaType() )
{
continue;
}
else if ( !CameraRun() )
{
continue;
}
m_enable = TRUE;
break;//找到一个可以成功打开使用的摄像头,退出。
}
}

SAFE_RELEASE( pPropBag );
SAFE_RELEASE( pM );

return m_enable;
}
BOOL CCameraDS::CameraResInitialize()
{
BOOL ret = FALSE;
HRESULT hresult;

hresult = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_graphBuilder);
if (FAILED(hresult))
{
goto exit;
}

hresult = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_captureGraphBuilder2);
if (FAILED(hresult))
{
goto exit;
}

hresult = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&m_sampleGrabberBaseFilter);
if (FAILED(hresult))
{
goto exit;
}

hresult = m_sampleGrabberBaseFilter->QueryInterface(IID_ISampleGrabber, (void **)&m_sampleGrabber);
if (FAILED(hresult))
{
goto exit;
}

hresult = m_graphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_mediaControl);
if (FAILED(hresult))
{
goto exit;
}

hresult = m_captureGraphBuilder2->SetFiltergraph(m_graphBuilder);
if (FAILED(hresult))
{
goto exit;
}

hresult = m_graphBuilder->AddFilter(m_sourceBaseFilter, L"Video Capture");
if (FAILED(hresult))
{
goto exit;
}

hresult = m_graphBuilder->AddFilter(m_sampleGrabberBaseFilter, L"Sample Grabber");
if (FAILED(hresult))
{
goto exit;
}

hresult = m_sampleGrabber->SetBufferSamples(TRUE);
if (FAILED(hresult))
{
goto exit;
}

hresult = m_sampleGrabber->SetOneShot(FALSE);
if (FAILED(hresult))
{
goto exit;
}

m_sampleGrabberCallback = new SampleGrabberCallback( this );
if (m_sampleGrabberCallback == NULL)
{
goto exit;
}

hresult = m_sampleGrabber->SetCallback(m_sampleGrabberCallback, 1);
if (FAILED(hresult))
{
goto exit;
}

ret = TRUE;

exit:

return ret;
}

BOOL CCameraDS::CameraSetMediaType()
{
BOOL ret = FALSE;
HRESULT hresult;

AM_MEDIA_TYPE am_media_type;
ZeroMemory(&am_media_type, sizeof(am_media_type));
am_media_type.majortype = MEDIATYPE_Video;
am_media_type.subtype = MEDIASUBTYPE_RGB32;
am_media_type.formattype = FORMAT_VideoInfo;

hresult = m_sampleGrabber->SetMediaType(&am_media_type);
if (FAILED(hresult))
{
goto exit;
}

hresult = m_captureGraphBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_sourceBaseFilter, NULL, m_sampleGrabberBaseFilter);
if (FAILED(hresult))
{
goto exit;
}

ZeroMemory(&am_media_type, sizeof(am_media_type));
hresult = m_sampleGrabber->GetConnectedMediaType(&am_media_type);
if (FAILED(hresult))
{
goto exit;
}

ret = TRUE;

exit:
return ret;
}

BOOL CCameraDS::CameraRun()
{
BOOL ret = FALSE;

if ( m_mediaControl )
{
HRESULT hresult = m_mediaControl->Run();//打开摄像头A,B,Run 失败
if ( SUCCEEDED(hresult) )
{
ret = TRUE;
}
}

return ret;
}

希望某位高人可以指点一二,感激不尽!!!
...全文
172 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenice9999 2011-10-31
  • 打赏
  • 举报
回复
m_mediaControl->Run();不成功。所有的resouce都初始化成功了。
星羽 2011-10-29
  • 打赏
  • 举报
回复
代码好长,楼主单步调试过没,看看那一步出的问题

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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