我们正在建造一个视频通讯软件。我们正在使用媒体基金会获得直播流。我们使用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输出)。这种情况可以在通话开始时或通话期间立即发生。
当它结冰时,会发生两种情况之一(不确定哪一种)
当我们挂断设备时,设备被重新配置为VGA捕获并正常工作。
有人在同一问题上与媒体基金会做斗争吗?
发布于 2016-09-19 22:50:14
你写的网络相机"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;
  };您可以在网站上找到更多代码:
在Windows 7和Windows 8上从网络摄像机获取实时视频
然而,使用IMFSourceReader可能并不有效。Media模型使用异步交互--在将请求发送到媒体之后,源代码必须侦听,使用新框架或其他信息从媒体源响应。直接调用m_reader->ReadSample()的方法不能有效--您将面对它。方法m_reader->ReadSample()可以有效地从视频文件中读取帧,而延迟可能很低,但是对于web摄像机,我可以建议使用拓扑-会话绑定,就像在我的代码在Windows 7和Windows 8上从网络摄像机获取实时视频中一样。
你好,Evgeny Pereguda
发布于 2016-09-20 08:31:39
问题描述给人的印象是,你以一种有点混乱的方式做事,由此产生的冻结不一定是由媒体基金会或照相机造成的。
使用媒体源和源读取器当然是访问摄像机的正确方式,它提供了同步和异步捕获视频的有效方法。
但是,不完整的代码片段显示您创建了一个媒体源,然后创建了源代码阅读器,然后继续直接处理媒体源。你不应该这么做的。一旦创建了源读取器,它将为您管理媒体源:您不需要Stop、Shutdown调用。调用该方法和其他方法可能会导致混淆,从而导致不正确的源读取器行为。
也就是说,要么处理媒体源,要么将其插入media会话或source并使用此更高级别的API。
还请注意,如果/当您经历冻结时,您有兴趣使用调试过的线程并定位指示冻结位置的线程。
https://stackoverflow.com/questions/39581243
复制相似问题