Michael Chi Lam
Michael Chi Lam

Reputation: 390

No video when using Enhanced Video Renderer

Situation:

Creating an decrypting filter with directshow. The graph is DecryptFileSource -> GDCL Mpeg-4 Demux -> FFDShow Video Decoder -> Enhanced Video Renderer

Issue:

Another user had this issue here however his answer was vague. According to Roman (In the comments on the previous link) it requires a specific initialization. However I'm unsure how to go about specifically initializing it.

No Errors are thrown when I attempt create the graph through code. I have a seeking enabled and I can see that the IMediaPosition is working. Just no video is showing but the audio plays

Upvotes: 1

Views: 1651

Answers (1)

Michael Chi Lam
Michael Chi Lam

Reputation: 390

I found the answer.

  1. Compile EVRPresenter.dll found in "Program Files\Microsoft SDKs\Windows\v6.1\Samples\Multimedia\MediaFoundation\EVRPresenter"

  2. Install the DLL "regsvr32 EVRPresenter.dll"

  3. Compile and include the MediaFoundation.dll into my product. Link here

  4. Instead of creating the object like I normally do

Like this:

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

instead

        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);

InitializeEVR:

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;
        }

Upvotes: 2

Related Questions