IMediaControl.Run() 成功静态相机预览为黑色

IMediaControl.Run() is successful still camera preview is black

通过使用 Directshow.NET 和 c#,我开发了一个显示相机预览的应用程序。自 1 年以来一切正常,但突然客户抱怨黑色相机预览。

在深入研究问题后,我了解到 防病毒程序正在阻止我的应用程序使用相机 。将我的应用程序添加到该防病毒程序的排除列表中后,应用程序可以像以前一样工作。

在程序中,我已经为 HRESULT 正确抛出异常,如下所示:

try
{
    //FilterGraph creation
    //CaptureGraphBuilder2 creation
    //AddSourceFilterForMoniker()
    //SampleGrabber configuration
    //VMR9 configuration

    hr = mediaControl.Run();
    DsError.ThrowExceptionForHR(hr);
}
catch(Exception ex)
{
    //logging part
}

日志中仍然没有任何内容,即使我在该特定机器上调试该应用程序,但程序成功执行。 所以问题是,为了避免此类问题,我如何才能确保相机预览确实已启动? 有什么方法可以检查流是否未被阻止。

黑色相机预览不一定是 运行 图形失败的症状。例如,无论这是否是您的问题,尤其是过滤图。显示 IP 摄像机馈送可能会进入 运行ning 状态,视频渲染器会期望帧被接收并分别处理到它的显示就绪状态。但是,如果防病毒软件或防火墙阻止流量,则视频帧永远不会到达渲染器。虽然过滤图 运行ning 没有失败或错误。

您通常希望从过滤器图中的过滤器请求一些统计信息,以证明正在进行有效负载处理。这可能包括:

  • 来自源过滤器的查询它实际产生数据
  • 解码器等中间组件能够提供已处理数据的统计信息
  • 管道中的 Sample Grabber 过滤器,带有未修改的回调计数样本
  • 来自视频渲染器的统计请求(例如 IQualProp::get_FramesDrawn“...检索自流式传输开始以来实际绘制的帧数”)
  • 尝试从视频渲染器中读回当前显示的视频帧的快照

一旦您看到数据正在随着时间的推移进行处理,您就知道不会发生意外锁定。

您可以订阅事件MediaElementBase.NewAllocatorFrame,您可以知道相机源过滤器是否有效。

我建议您将 DirectShow 过滤图添加到 运行 对象 Table,允许 GraphEdit 在远程过滤图上 "spy"。 这有助于检查图形连接、过滤状态、引脚属性并更正或优化它以解决问题。

构建后 and/or 开始捕获图形只需调用此方法即可通过 Graphedit 应用程序选择图形和过滤状态。

///
/// \fn AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
/// 
HRESULT CCapture::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
    IMoniker * pMoniker;
    IRunningObjectTable *pROT;
    WCHAR wsz[128];
    HRESULT hr;
    ULONG ret = 0;

    if (FAILED(GetRunningObjectTable(0, &pROT)))
        return E_FAIL;

    wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph,
        GetCurrentProcessId());

    hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) {
        hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
        ret = pMoniker->Release();
    }   
    pROT->Release();
    return hr;
}

GraphEdit 在 Microsoft Windows 软件开发工具包 (SDK) (http://go.microsoft.com/fwlink/p/?linkid=62332) 中可用。