[vlc-commits] [Git][videolan/vlc][3.0.x] 6 commits: win32: common: avoid using SetRectEmpty

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Aug 7 15:54:19 UTC 2022



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
5270d387 by Steve Lhomme at 2022-08-04T16:34:05+02:00
win32: common: avoid using SetRectEmpty

We can do the same in standard C.

- - - - -
412bdb99 by Steve Lhomme at 2022-08-05T07:23:28+02:00
d3d11: enable the WinRT context/swapchain hack to work in non-UWP builds

Since there is not GPU callbacks in 3.0 this allows using a custom D3D11 render
target with regular libvlc as we can do in UWP libvlc.

Co-authored-by: Martin Finkel <me at martinfinkel.com>

- - - - -
f8969a66 by Steve Lhomme at 2022-08-05T07:24:25+02:00
direct3d11: move up fake UWP GetRect

No functional changes.

- - - - -
28e98694 by Steve Lhomme at 2022-08-05T07:30:34+02:00
direct3d11: allow external rendering even in non UWP builds

It's still the only supported mode in UWP 3.0 builds.

- - - - -
408d6e7e by Steve Lhomme at 2022-08-05T07:30:43+02:00
direct3d11: reindent

No functional changes.

- - - - -
0e4c20fc by Steve Lhomme at 2022-08-05T07:30:44+02:00
doc: libvlc: add a d3d11 external swapchain sample app

In UWP apps (and now libvlc) it was possible to set the swapchain and D3D
context to use for the rendering, via the command-line.

This sample app uses this functionality in a basic win32 app.

- - - - -


5 changed files:

- doc/libvlc/CMakeLists.txt
- + doc/libvlc/d3d11_swapr.cpp
- modules/codec/avcodec/d3d11va.c
- modules/video_output/win32/common.c
- modules/video_output/win32/direct3d11.c


Changes:

=====================================
doc/libvlc/CMakeLists.txt
=====================================
@@ -1,8 +1,8 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
 
 # configure with your own path
-#  -DLIBVLC_SDK_INC:STRING=S:/sources/build/win64/win64/vlc-4.0.0-dev/sdk/include
-#  -DLIBVLC_SDK_LIB:STRING=S:/sources/build/win64/win64/vlc-4.0.0-dev/sdk/lib
+#  -DLIBVLC_SDK_INC:STRING=S:/sources/build/win64/win64/vlc-3.0.0-dev/sdk/include
+#  -DLIBVLC_SDK_LIB:STRING=S:/sources/build/win64/win64/vlc-3.0.0-dev/sdk/lib
 #
 # or set them in your VSCode settings
 # {
@@ -28,6 +28,10 @@ endif ()
 
 if(WIN32)
 
+    add_executable(d3d11_swapr WIN32 d3d11_swapr.cpp)
+    target_compile_definitions(d3d11_swapr PRIVATE _WIN32_WINNT=0x0601)
+    target_link_libraries(d3d11_swapr libvlc d3d11 d3dcompiler uuid)
+
     add_executable(win_player WIN32 win_player.c)
     target_link_libraries(win_player libvlc)
 


