d3d11videosink: Fix rendering on external handle

Partial revert of the commit 068a5c1053.
That introduced size mismatch between internal and external HWND

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4006>
This commit is contained in:
Seungha Yang 2023-02-21 00:27:27 +09:00 committed by GStreamer Marge Bot
parent 2ffc594d96
commit 26dd6c5c26
4 changed files with 75 additions and 25 deletions

View file

@ -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);
}

View file

@ -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)

View file

@ -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);

View file

@ -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)
{