d3d11videosink: Add render-rectangle property

... and resize HWND on GstVideoOverlay::set_render_rectangle even when
we are rendering without external HWND

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2563
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4653>
This commit is contained in:
Seungha Yang 2023-05-14 20:05:25 +09:00 committed by GStreamer Marge Bot
parent e9d8bf7532
commit ad70dd64f9
2 changed files with 37 additions and 23 deletions

View file

@ -65,6 +65,7 @@ enum
PROP_PRIMARIES_MODE, PROP_PRIMARIES_MODE,
PROP_DISPLAY_FORMAT, PROP_DISPLAY_FORMAT,
PROP_EMIT_PRESENT, PROP_EMIT_PRESENT,
PROP_RENDER_RECTANGE,
}; };
#define DEFAULT_ADAPTER -1 #define DEFAULT_ADAPTER -1
@ -398,6 +399,13 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass)
(GParamFlags) (G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY | (GParamFlags) (G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY |
G_PARAM_STATIC_STRINGS))); G_PARAM_STATIC_STRINGS)));
/**
* GstD3D11VideoSink:render-rectangle:
*
* Since: 1.24
*/
gst_video_overlay_install_properties (gobject_class, PROP_RENDER_RECTANGE);
/** /**
* GstD3D11VideoSink::begin-draw: * GstD3D11VideoSink::begin-draw:
* @videosink: the #d3d11videosink * @videosink: the #d3d11videosink
@ -571,6 +579,10 @@ gst_d3d11_videosink_set_property (GObject * object, guint prop_id,
case PROP_EMIT_PRESENT: case PROP_EMIT_PRESENT:
self->emit_present = g_value_get_boolean (value); self->emit_present = g_value_get_boolean (value);
break; break;
case PROP_RENDER_RECTANGE:
gst_video_overlay_set_property (object, PROP_RENDER_RECTANGE,
PROP_RENDER_RECTANGE, value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;

View file

@ -343,16 +343,10 @@ gst_d3d11_window_win32_set_render_rectangle (GstD3D11Window * window,
* on message pumping thread is not a worst idea in generall */ * on message pumping thread is not a worst idea in generall */
PostMessageA (self->internal_hwnd, WM_GST_D3D11_MOVE_WINDOW, 0, 0); PostMessageA (self->internal_hwnd, WM_GST_D3D11_MOVE_WINDOW, 0, 0);
} }
} else { } else if (!window->external_handle && self->internal_hwnd) {
/* XXX: Not sure what's expected behavior if we are drawing on internal MoveWindow (self->internal_hwnd,
* HWND but user wants to specify rectangle. self->render_rect.x, self->render_rect.y, self->render_rect.w,
* self->render_rect.h, TRUE);
* - Should we move window to corresponding desktop coordinates ?
* - Or should crop correspondingly by modifying viewport of
* render target view of swapchian's backbuffer or so ?
* - Or should we ignore set_render_rectangle if we are drawing on
* internal HWND without external HWND ?
*/
} }
} }
@ -1189,22 +1183,30 @@ gst_d3d11_window_win32_show (GstD3D11Window * window)
/* if no parent the real size has to be set now because this has not been done /* if no parent the real size has to be set now because this has not been done
* when at window creation */ * when at window creation */
if (!self->external_hwnd) { if (!self->external_hwnd) {
RECT rect = { 0, }; if (self->render_rect.x != 0 || self->render_rect.y != 0 ||
self->render_rect.w != 0 || self->render_rect.h != 0) {
rect.right = width; MoveWindow (self->internal_hwnd,
rect.bottom = height; self->render_rect.x, self->render_rect.y, self->render_rect.w,
self->render_rect.h, FALSE);
if (AdjustWindowRect (&rect, WS_GST_D3D11, FALSE)) {
width = rect.right - rect.left;
height = rect.bottom - rect.top;
} else { } else {
width += 2 * GetSystemMetrics (SM_CXSIZEFRAME); RECT rect = { 0, };
height +=
2 * GetSystemMetrics (SM_CYSIZEFRAME) + rect.right = width;
GetSystemMetrics (SM_CYCAPTION); rect.bottom = height;
if (AdjustWindowRect (&rect, WS_GST_D3D11, FALSE)) {
width = rect.right - rect.left;
height = rect.bottom - rect.top;
} else {
width += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
height +=
2 * GetSystemMetrics (SM_CYSIZEFRAME) +
GetSystemMetrics (SM_CYCAPTION);
}
MoveWindow (self->internal_hwnd, 0, 0, width, height, FALSE);
} }
MoveWindow (self->internal_hwnd, 0, 0, width, height, FALSE);
ShowWindow (self->internal_hwnd, SW_SHOW); ShowWindow (self->internal_hwnd, SW_SHOW);
} else if (self->internal_hwnd) { } else if (self->internal_hwnd) {
/* ShowWindow will throw message to message pumping thread (app thread) /* ShowWindow will throw message to message pumping thread (app thread)