使用增强型视频渲染器时没有视频

No video when using Enhanced Video Renderer

情况:

正在使用 directshow 创建解密过滤器。该图是 DecryptFileSource -> GDCL Mpeg-4 Demux -> FFDShow 视频解码器 -> 增强型视频渲染器

问题:

另一位用户遇到了这个问题 here 但他的回答含糊不清。根据 Roman(在前面 link 的评论中),它需要特定的初始化。但是我不确定如何具体初始化它。

当我尝试通过代码创建图形时没有抛出任何错误。我启用了搜索,我可以看到 IMediaPosition 正在工作。只是没有视频显示,但 播放音频

我找到了答案。

  1. 编译 EVRPresenter.dll 在 "Program Files\Microsoft SDKs\Windows\v6.1\Samples\Multimedia\MediaFoundation\EVRPresenter"

  2. 中找到
  3. 安装 DLL "regsvr32 EVRPresenter.dll"

  4. 编译并将 MediaFoundation.dll 包含到我的产品中。 Link here

  5. 而不是像我通常那样创建对象

像这样:

IBaseFilter pEnhancedVideoRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_EnhancedVideoRenderer));

改为

        IBaseFilter pEVR = (IBaseFilter)new MediaFoundation.EVR.EnhancedVideoRenderer();
        hr = pGraph.AddFilter(pEVR, "Enhanced Video Renderer");

        MediaFoundation.EVR.IMFVideoDisplayControl m_pDisplay;

        InitializeEVR(pEVR, 1, out m_pDisplay);

初始化EVR:

private void InitializeEVR(IBaseFilter pEVR, int dwStreams, out MediaFoundation.EVR.IMFVideoDisplayControl ppDisplay)
        {
            MediaFoundation.EVR.IMFVideoRenderer pRenderer;
            MediaFoundation.EVR.IMFVideoDisplayControl pDisplay;
            MediaFoundation.EVR.IEVRFilterConfig pConfig;
            MediaFoundation.EVR.IMFVideoPresenter pPresenter;

            // Before doing anything else, set any custom presenter or mixer.

            // Presenter?
            if (m_PresenterCLSID != Guid.Empty)
            {
                Type type = Type.GetTypeFromCLSID(m_PresenterCLSID);

                // An error here means that the custom presenter sample from
                // http://mfnet.sourceforge.net hasn't been installed or
                // registered.
                pPresenter = (MediaFoundation.EVR.IMFVideoPresenter)Activator.CreateInstance(type);

                try
                {
                    pRenderer = (MediaFoundation.EVR.IMFVideoRenderer)pEVR;

                    pRenderer.InitializeRenderer(null, pPresenter);
                }
                finally
                {
                    //Marshal.ReleaseComObject(pPresenter);
                }
            }

            // Continue with the rest of the set-up.

            // Set the video window.
            object o;
            MediaFoundation.IMFGetService pGetService = null;
            pGetService = (MediaFoundation.IMFGetService)pEVR;
            pGetService.GetService(MediaFoundation.MFServices.MR_VIDEO_RENDER_SERVICE, typeof(MediaFoundation.EVR.IMFVideoDisplayControl).GUID, out o);

            try
            {
                pDisplay = (MediaFoundation.EVR.IMFVideoDisplayControl)o;
            }
            catch
            {
                Marshal.ReleaseComObject(o);
                throw;
            }

            try
            {
                // Set the number of streams.
                pDisplay.SetVideoWindow(this.Handle);

                if (dwStreams > 1)
                {
                    pConfig = (MediaFoundation.EVR.IEVRFilterConfig)pEVR;
                    pConfig.SetNumberOfStreams(dwStreams);
                }

                // Set the display position to the entire window.
                Rectangle r = this.ClientRectangle;
                MediaFoundation.Misc.MFRect rc = new MediaFoundation.Misc.MFRect(r.Left, r.Top, r.Right, r.Bottom);

                pDisplay.SetVideoPosition(null, rc);

                // Return the IMFVideoDisplayControl pointer to the caller.
                ppDisplay = pDisplay;
            }
            finally
            {
                //Marshal.ReleaseComObject(pDisplay);
            }
            m_pMixer = null;
        }