=====================================
doc/libvlc/d3d11_swapr.cpp
=====================================
@@ -0,0 +1,340 @@
+/* compile: g++ d3d11_swapr.cpp -o d3d11_swapr.exe -L<path/libvlc> -lvlc -ld3d11 -ld3dcompiler -luuid */
+
+/* This is a basic sample app using a SwapChain hosted in the app and passed to
+   libvlc via the command line parameters. This is the legacy mode used by
+   UWP apps.
+
+   The swapchain size changes are signaled to libvlc by updating the swapchain
+   variables GUID_SWAPCHAIN_WIDTH and GUID_SWAPCHAIN_HEIGHT.
+*/
+
+#include <windows.h>
+#include <d3d11.h>
+#include <d3dcompiler.h>
+
+#include <d3d11_1.h>
+#include <dxgi1_2.h>
+
+#ifdef DEBUG_D3D11_LEAKS
+# include <initguid.h>
+# include <dxgidebug.h>
+#endif
+
+#include <cassert>
+#include <string>
+#include <sstream>
+
+#ifdef _MSC_VER
+typedef int ssize_t;
+#endif
+
+#include <vlc/vlc.h>
+
+#define INITIAL_WIDTH  1500
+#define INITIAL_HEIGHT  900
+
+#define check_leak(x)  assert(x)
+
+#include <initguid.h>
+// updates to the swapchain width/height need to be set a private data of the shared IDXGISwapChain object
+DEFINE_GUID(GUID_SWAPCHAIN_WIDTH,  0xf1b59347, 0x1643, 0x411a, 0xad, 0x6b, 0xc7, 0x80, 0x17, 0x7a, 0x06, 0xb6);
+DEFINE_GUID(GUID_SWAPCHAIN_HEIGHT, 0x6ea976a0, 0x9d60, 0x4bb7, 0xa5, 0xa9, 0x7d, 0xd1, 0x18, 0x7f, 0xc9, 0xbd);
+
+// if the host app is using the ID3D11DeviceContext, it should use a Mutext to access it and share it
+// as a private data of the shared ID3D11DeviceContext object
+DEFINE_GUID(GUID_CONTEXT_MUTEX, 0x472e8835, 0x3f8e, 0x4f93, 0xa0, 0xcb, 0x25, 0x79, 0x77, 0x6c, 0xed, 0x86);
+
+
+struct render_context
+{
+    HWND hWnd = 0;
+
+    libvlc_media_player_t *p_mp = nullptr;
+
+    /* Direct3D11 device/context */
+    ID3D11Device        *d3device = nullptr;
+    ID3D11DeviceContext *d3dctx = nullptr;
+    HANDLE              d3dctx_mutex = INVALID_HANDLE_VALUE;
+
+    IDXGISwapChain      *swapchain = nullptr;
+
+    unsigned width, height;
+};
+
+static void init_direct3d(struct render_context *ctx)
+{
+    HRESULT hr;
+    DXGI_SWAP_CHAIN_DESC scd = { };
+
+    scd.BufferCount = 1;
+    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+    scd.BufferDesc.Width = ctx->width;
+    scd.BufferDesc.Height = ctx->height;
+    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+    scd.OutputWindow = ctx->hWnd;
+    scd.SampleDesc.Count = 1;
+    scd.Windowed = TRUE;
+    scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+    UINT creationFlags = 0;
+#ifndef NDEBUG
+    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+    ctx->d3dctx_mutex = CreateMutexEx( NULL, NULL, 0, SYNCHRONIZE );
+
+    D3D11CreateDeviceAndSwapChain(NULL,
+                                  D3D_DRIVER_TYPE_HARDWARE,
+                                  NULL,
+                                  creationFlags,
+                                  NULL,
+                                  0,
+                                  D3D11_SDK_VERSION,
+                                  &scd,
+                                  &ctx->swapchain,
+                                  &ctx->d3device,
+                                  NULL,
+                                  &ctx->d3dctx);
+
+    ctx->d3dctx->SetPrivateData(GUID_CONTEXT_MUTEX,  sizeof(ctx->d3dctx_mutex), &ctx->d3dctx_mutex);
+
+    uint32_t i_width = scd.BufferDesc.Width;
+    uint32_t i_height = scd.BufferDesc.Height;
+    ctx->swapchain->SetPrivateData(GUID_SWAPCHAIN_WIDTH,  sizeof(i_width),  &i_width);
+    ctx->swapchain->SetPrivateData(GUID_SWAPCHAIN_HEIGHT, sizeof(i_height), &i_height);
+
+    /* The ID3D11Device must have multithread protection */
+    ID3D10Multithread *pMultithread;
+    hr = ctx->d3device->QueryInterface( __uuidof(ID3D10Multithread), (void **)&pMultithread);
+    if (SUCCEEDED(hr)) {
+        pMultithread->SetMultithreadProtected(TRUE);
+        pMultithread->Release();
+    }
+}
+
+static void list_dxgi_leaks(void)
+{
+#ifdef DEBUG_D3D11_LEAKS
+    HMODULE dxgidebug_dll = LoadLibrary(TEXT("DXGIDEBUG.DLL"));
+    if (dxgidebug_dll)
+    {
+        typedef HRESULT (WINAPI * LPDXGIGETDEBUGINTERFACE)(REFIID, void ** );
+        LPDXGIGETDEBUGINTERFACE pf_DXGIGetDebugInterface;
+        pf_DXGIGetDebugInterface = reinterpret_cast<LPDXGIGETDEBUGINTERFACE>(
+            reinterpret_cast<void*>( GetProcAddress( dxgidebug_dll, "DXGIGetDebugInterface" ) ) );
+        if (pf_DXGIGetDebugInterface)
+        {
+            IDXGIDebug *pDXGIDebug;
+            if (SUCCEEDED(pf_DXGIGetDebugInterface(__uuidof(IDXGIDebug), (void**)&pDXGIDebug)))
+                pDXGIDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL);
+            pDXGIDebug->Release();
+        }
+        FreeLibrary(dxgidebug_dll);
+    }
+#endif // DEBUG_D3D11_LEAKS
+}
+
+static void release_direct3d(struct render_context *ctx)
+{
+    ULONG ref;
+
+    ref = ctx->swapchain->Release();
+    check_leak(ref == 0);
+    ref = ctx->d3dctx->Release();
+    check_leak(ref == 0);
+    ref = ctx->d3device->Release();
+    check_leak(ref == 0);
+
+    CloseHandle(ctx->d3dctx_mutex);
+
+    list_dxgi_leaks();
+}
+
+static const char *AspectRatio = NULL;
+
+static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    if( message == WM_CREATE )
+    {
+        /* Store p_mp for future use */
+        CREATESTRUCT *c = (CREATESTRUCT *)lParam;
+        SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)c->lpCreateParams );
+        return 0;
+    }
+
+    LONG_PTR p_user_data = GetWindowLongPtr( hWnd, GWLP_USERDATA );
+    if( p_user_data == 0 )
+        return DefWindowProc(hWnd, message, wParam, lParam);
+    struct render_context *ctx = (struct render_context *)p_user_data;
+
+    switch(message)
+    {
+        case WM_SIZE:
+        {
+            ctx->width  = LOWORD(lParam);
+            ctx->height = HIWORD(lParam);
+
+            // update the swapchain to match our window client area
+            if (ctx->swapchain != nullptr)
+            {
+                uint32_t i_width  = ctx->width;
+                uint32_t i_height = ctx->height;
+                ctx->swapchain->SetPrivateData(GUID_SWAPCHAIN_WIDTH,  sizeof(i_width),  &i_width);
+                ctx->swapchain->SetPrivateData(GUID_SWAPCHAIN_HEIGHT, sizeof(i_height), &i_height);
+
+                D3D11_VIEWPORT viewport = { 0, 0, (FLOAT)ctx->width, (FLOAT)ctx->height, 0, 0 };
+                WaitForSingleObjectEx( ctx->d3dctx_mutex, INFINITE, FALSE );
+                // This call is not necessary but show how to use the shared mutex
+                // when accessing the shared ID3D11DeviceContext object
+                ctx->d3dctx->RSSetViewports(1, &viewport);
+                ReleaseMutex( ctx->d3dctx_mutex );
+            }
+        }
+        break;
+
+        case WM_DESTROY:
+            PostQuitMessage(0);
+            return 0;
+
+        case WM_KEYDOWN:
+        case WM_SYSKEYDOWN:
+            {
+                int key = tolower( MapVirtualKey( (UINT)wParam, 2 ) );
+                if (key == 'a')
+                {
+                    if (AspectRatio == NULL)
+                        AspectRatio = "16:10";
+                    else if (strcmp(AspectRatio,"16:10")==0)
+                        AspectRatio = "16:9";
+                    else if (strcmp(AspectRatio,"16:9")==0)
+                        AspectRatio = "4:3";
+                    else if (strcmp(AspectRatio,"4:3")==0)
+                        AspectRatio = "185:100";
+                    else if (strcmp(AspectRatio,"185:100")==0)
+                        AspectRatio = "221:100";
+                    else if (strcmp(AspectRatio,"221:100")==0)
+                        AspectRatio = "235:100";
+                    else if (strcmp(AspectRatio,"235:100")==0)
+                        AspectRatio = "239:100";
+                    else if (strcmp(AspectRatio,"239:100")==0)
+                        AspectRatio = "5:3";
+                    else if (strcmp(AspectRatio,"5:3")==0)
+                        AspectRatio = "5:4";
+                    else if (strcmp(AspectRatio,"5:4")==0)
+                        AspectRatio = "1:1";
+                    else if (strcmp(AspectRatio,"1:1")==0)
+                        AspectRatio = NULL;
+                    libvlc_video_set_aspect_ratio( ctx->p_mp, AspectRatio );
+                }
+                break;
+            }
+        default: break;
+    }
+
+    return DefWindowProc (hWnd, message, wParam, lParam);
+}
+
+int WINAPI WinMain(HINSTANCE hInstance,
+                   HINSTANCE hPrevInstance,
+                   LPSTR lpCmdLine,
+                   int nCmdShow)
+{
+    WNDCLASSEX wc;
+    struct render_context Context = { };
+    char *file_path;
+    libvlc_instance_t *p_libvlc;
+    libvlc_media_t *p_media;
+    (void)hPrevInstance;
+
+    /* remove "" around the given path */
+    if (lpCmdLine[0] == '"')
+    {
+        file_path = _strdup( lpCmdLine+1 );
+        if (file_path[strlen(file_path)-1] == '"')
+            file_path[strlen(file_path)-1] = '\0';
+    }
+    else
+        file_path = _strdup( lpCmdLine );
+
+
+    ZeroMemory(&wc, sizeof(WNDCLASSEX));
+
+    wc.cbSize = sizeof(WNDCLASSEX);
+    wc.style = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc = WindowProc;
+    wc.hInstance = hInstance;
+    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+    wc.lpszClassName = "WindowClass";
+
+    RegisterClassEx(&wc);
+
+    RECT wr = {0, 0, INITIAL_WIDTH, INITIAL_HEIGHT};
+    AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
+
+    Context.width  = wr.right - wr.left;
+    Context.height = wr.bottom - wr.top;
+
+    Context.hWnd = CreateWindowEx(0,
+                          "WindowClass",
+                          "libvlc external swapchain demo",
+                          WS_OVERLAPPEDWINDOW,
+                          CW_USEDEFAULT, CW_USEDEFAULT,
+                          Context.width,
+                          Context.height,
+                          NULL,
+                          NULL,
+                          hInstance,
+                          &Context);
+
+    ShowWindow(Context.hWnd, nCmdShow);
+
+    init_direct3d(&Context);
+
+    std::stringstream winrt_ctx_ss;
+    winrt_ctx_ss << "--winrt-d3dcontext=0x";
+    winrt_ctx_ss << std::hex << (intptr_t)Context.d3dctx;
+    std::string winrt_ctx  = winrt_ctx_ss.str();
+    std::stringstream winrt_swap_ss;
+    winrt_swap_ss << "--winrt-swapchain=0x";
+    winrt_swap_ss << std::hex << (intptr_t)Context.swapchain;
+    std::string winrt_swap = winrt_swap_ss.str();
+    const char *params [] = {
+        winrt_ctx.c_str(),
+        winrt_swap.c_str(),
+    };
+
+    p_libvlc = libvlc_new( sizeof(params)/sizeof(params[0]), params );
+    p_media = libvlc_media_new_path( p_libvlc, file_path );
+    free( file_path );
+    Context.p_mp = libvlc_media_player_new_from_media( p_media );
+
+
+    // DON'T use with callbacks libvlc_media_player_set_hwnd(p_mp, hWnd);
+
+    libvlc_media_player_play( Context.p_mp );
+
+    MSG msg;
+
+    while(TRUE)
+    {
+        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+        {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+
+            if(msg.message == WM_QUIT)
+                break;
+        }
+    }
+
+    libvlc_media_player_stop( Context.p_mp );
+
+    libvlc_media_player_release( Context.p_mp );
+    libvlc_media_release( p_media );
+
+    release_direct3d(&Context);
+
+    libvlc_release( p_libvlc );
+
+    return (int)msg.wParam;
+}


