c++sdldirectshow

How to Embed DirectShow Video Player to SDL Window


I'm trying to play a Video File using DirectShow library in a SDL Window, I use the library provided from Microsoft Docs and works fine when I try build it separately, but the code from main.cpp needs create a apart window in HWND to work and I want to use it in a existent SDL_Window.

Code from main.cpp

HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"DirectShow Playback", 
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

My code

SDL_SysWMinfo info; 
SDL_VERSION(&info.version);
SDL_GetWindowWMInfo(g_window, &info);
HWND hwnd = GetWindow(info.info.win.window, GWL_WNDPROC);

I already have SDL_Window* g_window, SDL_Renderer* g_renderer and SDL_Thread* video_tid but seems not work with HWND hwnd

Also, if I got it successfully then I will change ShowWindow(hwnd, nCmdShow);?

Here the complete code:

TUserFunc(void, PlayVideo, HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow, bool testvideo)
{
    // Register the window class.
    const wchar_t CLASS_NAME[]  = L"Sample Window Class";
    
    WNDCLASS wc = { };
    wc.lpfnWndProc   = WindowProc;
    wc.hInstance     = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

       SDL_SysWMinfo info; 
       SDL_VERSION(&info.version);
       SDL_GetWindowWMInfo(g_window, &info);
       HWND hwnd = GetWindow(info.info.win.window, GWL_WNDPROC);

    if (hwnd == NULL)
    {
        NotifyError(NULL, L"CreateWindowEx failed.");
    }

    ShowWindow(hwnd, nCmdShow);

    // Run the message loop.

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

PD: When I use the HWND hwnd of main.cpp the video plays but in a hidden window and the SDL window keeps completely frozen


Solution

  • DirectShow video renderers have support for so called "windowless mode" which you can utilize:

    Using Windowless Mode

    Windowless mode avoids these problems by having the VMR draw directly on the application window's client area, using DirectDraw to clip the video rectangle.

    Old Windows SDK offers related samlpes (e.g. vmr9/windowless).