[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