From 26dd6c5c26fc061fd5a0dc28545bc6f6a3270d3f Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 21 Feb 2023 00:27:27 +0900 Subject: [PATCH] d3d11videosink: Fix rendering on external handle Partial revert of the commit 068a5c1053ae05b3c7747243948447e764d25aa6. That introduced size mismatch between internal and external HWND Part-of: --- .../sys/d3d11/gstd3d11videosink.cpp | 1 + .../sys/d3d11/gstd3d11window.cpp | 13 +++ .../sys/d3d11/gstd3d11window.h | 4 + .../sys/d3d11/gstd3d11window_win32.cpp | 82 +++++++++++++------ 4 files changed, 75 insertions(+), 25 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp index b091354c6d..2d3ba79c7c 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp @@ -1430,6 +1430,7 @@ gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf) GST_LOG_OBJECT (self, "End drawing"); self->drawing = FALSE; } else { + gst_d3d11_window_show (self->window); ret = gst_d3d11_window_render (self->window, self->prepared_buffer); } diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp index 394c7046d9..85be423b7d 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp @@ -814,6 +814,19 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width, return GST_FLOW_OK; } +void +gst_d3d11_window_show (GstD3D11Window * window) +{ + GstD3D11WindowClass *klass; + + g_return_if_fail (GST_IS_D3D11_WINDOW (window)); + + klass = GST_D3D11_WINDOW_GET_CLASS (window); + + if (klass->show) + klass->show (window); +} + void gst_d3d11_window_set_render_rectangle (GstD3D11Window * window, const GstVideoRectangle * rect) diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h index 25b75ebe81..5a836ec679 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h @@ -121,6 +121,8 @@ struct _GstD3D11WindowClass { GstObjectClass object_class; + void (*show) (GstD3D11Window * window); + void (*update_swap_chain) (GstD3D11Window * window); void (*change_fullscreen_mode) (GstD3D11Window * window); @@ -168,6 +170,8 @@ struct _GstD3D11WindowClass GType gst_d3d11_window_get_type (void); +void gst_d3d11_window_show (GstD3D11Window * window); + void gst_d3d11_window_set_render_rectangle (GstD3D11Window * window, const GstVideoRectangle * rect); diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_win32.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_win32.cpp index eaff4a95a4..5896f7f76c 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_win32.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_win32.cpp @@ -43,6 +43,7 @@ G_LOCK_DEFINE_STATIC (create_lock); #define WM_GST_D3D11_CONSTRUCT_INTERNAL_WINDOW (WM_USER + 2) #define WM_GST_D3D11_DESTROY_INTERNAL_WINDOW (WM_USER + 3) #define WM_GST_D3D11_MOVE_WINDOW (WM_USER + 4) +#define WM_GST_D3D11_SHOW_WINDOW (WM_USER + 5) static LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -66,6 +67,8 @@ struct _GstD3D11WindowWin32 GMainContext *main_context; GMainLoop *loop; + gboolean visible; + GSource *msg_source; GIOChannel *msg_io_channel; @@ -102,6 +105,7 @@ G_DEFINE_TYPE (GstD3D11WindowWin32, gst_d3d11_window_win32, static void gst_d3d11_window_win32_constructed (GObject * object); static void gst_d3d11_window_win32_dispose (GObject * object); +static void gst_d3d11_window_win32_show (GstD3D11Window * window); static void gst_d3d11_window_win32_update_swap_chain (GstD3D11Window * window); static void gst_d3d11_window_win32_change_fullscreen_mode (GstD3D11Window * window); @@ -143,6 +147,7 @@ gst_d3d11_window_win32_class_init (GstD3D11WindowWin32Class * klass) gobject_class->constructed = gst_d3d11_window_win32_constructed; gobject_class->dispose = gst_d3d11_window_win32_dispose; + window_class->show = GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_show); window_class->update_swap_chain = GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_update_swap_chain); window_class->change_fullscreen_mode = @@ -211,32 +216,9 @@ gst_d3d11_window_win32_prepare (GstD3D11Window * window, guint display_width, GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (window); HWND hwnd; GstFlowReturn ret; - gint width, height; - switch (window->method) { - case GST_VIDEO_ORIENTATION_90R: - case GST_VIDEO_ORIENTATION_90L: - case GST_VIDEO_ORIENTATION_UL_LR: - case GST_VIDEO_ORIENTATION_UR_LL: - width = display_height; - height = display_width; - break; - default: - width = display_width; - height = display_height; - break; - } - - if (!self->setup_external_hwnd) { - RECT rect; - GetClientRect (self->internal_hwnd, &rect); - width += 2 * GetSystemMetrics (SM_CXSIZEFRAME); - height += - 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION); - MoveWindow (self->internal_hwnd, rect.left, rect.top, width, height, FALSE); - ShowWindow (self->internal_hwnd, SW_SHOW); + if (!self->setup_external_hwnd) goto done; - } hwnd = (HWND) window->external_handle; if (!IsWindow (hwnd)) { @@ -592,6 +574,9 @@ gst_d3d11_window_win32_create_internal_window (GstD3D11WindowWin32 * self) } self->device_handle = 0; + self->internal_hwnd = 0; + self->visible = FALSE; + self->internal_hwnd = CreateWindowExA (0, "GSTD3D11", "Direct3D11 renderer", @@ -838,6 +823,9 @@ gst_d3d11_window_win32_handle_window_proc (GstD3D11WindowWin32 * self, } } break; + case WM_GST_D3D11_SHOW_WINDOW: + ShowWindow (self->internal_hwnd, SW_SHOW); + break; default: break; } @@ -929,7 +917,6 @@ sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) SWP_FRAMECHANGED | SWP_NOACTIVATE); MoveWindow (self->internal_hwnd, rect.left, rect.top, rect.right, rect.bottom, FALSE); - ShowWindow (self->internal_hwnd, SW_SHOW); GstD3D11SRWLockGuard lk (&self->lock); self->overlay_state = GST_D3D11_WINDOW_WIN32_OVERLAY_STATE_OPENED; @@ -1125,6 +1112,51 @@ gst_d3d11_window_win32_create_swap_chain (GstD3D11Window * window, return TRUE; } +static void +gst_d3d11_window_win32_show (GstD3D11Window * window) +{ + GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (window); + gint width, height; + + switch (window->method) { + case GST_VIDEO_ORIENTATION_90R: + case GST_VIDEO_ORIENTATION_90L: + case GST_VIDEO_ORIENTATION_UL_LR: + case GST_VIDEO_ORIENTATION_UR_LL: + width = GST_VIDEO_INFO_HEIGHT (&window->render_info); + height = GST_VIDEO_INFO_WIDTH (&window->render_info); + break; + default: + width = GST_VIDEO_INFO_WIDTH (&window->render_info); + height = GST_VIDEO_INFO_HEIGHT (&window->render_info); + break; + } + + if (!self->visible) { + /* if no parent the real size has to be set now because this has not been done + * when at window creation */ + if (!self->external_hwnd) { + RECT rect; + GetClientRect (self->internal_hwnd, &rect); + width += 2 * GetSystemMetrics (SM_CXSIZEFRAME); + height += + 2 * GetSystemMetrics (SM_CYSIZEFRAME) + + GetSystemMetrics (SM_CYCAPTION); + MoveWindow (self->internal_hwnd, rect.left, rect.top, width, + height, FALSE); + ShowWindow (self->internal_hwnd, SW_SHOW); + } else if (self->internal_hwnd) { + /* ShowWindow will throw message to message pumping thread (app thread) + * synchroniously, which can be blocked at the moment. + * Post message to internal hwnd and do that from message pumping thread + */ + PostMessageA (self->internal_hwnd, WM_GST_D3D11_SHOW_WINDOW, 0, 0); + } + + self->visible = TRUE; + } +} + static GstFlowReturn gst_d3d11_window_win32_present (GstD3D11Window * window, guint present_flags) {