goto no_display_size;
GST_OBJECT_LOCK (self);
- if (!self->pending_render_rect) {
- self->render_rect.x = 0;
- self->render_rect.y = 0;
- self->render_rect.w = GST_VIDEO_SINK_WIDTH (self);
- self->render_rect.h = GST_VIDEO_SINK_HEIGHT (self);
- }
+ if (self->pending_render_rect) {
+ GstVideoRectangle rect = self->render_rect;
- gst_d3d11_window_set_render_rectangle (self->window,
- self->render_rect.x, self->render_rect.y, self->render_rect.w,
- self->render_rect.h);
- self->pending_render_rect = FALSE;
- GST_OBJECT_UNLOCK (self);
+ self->pending_render_rect = FALSE;
+ GST_OBJECT_UNLOCK (self);
+
+ gst_d3d11_window_set_render_rectangle (self->window, &rect);
+ } else {
+ GST_OBJECT_UNLOCK (self);
+ }
self->have_video_processor = FALSE;
if (!gst_d3d11_window_prepare (self->window, GST_VIDEO_SINK_WIDTH (self),
GST_OBJECT_LOCK (self);
if (self->window) {
- gst_d3d11_window_set_render_rectangle (self->window, x, y, width, height);
+ GstVideoRectangle rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.w = width;
+ rect.h = height;
+
+ self->render_rect = rect;
+ GST_OBJECT_UNLOCK (self);
+
+ gst_d3d11_window_set_render_rectangle (self->window, &rect);
} else {
self->render_rect.x = x;
self->render_rect.y = y;
self->render_rect.w = width;
self->render_rect.h = height;
self->pending_render_rect = TRUE;
+ GST_OBJECT_UNLOCK (self);
}
- GST_OBJECT_UNLOCK (self);
}
static void
#define WM_GST_D3D11_FULLSCREEN (WM_USER + 1)
#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)
static LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
/* atomic */
gint pending_fullscreen_count;
+ gint pending_move_window;
/* fullscreen related */
RECT restore_rect;
LONG restore_style;
+
+ /* Handle set_render_rectangle */
+ GstVideoRectangle render_rect;
};
#define gst_d3d11_window_win32_parent_class parent_class
gst_d3d11_window_win32_on_resize (GstD3D11Window * window,
guint width, guint height);
static void gst_d3d11_window_win32_unprepare (GstD3D11Window * window);
+static void
+gst_d3d11_window_win32_set_render_rectangle (GstD3D11Window * window,
+ const GstVideoRectangle * rect);
static void
gst_d3d11_window_win32_class_init (GstD3D11WindowWin32Class * klass)
GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_on_resize);
window_class->unprepare =
GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_unprepare);
+ window_class->set_render_rectangle =
+ GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_set_render_rectangle);
}
static void
}
static void
+gst_d3d11_window_win32_set_render_rectangle (GstD3D11Window * window,
+ const GstVideoRectangle * rect)
+{
+ GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (window);
+
+ if (self->external_hwnd && self->internal_hwnd) {
+ g_atomic_int_add (&self->pending_move_window, 1);
+ self->render_rect = *rect;
+
+ if (self->internal_hwnd_thread == g_thread_self ()) {
+ /* We are on message pumping thread already, handle this synchroniously */
+ SendMessage (self->internal_hwnd, WM_GST_D3D11_MOVE_WINDOW, 0, 0);
+ } else {
+ /* Post message to message pumping thread. Handling HWND specific message
+ * on message pumping thread is not a worst idea in generall */
+ PostMessage (self->internal_hwnd, WM_GST_D3D11_MOVE_WINDOW, 0, 0);
+ }
+ } else {
+ /* XXX: Not sure what's expected behavior if we are drawing on internal
+ * HWND but user wants to specify rectangle.
+ *
+ * - 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 ?
+ */
+ }
+}
+
+static void
gst_d3d11_window_win32_finalize (GObject * object)
{
GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (object);
gst_d3d11_window_win32_change_fullscreen_mode_internal (self);
}
break;
+ case WM_GST_D3D11_MOVE_WINDOW:
+ if (g_atomic_int_get (&self->pending_move_window)) {
+ g_atomic_int_set (&self->pending_move_window, 0);
+
+ if (self->internal_hwnd && self->external_hwnd) {
+ if (self->render_rect.w < 0 || self->render_rect.h < 0) {
+ RECT rect;
+
+ /* Reset render rect and back to full-size window */
+ if (GetClientRect (self->external_hwnd, &rect)) {
+ MoveWindow (self->internal_hwnd, 0, 0,
+ rect.right - rect.left, rect.bottom - rect.top, FALSE);
+ }
+ } else {
+ MoveWindow (self->internal_hwnd, self->render_rect.x,
+ self->render_rect.y, self->render_rect.w, self->render_rect.h,
+ FALSE);
+ }
+ }
+ }
+ break;
default:
break;
}