=====================================
modules/codec/avcodec/d3d11va.c
=====================================
@@ -423,19 +423,16 @@ static int D3dCreateDevice(vlc_va_t *va)
         return VLC_SUCCESS;
     }
 
-#if VLC_WINSTORE_APP
     sys->d3d_dev.d3dcontext = var_InheritInteger(va, "winrt-d3dcontext");
-    if (likely(sys->d3d_dev.d3dcontext))
+    if (unlikely(sys->d3d_dev.d3dcontext))
     {
-        ID3D11Device* d3ddevice = NULL;
         ID3D11DeviceContext_GetDevice(sys->d3d_dev.d3dcontext, &sys->d3d_dev.d3ddevice);
         ID3D11DeviceContext_AddRef(sys->d3d_dev.d3dcontext);
         ID3D11Device_Release(sys->d3d_dev.d3ddevice);
     }
-#endif
 
     /* */
-    if (!sys->d3d_dev.d3ddevice)
+    if (likely(!sys->d3d_dev.d3ddevice))
     {
         hr = D3D11_CreateDevice(va, &sys->hd3d, true, &sys->d3d_dev);
         if (FAILED(hr)) {


=====================================
modules/video_output/win32/common.c
=====================================
@@ -176,21 +176,27 @@ void UpdateRects(vout_display_t *vd,
     /* Retrieve the window position */
     point.x = point.y = 0;
 #if !VLC_WINSTORE_APP
-    ClientToScreen(sys->hwnd, &point);
+    if (likely(sys->hwnd)) // internal rendering
+        ClientToScreen(sys->hwnd, &point);
 #endif
 
     /* If nothing changed, we can return */
     bool has_moved;
     bool is_resized;
-#if VLC_WINSTORE_APP
-    has_moved = false;
-    is_resized = rect.right != (sys->rect_display.right - sys->rect_display.left) ||
-        rect.bottom != (sys->rect_display.bottom - sys->rect_display.top);
-    sys->rect_display = rect;
-#else
-    EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized,
-        point.x, point.y,
-        rect.right, rect.bottom);
+    if (unlikely(!sys->event)) // external rendering
+    {
+        has_moved = false;
+        is_resized = rect.right != (sys->rect_display.right - sys->rect_display.left) ||
+            rect.bottom != (sys->rect_display.bottom - sys->rect_display.top);
+        sys->rect_display = rect;
+    }
+#if !VLC_WINSTORE_APP
+    else
+    {
+        EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized,
+            point.x, point.y,
+            rect.right, rect.bottom);
+    }
 #endif
     if (is_resized)
         vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom);
