basetextoverlay: Receive window size event and adjust rendering
authorLubosz Sarnecki <lubosz.sarnecki@collabora.co.uk>
Wed, 25 Mar 2015 13:10:10 +0000 (14:10 +0100)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Mon, 20 Jul 2015 19:09:22 +0000 (15:09 -0400)
* cache window size event and update handle ratio
* init width with 1, don't use 0
* don't update overlay when receiving same window size
* receive window size from allocation query

https://bugzilla.gnome.org/show_bug.cgi?id=751157

ext/pango/gstbasetextoverlay.c
ext/pango/gstbasetextoverlay.h

index 900d79c..9cc04a1 100644 (file)
@@ -268,6 +268,9 @@ gst_base_text_overlay_adjust_values_with_fontdesc (GstBaseTextOverlay * overlay,
     PangoFontDescription * desc);
 static gboolean gst_base_text_overlay_can_handle_caps (GstCaps * incaps);
 
+static void
+gst_base_text_overlay_update_render_size (GstBaseTextOverlay * overlay);
+
 GType
 gst_base_text_overlay_get_type (void)
 {
@@ -632,6 +635,18 @@ gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
   overlay->composition = NULL;
   overlay->upstream_composition = NULL;
 
+  overlay->width = 1;
+  overlay->height = 1;
+
+  overlay->window_width = 1;
+  overlay->window_height = 1;
+
+  overlay->stream_height = 1;
+  overlay->stream_width = 1;
+
+  overlay->image_width = 1;
+  overlay->image_height = 1;
+
   g_mutex_init (&overlay->lock);
   g_cond_init (&overlay->cond);
   gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
@@ -729,6 +744,7 @@ gst_base_text_overlay_negotiate (GstBaseTextOverlay * overlay, GstCaps * caps)
     overlay_caps = gst_caps_ref (caps);
   } else {
     GstQuery *query;
+    guint alloc_index;
 
     /* First check if the allocation meta has compositon */
     query = gst_query_new_allocation (caps, FALSE);
@@ -744,7 +760,31 @@ gst_base_text_overlay_negotiate (GstBaseTextOverlay * overlay, GstCaps * caps)
     }
 
     alloc_has_meta = gst_query_find_allocation_meta (query,
-        GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
+        GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, &alloc_index);
+
+    if (alloc_has_meta) {
+      guint width, height;
+      const GstStructure *params;
+
+      gst_query_parse_nth_allocation_meta (query, alloc_index, &params);
+      if (params) {
+        if (!gst_structure_get (params,
+                "width", G_TYPE_UINT, &width,
+                "height", G_TYPE_UINT, &height, NULL)) {
+          GST_ERROR ("%s: Could not read window dimensions",
+              gst_structure_get_name (params));
+        } else {
+          GST_DEBUG ("received window size: %dx%d", width, height);
+          if ((width != 0 && height != 0) &&
+              (overlay->window_width != width
+                  || overlay->window_height != height)) {
+            overlay->window_width = width;
+            overlay->window_height = height;
+            gst_base_text_overlay_update_render_size (overlay);
+          }
+        }
+      }
+    }
 
     gst_query_unref (query);
 
@@ -839,8 +879,19 @@ gst_base_text_overlay_setcaps (GstBaseTextOverlay * overlay, GstCaps * caps)
 
   overlay->info = info;
   overlay->format = GST_VIDEO_INFO_FORMAT (&info);
-  overlay->width = GST_VIDEO_INFO_WIDTH (&info);
-  overlay->height = GST_VIDEO_INFO_HEIGHT (&info);
+
+  overlay->stream_width = GST_VIDEO_INFO_WIDTH (&info);
+  overlay->stream_height = GST_VIDEO_INFO_HEIGHT (&info);
+
+  if (overlay->width == 1) {
+    overlay->width = overlay->stream_width;
+    overlay->height = overlay->stream_height;
+    GST_DEBUG ("getting rendering dimensions from stream %dx%d",
+        overlay->width, overlay->height);
+  }
+
+  if (overlay->window_height != 1)
+    gst_base_text_overlay_update_render_size (overlay);
 
   ret = gst_base_text_overlay_negotiate (overlay, caps);
 
@@ -1103,6 +1154,37 @@ gst_base_text_overlay_src_query (GstPad * pad, GstObject * parent,
   return ret;
 }
 
+static void
+gst_base_text_overlay_update_render_size (GstBaseTextOverlay * overlay)
+{
+  gfloat video_aspect = (float) overlay->stream_width /
+      (float) overlay->stream_height;
+
+  gfloat window_aspect = (float) overlay->window_width /
+      (float) overlay->window_height;
+
+  guint text_buffer_width = 0;
+  guint text_buffer_height = 0;
+
+  if (video_aspect >= window_aspect) {
+    text_buffer_width = overlay->window_width;
+    text_buffer_height = window_aspect * overlay->window_height / video_aspect;
+  } else if (video_aspect < window_aspect) {
+    text_buffer_width = video_aspect * overlay->window_width / window_aspect;
+    text_buffer_height = overlay->window_height;
+  }
+
+  overlay->need_render = TRUE;
+
+  overlay->width = text_buffer_width;
+  overlay->height = text_buffer_height;
+  GST_DEBUG
+      ("updating render dimensions %dx%d from stream %dx%d and window %dx%d",
+      overlay->width, overlay->height,
+      overlay->stream_width, overlay->stream_height,
+      overlay->window_width, overlay->window_height);
+}
+
 static gboolean
 gst_base_text_overlay_src_event (GstPad * pad, GstObject * parent,
     GstEvent * event)
@@ -1417,9 +1499,10 @@ gst_base_text_overlay_set_composition (GstBaseTextOverlay * overlay)
 
   gst_base_text_overlay_get_pos (overlay, &xpos, &ypos);
 
-  GST_DEBUG ("updating composition for '%s'", overlay->default_text);
+  GST_DEBUG ("updating composition for '%s' with window size %dx%d",
+      overlay->default_text, overlay->window_width, overlay->window_height);
 
-  if (overlay->text_image) {
+  if (overlay->text_image && overlay->image_width != 1) {
     gst_buffer_add_video_meta (overlay->text_image, GST_VIDEO_FRAME_FLAG_NONE,
         GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB,
         overlay->image_width, overlay->image_height);
@@ -1628,8 +1711,10 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
   cairo_destroy (cr);
   cairo_surface_destroy (surface);
   gst_buffer_unmap (buffer, &map);
-  overlay->image_width = width;
-  overlay->image_height = height;
+  if (width != 0)
+    overlay->image_width = width;
+  if (height != 0)
+    overlay->image_height = height;
   overlay->baseline_y = ink_rect.y;
   g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
 
index ba30b21..1d643b3 100644 (file)
@@ -170,6 +170,11 @@ struct _GstBaseTextOverlay {
     gint                     image_height;
     gint                     baseline_y;
 
+    gint                     stream_width;
+    gint                     stream_height;
+    gint                     window_width;
+    gint                     window_height;
+
     gboolean                 auto_adjust_size;
     gboolean                 need_render;