WPF Media kit within Remote Desktop

May 19, 2015 at 5:46 AM
I'm using this wonderful kit as video in my WPF application. Everything is great except that video does not work via remote desktop. I've read (and seen) that the VMR9 definately doesn't like to work from remote desktop, but via graphedit, the EVR does work.

I'm guessing the D3D engine in the WPFMediaKit is causing issues with remote desktop as the sample app doesn't seem to play either. Is there any quick way to get the WPF Media kit elements to work from remote desktop?

Thanks,
Ofer
May 19, 2015 at 9:33 AM
Good news! I fixed it myself and it's completly possible!

In .net 4.5 the D3DImage now supports a software fallback that works via remote desktop. To make the media kit :

Modify the SetBackBufferInternal function:
    /// <summary>
    /// Configures D3DImage with a new surface.  This happens immediately
    /// </summary>
    private void SetBackBufferInternal(IntPtr backBuffer)
    {
        /* Do nothing if we don't have a new surface available */
        if (!m_newSurfaceAvailable)
            return;

        if (!D3DImage.Dispatcher.CheckAccess())
        {
            D3DImage.Dispatcher.BeginInvoke((Action)(() => SetBackBufferInternal(backBuffer)));
            return;
        }

        /* We have this around a try/catch just in case we
         * lose the device and our Surface is invalid. The
         * try/catch may not be needed, but testing needs
         * to take place before it's removed */
        try
        {
            D3DImage.Lock();
            D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, backBuffer, __true__);
            D3DImage.Unlock();
            SetNaturalWidthHeight();
        }
        catch (Exception ex)
        { }

        /* Clear our flag, so this won't be ran again
         * until a new surface is sent */
        m_newSurfaceAvailable = false;
    }
Modify the InternalInvalidateVIdeoImage function:

/// <summary>
    /// Invalidates the entire Direct3D image, notifying WPF to redraw
    /// </summary>
    protected void InternalInvalidateVideoImage()
    {
        /* Ensure we run on the correct Dispatcher */
        if(!D3DImage.Dispatcher.CheckAccess())
        {
            D3DImage.Dispatcher.Invoke((Action)(() => InvalidateVideoImage()));
            return;
        }

        /* If there is a new Surface to set,
         * this method will do the trick */
        SetBackBufferInternal(m_pBackBuffer);

        /* Only render the video image if possible, or if IsRenderingEnabled is true */
      __  if (IsRenderingEnabled && m_pBackBuffer != IntPtr.Zero)__
        {
            try
            {
                /* Invalidate the entire image */
                D3DImage.Lock();
                D3DImage.AddDirtyRect(new Int32Rect(0, /* Left */
                                                    0, /* Top */
                                                    D3DImage.PixelWidth, /* Width */
                                                    D3DImage.PixelHeight /* Height */));
                D3DImage.Unlock();
            }
            catch (Exception)
            { }
        }

        /* Invalidate all of our cloned D3DRenderers */
        InvalidateClonedVideoImages();
    }
and that's it! compile in .net 4.5, use the EVR, and your video will work via RDP!
Nov 24, 2016 at 10:44 AM
This fix does not work for me :(
Still do not see the video in RDP