examples: playback-test: Fix for UI resize scenario on Windows
authorSeungha Yang <seungha@centricular.com>
Mon, 2 Aug 2021 08:46:37 +0000 (17:46 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 13 Oct 2021 07:04:08 +0000 (07:04 +0000)
Application needs to notify videosink element of video widget resize
via gst_video_overlay_set_render_rectangle() since WM_SIZE event
wouldn't be notified.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1115>

subprojects/gst-plugins-base/tests/examples/playback/playback-test.c

index cbaed94..c3aa3c1 100644 (file)
@@ -2227,6 +2227,13 @@ draw_cb (GtkWidget * widget, cairo_t * cr, PlaybackApp * app)
     return TRUE;
   }
 
+  /* "prepare-window-handle" message might not be posted yet depending on
+   * videosink implementation */
+  if (!app->overlay_element) {
+    app->overlay_element = gst_bin_get_by_interface (GST_BIN (app->pipeline),
+        GST_TYPE_VIDEO_OVERLAY);
+  }
+
   if (app->overlay_element)
     gst_video_overlay_expose (GST_VIDEO_OVERLAY (app->overlay_element));
 
@@ -2311,6 +2318,39 @@ motion_notify_cb (GtkWidget * widget, GdkEventMotion * event, PlaybackApp * app)
   return FALSE;
 }
 
+#ifdef G_OS_WIN32
+/* On Windows, videosink elements expect full-size overlay window handle.
+ * And an expectation for window resize scenario is that WM_SIZE event of
+ * parent HWND is forwarded to child window.
+ * But some GUI applications like GTK might handle WM_SIZE event by themselves
+ * and therefore child HWND wouldn't be able to understand any resize event.
+ *
+ * In this example, we will watch "configure-event" of GTK widget and
+ * GstVideoOverlay::set_render_rectangle() will be used to notify videosink
+ * elements of resized render area.
+ */
+static gboolean
+configure_event_cb (GtkWidget * widget, GdkEventConfigure * event,
+    PlaybackApp * app)
+{
+  /* GdkEventConfigure::x and GdkEventConfigure::y are positions of this
+   * video widget relative to parent. So, we should not forward it to videosink.
+   * From videosink point of view, its parent window is this video widget */
+
+  if (!app->overlay_element) {
+    app->overlay_element = gst_bin_get_by_interface (GST_BIN (app->pipeline),
+        GST_TYPE_VIDEO_OVERLAY);
+  }
+
+  if (app->overlay_element) {
+    gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY
+        (app->overlay_element), 0, 0, event->width, event->height);
+  }
+
+  return FALSE;
+}
+#endif
+
 static void
 msg_eos (GstBus * bus, GstMessage * message, PlaybackApp * app)
 {
@@ -2682,6 +2722,10 @@ create_ui (PlaybackApp * app)
       G_CALLBACK (key_release_cb), app);
   g_signal_connect (app->video_window, "motion-notify-event",
       G_CALLBACK (motion_notify_cb), app);
+#ifdef G_OS_WIN32
+  g_signal_connect (app->video_window, "configure-event",
+      G_CALLBACK (configure_event_cb), app);
+#endif
   gtk_widget_set_can_focus (app->video_window, TRUE);
   gtk_widget_add_events (app->video_window,
       GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK