2016-09-19 14 views
0

우리는 비디오 통신 소프트웨어를 제작하고 있습니다. 우리는 라이브 스트림을 얻기 위해 Media Foundation을 사용하고 있습니다. 우리는 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 캡처로 다시 구성되어 정상적으로 작동합니다.

누군가가 동일한 문제로 인해 Media Foundation에 어려움을 겪었습니까?

답변

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를 사용합니다.

동결이 발생하는 경우 고정 위치를 나타내는 디버그 및 위치 스레드로 침입하는 것이 좋습니다.