使用IMFSourceReaderCallback检测USB相机断开连接

时间:2015-12-17 10:45:17

标签: c++ ms-media-foundation

我正在使用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轮询可用设备,这可能很耗时......?

提前致谢!

1 个答案:

答案 0 :(得分:2)

此处介绍了处理捕获设备丢失的推荐方法:Handling Video Device Loss

您需要注册设备通知:RegisterDeviceNotification。你需要一个窗口句柄(HWND)。

在消息循环中,您将收到WM_DEVICECHANGE。你必须检查符号链接(它是USB摄像头吗?)。

完成后,请调用UnregisterDeviceNotification。