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

标签 c++ ms-media-foundation

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

提前致谢!

最佳答案

处理捕获设备丢失的推荐方法解释如下:Handling Video Device Loss

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

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

完成后,调用 UnregisterDeviceNotification。

关于c++ - 使用 IMFSourceReaderCallback 检测 USB 摄像头断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34332619/

相关文章:

ms-media-foundation - Media Foundation 是否适用于 Windows 7?

audio - IMFTransform SetInputType()/SetOutputType() 失败

c# - 使用 SharpDx 或 IMSourceReader 从 mp4 文件中读取第二个音轨流

c++ - Qt 读取访问冲突位于 :0x0, flags=0x0(第一次机会)

c++ - 为什么我不能在 .h 文件中声明 vector ?

c++ - 访问c++'s vector pointer'的元素

c++ - 从图像创建 MPEG4 视频时的分辨率问题 (Windows Media Foundation)

C++ read()-ing 从套接字到 ofstream

c++ - 在 for 循环中使用 end() 时无法访问双向链表中的最后一个元素

c++ - 获取 Microsoft Media Foundation 中相机的所有支持的 FPS 值