@@ -214,20 +220,33 @@ void UpdateRects(vout_display_t *vd,
     vout_display_PlacePicture(&place, source, &place_cfg, false);
 
 #if !VLC_WINSTORE_APP
-    EventThreadUpdateSourceAndPlace(sys->event, source, &place);
-
-    if (sys->hvideownd)
-        SetWindowPos(sys->hvideownd, 0,
-            place.x, place.y, place.width, place.height,
-            SWP_NOCOPYBITS | SWP_NOZORDER | SWP_ASYNCWINDOWPOS);
+    if (likely(sys->event)) // internal rendering
+    {
+        EventThreadUpdateSourceAndPlace(sys->event, source, &place);
+
+        if (sys->hvideownd)
+            SetWindowPos(sys->hvideownd, 0,
+                place.x, place.y, place.width, place.height,
+                SWP_NOCOPYBITS | SWP_NOZORDER | SWP_ASYNCWINDOWPOS);
+    }
 #endif
 
     /* Destination image position and dimensions */
-#if (defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct3d11)) && !VLC_WINSTORE_APP
-    rect_dest.left = 0;
-    rect_dest.right = place.width;
-    rect_dest.top = 0;
-    rect_dest.bottom = place.height;
+#if (defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct3d11))
+    if (unlikely(!sys->event)) // external rendering
+    {
+        rect_dest.left = place.x;
+        rect_dest.right = rect_dest.left + place.width;
+        rect_dest.top = place.y;
+        rect_dest.bottom = rect_dest.top + place.height;
+    }
+    else
+    {
+        rect_dest.left = 0;
+        rect_dest.right = place.width;
+        rect_dest.top = 0;
+        rect_dest.bottom = place.height;
+    }
 #else
     rect_dest.left = point.x + place.x;
     rect_dest.right = rect_dest.left + place.width;
@@ -270,9 +289,7 @@ void UpdateRects(vout_display_t *vd,
     /* the 2 following lines are to fix a bug when clicking on the desktop */
     if ((rect_dest_clipped.right - rect_dest_clipped.left) == 0 ||
         (rect_dest_clipped.bottom - rect_dest_clipped.top) == 0) {
-#if !VLC_WINSTORE_APP
-        SetRectEmpty(&rect_src_clipped);
-#endif
+        rect_src_clipped = (RECT){0, 0, 0, 0};
         goto exit;
     }
 
@@ -418,7 +435,7 @@ void CommonManage(vout_display_t *vd)
     }
 
     /* HasMoved means here resize or move */
-    if (EventThreadGetAndResetHasMoved(sys->event))
+    if (!sys->event || EventThreadGetAndResetHasMoved(sys->event))
         UpdateRects(vd, NULL, false);
 }
 
