2016-09-19 27 views
0

我們正在構建一個視頻通信軟件。我們正在使用媒體基金會獲取實況流。我們使用IMFSourceReadder來執行捕獲。媒體基金會攝像頭實況捕獲在低光照條件下死機

調用的順序是這樣的:

hr = pAttributes->SetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, m_pwszSymbolicLink); 

hr = MFCreateDeviceSourceActivate(pAttributes, &avdevice); 

hr = avdevice->ActivateObject(__uuidof(IMFMediaSource), (void**) &m_mediaSource); 

hr = m_mediaSource->CreatePresentationDescriptor(&pPD); 

hr = pPD->GetStreamDescriptorByIndex(m_streamIdx, &fSelected, &pSD); 

hr = 

// we select the best native MediaType enumerating the source reader 
pHandler->SetCurrentMediaType(m_bestNativeType); 

hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, FALSE); 
hr = pAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, TRUE); 

hr = MFCreateSourceReaderFromMediaSource(m_mediaSource, pAttributes, &m_reader);  

然後我們開始在一個單獨的線程使用

m_reader->ReadSample() 

同步讀取幀當我們需要停止設備或重新配置,我們停止線程(通過設置一個標誌並退出線程)。我們稱之爲

hr = m_mediaSource->Stop(); 
m_mediaSource->Shutdown(); 
SafeRelease(&m_mediaSource); 
SafeRelease(&m_reader); 

該軟件可以外撥電話。在那裏,它以VGA格式捕捉網絡攝像頭視頻並將其顯示在屏幕上。在通話中,它根據相關的通話質量選擇最佳的捕獲格式並重新開始捕獲。

我們遇到的問題如下:有些相機有時會在低光照條件下凍結(低fps輸出)。它可以在通話開始或通話過程中立即發生。

在凍結,兩件事情之一可能發生(不知道哪一個)

  • m_reader-> ReadSample()與MF_E_OPERATION_CANCELLED錯誤代碼反覆失敗

  • m_reader-> ReadSample( )通常每秒產生超過80幀,產生相同的凍結圖像。

當我們掛斷設備重新配置回VGA捕獲,並正常工作。

有人在媒體基礎上就同一問題掙扎嗎?

回答

0

您寫下了網絡攝像頭「freez」 - 在低光照條件下捕捉圖像時產生低幀率。網絡攝像機的控制器在自動模式下花費更多的時間來展示照片矩陣。它允許通過增加幀持續時間來提高圖像的質量。所以,它是硬件部分的特色。它可以對參數

的手動模式
Code::Result VideoCaptureDevice::setParametrs(CamParametrs parametrs){ 
ResultCode::Result result = ResultCode::VIDEOCAPTUREDEVICE_SETPARAMETRS_ERROR; 

if(pLocalSource) 
{ 
    unsigned int shift = sizeof(Parametr); 

    Parametr *pParametr = (Parametr *)(&settings); 

    Parametr *pPrevParametr = (Parametr *)(&prevParametrs); 

    CComPtrCustom<IAMVideoProcAmp> pProcAmp; 


    HRESULT hr = pLocalSource->QueryInterface(IID_PPV_ARGS(&pProcAmp)); 

    if (SUCCEEDED(hr)) 
    { 
     for(unsigned int i = 0; i < 10; i++) 
     { 
      if(pPrevParametr[i].CurrentValue != pParametr[i].CurrentValue || pPrevParametr[i].Flag != pParametr[i].Flag) 
       hr = pProcAmp->Set(VideoProcAmp_Brightness + i, pParametr[i].CurrentValue, pParametr[i].Flag); 

     } 
    } 
    else 
    { 
     result = ResultCode::VIDEOCAPTUREDEVICE_SETPARAMETRS_SETVIDEOPROCESSOR_ERROR; 

     goto finish; 
    } 

    CComPtrCustom<IAMCameraControl> pProcControl; 

    hr = pLocalSource->QueryInterface(IID_PPV_ARGS(&pProcControl)); 

    if (SUCCEEDED(hr)) 
    { 
     for(unsigned int i = 0; i < 7; i++) 
     { 
      if(pPrevParametr[10 + i].CurrentValue != pParametr[10 + i].CurrentValue || pPrevParametr[10 + i].Flag != pParametr[10 + i].Flag) 
      hr = pProcControl->Set(CameraControl_Pan+i, pParametr[10 + i].CurrentValue, pParametr[10 + i].Flag);      
     } 

    } 
    else 
    { 
     result = ResultCode::VIDEOCAPTUREDEVICE_SETPARAMETRS_SETVIDEOCONTROL_ERROR; 

     goto finish; 
    } 

    result = ResultCode::OK; 

    prevParametrs = parametrs.settings; 
}finish: 
if(result != ResultCode::OK) 
    DebugPrintOut::getInstance().printOut(L"VIDEO CAPTURE DEVICE: Parametrs of video device cannot be set!!!\n"); 

return result; 
} 

從自動模式切換照相機的這種行爲,其中:

struct Parametr 
{ 
long CurrentValue; 

long Min; 

long Max; 

long Step; 

long Default; 

long Flag; 

Parametr(); 
}; 

    struct CamParametrs 
    { 
    Parametr Brightness; 
    Parametr Contrast; 
    Parametr Hue; 
    Parametr Saturation; 
    Parametr Sharpness; 
    Parametr Gamma; 
    Parametr ColorEnable; 
    Parametr WhiteBalance; 
    Parametr BacklightCompensation; 
    Parametr Gain; 


    Parametr Pan; 
    Parametr Tilt; 
    Parametr Roll; 
    Parametr Zoom; 
    Parametr Exposure; 
    Parametr Iris; 
    Parametr Focus; 
    }; 

更多的代碼,你可以在網站上找到:
Capturing Live-video from Web-camera on Windows 7 and Windows 8

然而,使用IMFSourceReader可能無效。 Media Foundation模型使用異步交互 - 將請求發送到媒體源代碼後,必須使用新幀或其他信息監聽媒體源的響應。直接撥打電話m_reader->ReadSample()的方法不能有效 - 您面對它。方法m_reader->ReadSample()可以從視頻文件閱讀框有效,而延遲非常低,但是對於網絡攝像頭我將建議使用的拓撲結構 - 會話綁定,就像在我的代碼Capturing Live-video from Web-camera on Windows 7 and Windows 8

問候, 葉夫根尼·Pereguda

+0

有趣的是,我必須仔細閱讀您的代碼示例,因爲這種方法相當令人不安,但確實很有趣。 –

0

的問題描述留下的印象是,你以一種有些混亂的方式來做事情,並且由此產生的凍結不一定是媒體基金會或相機造成的。

使用媒體源和源讀取器當然是訪問攝像機的正確方式,它提供了同步和異步捕獲視頻的有效方法。

但是,您的不完整代碼片段顯示您創建了一個媒體源,然後創建了源讀取器,然後您繼續直接處理媒體源。那麼,你不應該這樣做。一旦您創建了源讀取器,它將爲您管理媒體源:您不需要Stop,Shutdown調用。您的調用和其他方法可能會導致混淆,導致源讀取器行爲不正確。

也就是說,您要麼處理媒體源,要麼將其插入媒體會話或源讀取器並使用此更高級別的API。

另請注意,如果/當您遇到凍結,您有興趣進行調試並找到指示凍結位置的線程。