2016-09-19 32 views
0

ビデオ通信ソフトウェアを構築しています。私たちは、Media Foundationを使用してライブストリームを取得しています。 IMFSourceReadderを使用してキャプチャを実行します。Media Foundation Webcamライブキャプチャは低照度でフリーズします

呼び出しのシーケンスは次のようになります。

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出力)で時々カメラが凍結することがあります。通話の開始時または通話中にすぐに実行できます。それがフリーズしたとき

、2つのうちの1つは、(

  • m_reader-> ReadSample()MF_E_OPERATION_CANCELLEDエラーコードで繰り返し失敗し

  • m_reader-> ReadSample(どちらかわからない)発生する可能性があります)は、1秒間に80フレーム以上を生成し、同じ固定画像を生成します。

私たちが電話を切ると、デバイスはVGAキャプチャに再設定されて正常に動作します。

誰かが同じ問題でMedia Foundationに苦労しましたか?

答えて

0

ウェブカメラ「フリーズ」を書いたことがあります。低い明るさの画像をキャプチャしながら低いフレームレートを生成しました。その結果、Webカメラのコントローラーは、自動モードで写真マトリックスの展示に時間がかかります。これは、フレーム持続時間を増加させることによって画像の品質を向上させる。だから、ハードウェア部分の特色です。それは

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

質問の説明はあなたがややカオス的なやり方でやるという印象を残し、結果として生じるフリーズは必ずしもMedia Foundationやカメラによって引き起こされるとは限りません。

メディアソースとソースリーダーの使用は確かにカメラにアクセスする正しい方法であり、ビデオを同期的または非同期的にキャプチャする効率的な方法を提供します。

ただし、不完全なコードスニペットでは、メディアソースを作成した後にソースリーダーを作成した後、メディアソースを直接処理していることがわかります。さて、あなたはこれをするつもりはありません。ソースリーダーを作成すると、メディアソースが管理されます。Stop,Shutdownの呼び出しは不要です。あなたや他の方法を呼び出すと混乱が起こり、ソースの読者のふるまいが正しくない可能性があります。

つまり、メディアソースを扱うか、メディアセッションまたはソースリーダーに接続して、この上位レベルのAPIを使用します。

フリーズが発生した場合は、フリーズ位置を示すスレッドをデバッグして見つけてください。

関連する問題