@@ -647,6 +664,8 @@ int CommonControl(vout_display_t *vd, int query, va_list args)
 #if !VLC_WINSTORE_APP
     case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:   /* const vout_display_cfg_t *p_cfg */
     {   /* Update dimensions */
+        if (unlikely(!sys->event)) // external rendering
+            return VLC_EGENERIC;
         const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
         RECT rect_window = {
             .top    = 0,
@@ -665,6 +684,8 @@ int CommonControl(vout_display_t *vd, int query, va_list args)
         return VLC_SUCCESS;
     }
     case VOUT_DISPLAY_CHANGE_WINDOW_STATE: {       /* unsigned state */
+        if (unlikely(!sys->event)) // external rendering
+            return VLC_EGENERIC;
         const unsigned state = va_arg(args, unsigned);
         const bool is_on_top = (state & VOUT_WINDOW_STATE_ABOVE) != 0;
 #ifdef MODULE_NAME_IS_direct3d9
@@ -684,6 +705,8 @@ int CommonControl(vout_display_t *vd, int query, va_list args)
         return VLC_SUCCESS;
     }
     case VOUT_DISPLAY_CHANGE_FULLSCREEN: {
+        if (unlikely(!sys->event)) // external rendering
+            return VLC_EGENERIC;
         bool fs = va_arg(args, int);
         if (CommonControlSetFullscreen(vd, fs))
             return VLC_EGENERIC;


=====================================
modules/video_output/win32/direct3d11.c
=====================================
@@ -78,10 +78,8 @@ vlc_module_begin ()
 
     add_bool("direct3d11-hw-blending", true, HW_BLENDING_TEXT, HW_BLENDING_LONGTEXT, true)
 
-#if VLC_WINSTORE_APP
     add_integer("winrt-d3dcontext",    0x0, NULL, NULL, true) /* ID3D11DeviceContext* */
     add_integer("winrt-swapchain",     0x0, NULL, NULL, true) /* IDXGISwapChain1*     */
-#endif
 
     set_capability("vout display", 300)
     add_shortcut("direct3d11")
@@ -141,7 +139,7 @@ static void Display(vout_display_t *, picture_t *, subpicture_t *subpicture);
 
 static void Direct3D11Destroy(vout_display_t *);
 
-static int  Direct3D11Open (vout_display_t *);
+static int  Direct3D11Open (vout_display_t *, bool external_device);
 static void Direct3D11Close(vout_display_t *);
 
 static int SetupOutputFormat(vout_display_t *, video_format_t *);
@@ -192,16 +190,28 @@ static void Direct3D11UnmapPoolTexture(picture_t *picture)
     ID3D11DeviceContext_Unmap(p_sys->context, p_sys->resource[KNOWN_DXGI_INDEX], 0);
 }
 
-#if !VLC_WINSTORE_APP
-static int OpenHwnd(vout_display_t *vd)
+static bool GetRect(const vout_display_sys_win32_t *p_sys, RECT *out)
 {
-    vout_display_sys_t *sys = vd->sys = calloc(1, sizeof(vout_display_sys_t));
-    if (!sys)
-        return VLC_ENOMEM;
-
-    return D3D11_Create(vd, &sys->hd3d, true);
+    const vout_display_sys_t *sys = (const vout_display_sys_t *)p_sys;
+    out->left   = 0;
+    out->top    = 0;
+    uint32_t i_width;
+    uint32_t i_height;
+    UINT dataSize = sizeof(i_width);
+    HRESULT hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_WIDTH, &dataSize, &i_width);
+    if (FAILED(hr)) {
+        return false;
+    }
+    dataSize = sizeof(i_height);
+    hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_HEIGHT, &dataSize, &i_height);
+    if (FAILED(hr)) {
+        return false;
+    }
+    out->right  = i_width;
+    out->bottom = i_height;
+    return true;
 }
