首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >媒体基金会网络摄像头在弱光条件下的实时捕捉冻结

媒体基金会网络摄像头在弱光条件下的实时捕捉冻结
EN

Stack Overflow用户
提问于 2016-09-19 20:07:39
回答 2查看 659关注 0票数 0

我们正在建造一个视频通讯软件。我们正在使用媒体基金会获得直播流。我们使用IMFSourceReadder来执行捕获。

呼叫顺序如下:

代码语言:javascript
运行
复制
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);    

然后,我们开始在一个单独的线程中同步读取帧。

代码语言:javascript
运行
复制
m_reader->ReadSample()

当我们需要停止设备或重新配置它时,我们停止线程(通过设置一个标志和退出线程)。我们称以下为

代码语言:javascript
运行
复制
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捕获并正常工作。

有人在同一问题上与媒体基金会做斗争吗?

EN

回答 2

Stack Overflow用户

发布于 2016-09-19 22:50:14

你写的网络相机"freez“-产生低帧率,而捕获图像的低光条件。结果表明,网络摄像机控制器在自动模式下对图像矩阵的描述需要更多的时间。它允许通过增加帧持续时间来提高图像质量。因此,它是硬件部分的特点。在参数的手动模式下,可以将摄像机的这种行为从自动模式切换到手动模式。

代码语言:javascript
运行
复制
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;
}

其中:

代码语言:javascript
运行
复制
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

票数 0
EN

Stack Overflow用户

发布于 2016-09-20 08:31:39

问题描述给人的印象是,你以一种有点混乱的方式做事,由此产生的冻结不一定是由媒体基金会或照相机造成的。

使用媒体源和源读取器当然是访问摄像机的正确方式,它提供了同步和异步捕获视频的有效方法。

但是,不完整的代码片段显示您创建了一个媒体源,然后创建了源代码阅读器,然后继续直接处理媒体源。你不应该这么做的。一旦创建了源读取器,它将为您管理媒体源:您不需要StopShutdown调用。调用该方法和其他方法可能会导致混淆,从而导致不正确的源读取器行为。

也就是说,要么处理媒体源,要么将其插入media会话或source并使用此更高级别的API。

还请注意,如果/当您经历冻结时,您有兴趣使用调试过的线程并定位指示冻结位置的线程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39581243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档