2015-12-17 2 views
2

Я использую IMFSourceReaderCallback asynchroneous C++ реализацию читать и обрабатывать видеопоток камеры USBОбнаружение USB камеры разъединения с помощью IMFSourceReaderCallback

Это работает отлично, за исключением того, что если камера получает отсоединена (что может произойти часто, так как мы используя многие 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 время от времени, что может быть много времени ...?

Спасибо заранее!

ответ

2

Рекомендуемый способ справиться с потерей устройства захвата объясняется здесь: Handling Video Device Loss

Вы должны зарегистрироваться для уведомления устройства: RegisterDeviceNotification. Вам нужен дескриптор окна (HWND).

В контуре сообщения вы получите WM_DEVICECHANGE. Вы должны проверить символическую ссылку (это USB-камера?).

Когда вы закончите, вызовите UnregisterDeviceNotification.

+0

Спасибо за ваше предложение, у меня нет в настоящее время дескриптора окна, чтобы передать эту функцию или цикл сообщений (плагин, на котором я работаю, выполняет только общий захват видео и преобразование в стандартное растровое изображение, которое может использоваться для автоматической обработки в другом плагин без даже окна приложения), но, по крайней мере, теперь я вижу, как это должно быть сделано в медиа-среде ... – Nicolas

+0

Привет. Использование дескриптора окна не означает, что ваш плагин должен быть оконным приложением. Вы можете создать и использовать дескриптор окна, не показывая его. – mofo77

Смежные вопросы