-#else
+
 static int OpenCoreW(vout_display_t *vd)
 {
     IDXGISwapChain1* dxgiswapChain  = var_InheritInteger(vd, "winrt-swapchain");
@@ -215,10 +225,7 @@ static int OpenCoreW(vout_display_t *vd)
     if (!d3ddevice)
         return VLC_EGENERIC;
 
-    vout_display_sys_t *sys = vd->sys = calloc(1, sizeof(vout_display_sys_t));
-    if (!sys)
-        return VLC_ENOMEM;
-
+    vout_display_sys_t *sys = vd->sys;
     sys->dxgiswapChain = dxgiswapChain;
     sys->d3d_dev.d3ddevice     = d3ddevice;
     sys->d3d_dev.d3dcontext    = d3dcontext;
@@ -227,33 +234,10 @@ static int OpenCoreW(vout_display_t *vd)
     ID3D11Device_AddRef       (sys->d3d_dev.d3ddevice);
     ID3D11DeviceContext_AddRef(sys->d3d_dev.d3dcontext);
 
-    return VLC_SUCCESS;
-}
-#endif
+    sys->sys.pf_GetRect = GetRect;
 
-#if VLC_WINSTORE_APP
-static bool GetRect(const vout_display_sys_win32_t *p_sys, RECT *out)
-{
-    const vout_display_sys_t *sys = (const vout_display_sys_t *)p_sys;
-    out->left   = 0;
-    out->top    = 0;
-    uint32_t i_width;
-    uint32_t i_height;
-    UINT dataSize = sizeof(i_width);
-    HRESULT hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_WIDTH, &dataSize, &i_width);
-    if (FAILED(hr)) {
-        return false;
-    }
-    dataSize = sizeof(i_height);
-    hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_HEIGHT, &dataSize, &i_height);
-    if (FAILED(hr)) {
-        return false;
-    }
-    out->right  = i_width;
-    out->bottom = i_height;
-    return true;
+    return VLC_SUCCESS;
 }
