使用IMFSourceReaderCallback检测USB摄像头断开连接

Detect USB camera disconnection using IMFSourceReaderCallback

本文关键字:断开 连接 摄像头 USB IMFSourceReaderCallback 检测 使用      更新时间:2023-10-16

我正在使用IMFSourceReaderCallback异步c++实现来读取和处理USB摄像头视频流

它工作得很好,只是如果相机被拔下(这种情况经常发生,因为我们使用了很多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轮询可用设备,这可能很耗时?

提前感谢!

这里解释了处理捕获设备丢失的推荐方法:处理视频设备丢失

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

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

完成后,请调用UnregisterDeviceNotification。