我正在使用IMFSourceReaderCallback asynchroneous c ++实现来读取和处理USB Camera视频流
它工作正常,但如果相机被拔掉(这可能经常发生,因为我们使用了许多USB中继器),我没有收到通知。以下是代码的摘录:
HRESULT CMFSourceReaderCallback::OnEvent(DWORD dwStreamIndex, IMFMediaEvent *pEvent)
{
// I was hoping to get an Event here if I lost the camera, but no...
// The break point nether hits, and from EvilCorp documentation, there is no such event type
return S_OK;
}
HRESULT CMFSourceReaderCallback::OnReadSample(
HRESULT hrStatus,
DWORD dwStreamIndex,
DWORD dwStreamFlags,
LONGLONG llTimestamp,
IMFSample *pSample)
{
bool isGrabbing = false;
try
{
if (SUCCEEDED(hrStatus))
{
if (pSample)
{
// Do something with the sample.
IMFMediaBuffer * pMediaBuffer;
HRESULT hr;
hr = pSample->ConvertToContiguousBuffer(&pMediaBuffer);
if (FAILED(hr))
{
// Inform other thread of the disconnection
//...
return S_OK;
}
byte *imgBuff;
DWORD buffCurrLen = 0;
DWORD buffMaxLen = 0;
pMediaBuffer->Lock(&imgBuff, &buffMaxLen, &buffCurrLen);
// Process image byte buffer
pMediaBuffer->Unlock();
pMediaBuffer->Release();
}
}
else
{
// Inform other thread of the disconnection
//...
return S_OK;
}
if ((MF_SOURCE_READERF_ENDOFSTREAM & dwStreamFlags) ||
(MF_SOURCE_READERF_ERROR & dwStreamFlags))
{
// Inform other thread of the disconnection
//...
return S_OK;
}
} catch (std::exception &ex )
{
// Inform other thread of the disconnection
//...
return S_OK;
}
// check if other thread has not requested a stop
isGrabbing = ...;
if (isGrabbing)
{
//Re-arm callback
HRESULT hr = _dataStruct->Reader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
0, NULL, NULL, NULL, NULL);
if (FAILED(hr))
{
// Inform other thread of the disconnection
//...
return S_OK;
}
}
return S_OK;
}
有没有办法通过IMFSourceReader获取此类通知,而不必担心随时使用MFEnumDeviceSources轮询可用设备,这可能很耗时......?
提前致谢!
答案 0 :(得分:2)
此处介绍了处理捕获设备丢失的推荐方法:Handling Video Device Loss
您需要注册设备通知:RegisterDeviceNotification。你需要一个窗口句柄(HWND)。
在消息循环中,您将收到WM_DEVICECHANGE。你必须检查符号链接(它是USB摄像头吗?)。
完成后,请调用UnregisterDeviceNotification。