-#endif
 
 static unsigned int GetPictureWidth(const vout_display_t *vd)
 {
@@ -282,31 +266,32 @@ static int Open(vlc_object_t *object)
     }
 #endif
 
-#if !VLC_WINSTORE_APP
-    int ret = OpenHwnd(vd);
-#else
-    int ret = OpenCoreW(vd);
-#endif
+    vout_display_sys_t *sys = vd->sys = calloc(1, sizeof(vout_display_sys_t));
+    int ret = D3D11_Create(vd, &sys->hd3d, true);
+    if (unlikely(ret != VLC_SUCCESS))
+        goto error;
 
-    if (ret != VLC_SUCCESS)
+    ret = OpenCoreW(vd);
+    bool external_device = ret == VLC_SUCCESS;
+#if VLC_WINSTORE_APP
+    if (!external_device)
         return ret;
+#endif
 
-    if (CommonInit(vd))
+    if (!external_device && CommonInit(vd) != VLC_SUCCESS)
         goto error;
 
-#if VLC_WINSTORE_APP
-    vd->sys->sys.pf_GetRect = GetRect;
-#endif
     vd->sys->sys.pf_GetPictureWidth  = GetPictureWidth;
     vd->sys->sys.pf_GetPictureHeight = GetPictureHeight;
 
