locked
MF code in a COM dll and display a video in a WPF control RRS feed

  • Question

  • Hello all,

    I've created a COM DLL using ATL, which exposes a VideoPlayer, based on the Media Session Playback sample.

    My intention is currently to give the VideoPlayer the handle of the control in which I'd like the EVR to paint the video.

    Do you think this is the right solution? Is there any alternative using WPF?

    If this solution is correct, how would you fix this code so the DLL can have the correct HWND from the WPF application?

    I know this is not really Media Foundation related, but I hope someone did try to do this before me :)

    IDL File

    interface IVideoPlayer : IDispatch {
        
        [id(1)] HRESULT Initialize([in] OLE_HANDLE video_hwnd, [in] OLE_HANDLE event_hwnd);
    };
    

    VideoPlayer file

    STDMETHODIMP VideoPlayer::Initialize(
        OLE_HANDLE hVideo, 
        OLE_HANDLE hEvent
        )
    {
        m_hwndVideo = (HWND) (DWORD_PTR)hVideo;
        m_hwndEvent = (HWND) (DWORD_PTR)hEvent;
    }
    


    WPF file

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var handle = new WindowInteropHelper(this).Handle.ToInt32();
        videoPlayer = new EmideeMediaFoundationLib.VideoPlayer();
    
        videoPlayer.Initialize(handle, handle);
    }
    


    When I put a breakpoint inside the VideoPlayer file, m_hwndVideo and m_hwndEvent have invalid values.

    Thanks in advance

    Mike

    Thursday, November 3, 2011 4:09 PM

Answers

  •  

    hi there,

     

    well the MediaElement might work but you´ll reach the limits very fast (performance, no custom player, custom decoders for standard formats etc.)

    you might want to create a HwndHost in your Wpf Control (WindowsFormsHost inherits HwndHost) which gives you a handle you can use.

    at least this works for me.

    however, if you want to use WPF specific features (RenderTransforms) or want to have WPF-ish overlays (Airspace Problems) you might want to go a different approach. Maybe you could render the Video to a D3DSurfae using a custom EVR presenter and display it using D3DImage. You won`t get the same kind of performance though.


    Friday, November 4, 2011 7:11 AM

All replies

  • of course an alternative solution would be to use the MediaElement of the WPF library, like the MF managed sample of the blog.

    But I will have another use cases for my application, like capturing the video from a camera, saving it on disk WHILE I allow the user to preview it. And in this case, I doubt I can do this using the MediaElement.

    So I really need a way to output some video on a WPF control.

    Maybe using a WindowsFormHost element?

    Any hints are welcome ;-)

    Thursday, November 3, 2011 10:02 PM
  •  

    hi there,

     

    well the MediaElement might work but you´ll reach the limits very fast (performance, no custom player, custom decoders for standard formats etc.)

    you might want to create a HwndHost in your Wpf Control (WindowsFormsHost inherits HwndHost) which gives you a handle you can use.

    at least this works for me.

    however, if you want to use WPF specific features (RenderTransforms) or want to have WPF-ish overlays (Airspace Problems) you might want to go a different approach. Maybe you could render the Video to a D3DSurfae using a custom EVR presenter and display it using D3DImage. You won`t get the same kind of performance though.


    Friday, November 4, 2011 7:11 AM
  • Thanks a lot for your answer.

    I'm trying your first solution, using HwndHost.

    For now, I don't succeed in passing the HWND of the control to my ATL DLL. How should I declare the function?

    I've tried using OLE_HANDLE, LONGLONG in the DLL, and tried passing videoHost.Handle.ToInt32() and videoHost.Handle.ToInt64() in the WPF side (videoHost being of course the class which inherits from HwndHost), but in the DLL, when I cast the function arguments in a HWND, and check the value of the casted value, VS tells me it is "unused"... 

    Friday, November 4, 2011 10:15 AM
  • when you have som interop with a native dll (using P/Invoke) i guess you could just declare your native function to receive a HWND or just a void pointer.

    on .net side just pass the IntPtr (HwndHosts´s Handle is of Type IntPtr) as argument and you´ll be fine.

    also check that your HwndHost has already a valid handle (i.e != IntPtr.Zero).

    Friday, November 4, 2011 10:21 AM
  • Yes, HwndHost has a valid handle, but I can't get a valid HWND in my COM dll when I give it the IntPtr, event IntPtr.ToInt32() or ToInt64().

    How do you use MF in your WPF application? Using a COM dll too?

    Friday, November 4, 2011 10:50 AM
  • i have managed com wrappers around MF functions and use them directly within .net for player functionality. similar to what the code on http://mfnet.sf.net does. 

    but i guess the IntPtr you´ll get from your HwndHost´s Handle should be a valid Hwnd (at least its overe here)

    Friday, November 4, 2011 11:04 AM
  • I finally could make it work, using a class deriving from HwndHost. Thanks a lot again.

    I'll have a look at the D3DImage too BTW, because I might need to fade-in/out the video controls on top of the video, like in the Windows Media Player, and I suspect I won't be able to do so using a HwndHost.

    Thanks again!

    Friday, November 4, 2011 1:48 PM