-    if (Direct3D11Open(vd)) {
+    if (Direct3D11Open(vd, external_device)) {
         msg_Err(vd, "Direct3D11 could not be opened");
         goto error;
     }
 
 #if !VLC_WINSTORE_APP
-    EventThreadUpdateTitle(vd->sys->sys.event, VOUT_TITLE " (Direct3D11 output)");
+    if (!external_device)
+        EventThreadUpdateTitle(vd->sys->sys.event, VOUT_TITLE " (Direct3D11 output)");
 #endif
     msg_Dbg(vd, "Direct3D11 device adapter successfully initialized");
 
@@ -554,9 +539,7 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
     ID3D11Texture2D* pDepthStencil;
     ID3D11Texture2D* pBackBuffer;
     RECT rect;
-#if VLC_WINSTORE_APP
-    if (!GetRect(&sys->sys, &rect))
-#endif
+    if (sys->sys.pf_GetRect != GetRect || !sys->sys.pf_GetRect(&sys->sys, &rect))
         rect = sys->sys.rect_dest_clipped;
     uint32_t i_width = RECTWidth(rect);
     uint32_t i_height = RECTHeight(rect);
@@ -1268,53 +1251,56 @@ static const d3d_format_t *GetBlendableFormat(vout_display_t *vd, vlc_fourcc_t i
     return FindD3D11Format( vd, &vd->sys->d3d_dev, i_src_chroma, false, 0, 0, 0, false, supportFlags );
 }
 
-static int Direct3D11Open(vout_display_t *vd)
+static int Direct3D11Open(vout_display_t *vd, bool external_device)
 {
     vout_display_sys_t *sys = vd->sys;
     IDXGIFactory2 *dxgifactory;
 
+    if (!external_device)
+    {
 #if !VLC_WINSTORE_APP
-    HRESULT hr = S_OK;
+        HRESULT hr = S_OK;
 
-    DXGI_SWAP_CHAIN_DESC1 scd;
-    FillSwapChainDesc(vd, &scd);
+        DXGI_SWAP_CHAIN_DESC1 scd;
+        FillSwapChainDesc(vd, &scd);
 
-    hr = D3D11_CreateDevice(vd, &sys->hd3d,
-                            is_d3d11_opaque(vd->source.i_chroma),
-                            &sys->d3d_dev);
-    if (FAILED(hr)) {
-       msg_Err(vd, "Could not Create the D3D11 device. (hr=0x%lX)", hr);
-       return VLC_EGENERIC;
-    }
+        hr = D3D11_CreateDevice(vd, &sys->hd3d,
+                                is_d3d11_opaque(vd->source.i_chroma),
+                                &sys->d3d_dev);
+        if (FAILED(hr)) {
+        msg_Err(vd, "Could not Create the D3D11 device. (hr=0x%lX)", hr);
+        return VLC_EGENERIC;
+        }
 
-    IDXGIAdapter *dxgiadapter = D3D11DeviceAdapter(sys->d3d_dev.d3ddevice);
-    if (unlikely(dxgiadapter==NULL)) {
-       msg_Err(vd, "Could not get the DXGI Adapter");
-       return VLC_EGENERIC;
-    }
+        IDXGIAdapter *dxgiadapter = D3D11DeviceAdapter(sys->d3d_dev.d3ddevice);
+        if (unlikely(dxgiadapter==NULL)) {
+        msg_Err(vd, "Could not get the DXGI Adapter");
+        return VLC_EGENERIC;
+        }
 
-    hr = IDXGIAdapter_GetParent(dxgiadapter, &IID_IDXGIFactory2, (void **)&dxgifactory);
-    IDXGIAdapter_Release(dxgiadapter);
-    if (FAILED(hr)) {
-       msg_Err(vd, "Could not get the DXGI Factory. (hr=0x%lX)", hr);
-       return VLC_EGENERIC;
-    }
+        hr = IDXGIAdapter_GetParent(dxgiadapter, &IID_IDXGIFactory2, (void **)&dxgifactory);
+        IDXGIAdapter_Release(dxgiadapter);
+        if (FAILED(hr)) {
+        msg_Err(vd, "Could not get the DXGI Factory. (hr=0x%lX)", hr);
+        return VLC_EGENERIC;
+        }
 
-    hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice,
-                                              sys->sys.hvideownd, &scd, NULL, NULL, &sys->dxgiswapChain);
-    if (hr == DXGI_ERROR_INVALID_CALL && scd.Format == DXGI_FORMAT_R10G10B10A2_UNORM)
-    {
-        msg_Warn(vd, "10 bits swapchain failed, try 8 bits");
-        scd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
         hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice,
-                                                  sys->sys.hvideownd, &scd, NULL, NULL, &sys->dxgiswapChain);
-    }
-    IDXGIFactory2_Release(dxgifactory);
-    if (FAILED(hr)) {
-       msg_Err(vd, "Could not create the SwapChain. (hr=0x%lX)", hr);
-       return VLC_EGENERIC;
-    }
+                                                sys->sys.hvideownd, &scd, NULL, NULL, &sys->dxgiswapChain);
+        if (hr == DXGI_ERROR_INVALID_CALL && scd.Format == DXGI_FORMAT_R10G10B10A2_UNORM)
+        {
+            msg_Warn(vd, "10 bits swapchain failed, try 8 bits");
+            scd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+            hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice,
+                                                    sys->sys.hvideownd, &scd, NULL, NULL, &sys->dxgiswapChain);
+        }
+        IDXGIFactory2_Release(dxgifactory);
+        if (FAILED(hr)) {
+        msg_Err(vd, "Could not create the SwapChain. (hr=0x%lX)", hr);
+        return VLC_EGENERIC;
+        }
 #endif
+    }
 
     IDXGISwapChain_QueryInterface( sys->dxgiswapChain, &IID_IDXGISwapChain4, (void **)&sys->dxgiswapChain4);
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a65b22fd0b9026a48c92ce7891a9e5967a9f5930...0e4c20fc941f931679fc897ba70047cebaca402b

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a65b22fd0b9026a48c92ce7891a9e5967a9f5930...0e4c20fc941f931679fc897ba70047cebaca402b
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list