[clutter-gst/wip/overlays: 4/4] untested/uncompiled overlay support starting point



commit 1165fc4fe78287356b06a21ed54da36fd43dad12
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Thu May 29 19:47:10 2014 +0100

    untested/uncompiled overlay support starting point

 clutter-gst/clutter-gst-aspectratio.c |   58 ++++++++---
 clutter-gst/clutter-gst-content.c     |  186 +++++++++++++++++++++++++++++---
 clutter-gst/clutter-gst-content.h     |    4 +
 clutter-gst/clutter-gst-private.h     |    8 ++
 clutter-gst/clutter-gst-types.c       |   92 ++++++++++++++++
 clutter-gst/clutter-gst-types.h       |   52 ++++++---
 clutter-gst/clutter-gst-video-sink.c  |   86 +++++++++++++++
 7 files changed, 437 insertions(+), 49 deletions(-)
---
diff --git a/clutter-gst/clutter-gst-aspectratio.c b/clutter-gst/clutter-gst-aspectratio.c
index 21b3802..53f5855 100644
--- a/clutter-gst/clutter-gst-aspectratio.c
+++ b/clutter-gst/clutter-gst-aspectratio.c
@@ -161,8 +161,8 @@ clutter_gst_aspectratio_paint_content (ClutterContent   *content,
 {
   ClutterGstAspectratio *self = CLUTTER_GST_ASPECTRATIO (content);
   ClutterGstAspectratioPrivate *priv = self->priv;
-  ClutterGstFrame *frame =
-    clutter_gst_content_get_frame (CLUTTER_GST_CONTENT (content));
+  ClutterGstContent *gst_content = CLUTTER_GST_CONTENT (content);
+  ClutterGstFrame *frame = clutter_gst_content_get_frame (gst_content);
   ClutterGstBox input_box, paint_box;
   ClutterActorBox content_box;
   ClutterPaintNode *node;
@@ -228,21 +228,51 @@ clutter_gst_aspectratio_paint_content (ClutterContent   *content,
       clutter_paint_node_unref (node);
     }
 
-  cogl_pipeline_set_color4ub (frame->pipeline,
-                              paint_opacity, paint_opacity,
-                              paint_opacity, paint_opacity);
+  if (clutter_gst_content_get_paint_frame (gst_content))
+    {
+      cogl_pipeline_set_color4ub (frame->pipeline,
+                                  paint_opacity, paint_opacity,
+                                  paint_opacity, paint_opacity);
 
-  node = clutter_pipeline_node_new (frame->pipeline);
-  clutter_paint_node_set_name (node, "AspectRatioVideoFrame");
+      node = clutter_pipeline_node_new (frame->pipeline);
+      clutter_paint_node_set_name (node, "AspectRatioVideoFrame");
 
-  clutter_paint_node_add_texture_rectangle_custom (node,
-                                                   paint_box.x1, paint_box.y1,
-                                                   paint_box.x2, paint_box.y2,
-                                                   input_box.x1, input_box.y1,
-                                                   input_box.x2, input_box.y2);
+      clutter_paint_node_add_texture_rectangle_custom (node,
+                                                       paint_box.x1, paint_box.y1,
+                                                       paint_box.x2, paint_box.y2,
+                                                       input_box.x1, input_box.y1,
+                                                       input_box.x2, input_box.y2);
+
+      clutter_paint_node_add_child (root, node);
+      clutter_paint_node_unref (node);
+    }
+
+  if (clutter_gst_content_get_paint_overlays (gst_content))
+    {
+      GPtrArray *overlays = clutter_gst_content_get_overlays (gst_content);
 
-  clutter_paint_node_add_child (root, node);
-  clutter_paint_node_unref (node);
+      if (overlays)
+        {
+          guint i;
+
+          for (i = 0; i < overlays->len; i++)
+            {
+              ClutterGstOverlay *overlay = g_ptr_array_index (overlays, i);
+
+              cogl_pipeline_set_color4ub (overlay->pipeline,
+                                          paint_opacity, paint_opacity,
+                                          paint_opacity, paint_opacity);
+
+              node = clutter_pipeline_node_new (overlay->pipeline);
+              clutter_paint_node_set_name (node, "AspectRatioVideoOverlay");
+
+              /* TODO: Compute overlay equivalent */
+
+              clutter_paint_node_add_child (root, node);
+              clutter_paint_node_unref (node);
+            }
+        }
+    }
 }
 
 static void
diff --git a/clutter-gst/clutter-gst-content.c b/clutter-gst/clutter-gst-content.c
index e23a31c..860020c 100644
--- a/clutter-gst/clutter-gst-content.c
+++ b/clutter-gst/clutter-gst-content.c
@@ -57,7 +57,12 @@ struct _ClutterGstContentPrivate
 {
   ClutterGstVideoSink *sink;
   ClutterGstPlayer *player;
+
   ClutterGstFrame *current_frame;
+  GPtrArray *overlays;
+
+  gboolean paint_frame;
+  gboolean paint_overlays;
 };
 
 enum
@@ -66,6 +71,8 @@ enum
 
   PROP_VIDEO_SINK,
   PROP_PLAYER,
+  PROP_PAINT_FRAME,
+  PROP_PAINT_OVERLAYS,
 
   PROP_LAST
 };
@@ -82,6 +89,56 @@ enum
 static guint signals[LAST_SIGNAL];
 
 
+/**/
+
+gboolean
+clutter_gst_content_get_paint_frame (ClutterGstContent *self)
+{
+  return self->priv->paint_frame;
+}
+
+static void
+clutter_gst_content_set_paint_frame (ClutterGstContent *self, gboolean value)
+{
+  if (self->priv->paint_frame == value)
+    return;
+
+  self->priv->paint_frame = value;
+  clutter_content_invalidate (CLUTTER_CONTENT (self));
+}
+
+gboolean
+clutter_gst_content_get_paint_overlays (ClutterGstContent *self)
+{
+  return self->priv->paint_overlays;
+}
+
+static void
+clutter_gst_content_set_paint_overlays (ClutterGstContent *self, gboolean value)
+{
+  if (self->priv->paint_overlays == value)
+    return;
+
+  self->priv->paint_overlays = value;
+  clutter_content_invalidate (CLUTTER_CONTENT (self));
+}
+
+static gboolean
+clutter_gst_content_has_painting_content (ClutterGstContent *self)
+{
+  ClutterGstContentPrivate *priv = self->priv;
+
+  if (priv->paint_frame && priv->current_frame)
+    return TRUE;
+
+  if (priv->paint_overlays && priv->overlays && priv->overlays->len > 0)
+    return TRUE;
+
+  return FALSE;
+}
+
+/**/
+
 static void
 update_frame (ClutterGstContent *self,
               ClutterGstFrame   *new_frame)
@@ -117,7 +174,8 @@ _new_frame_from_pipeline (ClutterGstVideoSink *sink,
 {
   update_frame (self, clutter_gst_video_sink_get_frame (sink));
 
-  clutter_content_invalidate (CLUTTER_CONTENT (self));
+  if (CLUTTER_GST_CONTENT_CLASS (self)->has_painting_content (self))
+    clutter_content_invalidate (CLUTTER_CONTENT (self));
 }
 
 static void
@@ -220,13 +278,16 @@ clutter_gst_content_paint_content (ClutterContent   *content,
                                    ClutterActor     *actor,
                                    ClutterPaintNode *root)
 {
-  ClutterGstContentPrivate *priv = CLUTTER_GST_CONTENT (content)->priv;
+  ClutterGstContent *self = CLUTTER_GST_CONTENT (content);
+  ClutterGstContentPrivate *priv = self->priv;
   ClutterActorBox box;
   ClutterPaintNode *node;
   ClutterContentRepeat repeat;
   guint8 paint_opacity;
 
-  if (!priv->current_frame)
+  g_message ("current_frame=%p", priv->current_frame);
+
+  if (!CLUTTER_GST_CONTENT_CLASS (self)->has_painting_content (self))
     return;
 
   clutter_actor_get_content_box (actor, &box);
@@ -238,28 +299,66 @@ clutter_gst_content_paint_content (ClutterContent   *content,
                               paint_opacity, paint_opacity,
                               paint_opacity, paint_opacity);
 
-  node = clutter_pipeline_node_new (priv->current_frame->pipeline);
-  clutter_paint_node_set_name (node, "Video");
 
-  if (repeat == CLUTTER_REPEAT_NONE)
-    clutter_paint_node_add_rectangle (node, &box);
-  else
+  g_message ("paint_frame=%i paint_overlays=%i", priv->paint_frame, priv->paint_overlays);
+
+  if (priv->paint_frame)
     {
-      float t_w = 1.f, t_h = 1.f;
+      node = clutter_pipeline_node_new (priv->current_frame->pipeline);
+      clutter_paint_node_set_name (node, "Video");
 
-      if ((repeat & CLUTTER_REPEAT_X_AXIS) != FALSE)
-        t_w = (box.x2 - box.x1) / priv->current_frame->resolution.width;
+      if (repeat == CLUTTER_REPEAT_NONE)
+        clutter_paint_node_add_rectangle (node, &box);
+      else
+        {
+          float t_w = 1.f, t_h = 1.f;
 
-      if ((repeat & CLUTTER_REPEAT_Y_AXIS) != FALSE)
-        t_h = (box.y2 - box.y1) / priv->current_frame->resolution.height;
+          if ((repeat & CLUTTER_REPEAT_X_AXIS) != FALSE)
+            t_w = (box.x2 - box.x1) / priv->current_frame->resolution.width;
 
-      clutter_paint_node_add_texture_rectangle (node, &box,
-                                                0.f, 0.f,
-                                                t_w, t_h);
+          if ((repeat & CLUTTER_REPEAT_Y_AXIS) != FALSE)
+            t_h = (box.y2 - box.y1) / priv->current_frame->resolution.height;
+
+          clutter_paint_node_add_texture_rectangle (node, &box,
+                                                    0.f, 0.f,
+                                                    t_w, t_h);
+        }
+
+      clutter_paint_node_add_child (root, node);
+      clutter_paint_node_unref (node);
     }
 
-  clutter_paint_node_add_child (root, node);
-  clutter_paint_node_unref (node);
+  if (priv->paint_overlays && priv->overlays)
+    {
+      guint i;
+
+      for (i = 0; i < priv->overlays->len; i++)
+        {
+          ClutterGstOverlay *overlay = g_ptr_array_index (priv->overlays, i);
+          gfloat box_width = clutter_actor_box_get_width (&box),
+            box_height = clutter_actor_box_get_height (&box);
+          ClutterActorBox obox = {
+            overlay->position.x1 * box_width / priv->current_frame->resolution.width,
+            overlay->position.y1 * box_height / priv->current_frame->resolution.height,
+            overlay->position.x2 * box_width / priv->current_frame->resolution.width,
+            overlay->position.y2 * box_height / priv->current_frame->resolution.height
+          };
+
+          cogl_pipeline_set_color4ub (overlay->pipeline,
+                                      paint_opacity, paint_opacity,
+                                      paint_opacity, paint_opacity);
+
+          node = clutter_pipeline_node_new (overlay->pipeline);
+          clutter_paint_node_set_name (node, "AspectRatioVideoOverlay");
+
+          clutter_paint_node_add_texture_rectangle (node, &obox,
+                                                    0, 0,
+                                                    1, 1);
+
+          clutter_paint_node_add_child (root, node);
+          clutter_paint_node_unref (node);
+        }
+    }
 }
 
 static void
@@ -288,6 +387,14 @@ clutter_gst_content_set_property (GObject      *object,
                           CLUTTER_GST_PLAYER (g_value_get_object (value)));
       break;
 
+    case PROP_PAINT_FRAME:
+      clutter_gst_content_set_paint_frame (self, g_value_get_boolean (value));
+      break;
+
+    case PROP_PAINT_OVERLAYS:
+      clutter_gst_content_set_paint_overlays (self, g_value_get_boolean (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -312,6 +419,14 @@ clutter_gst_content_get_property (GObject    *object,
       g_value_set_object (value, priv->player);
       break;
 
+    case PROP_PAINT_FRAME:
+      g_value_set_boolean (value, priv->paint_frame);
+      break;
+
+    case PROP_PAINT_OVERLAYS:
+      g_value_set_boolean (value, priv->paint_overlays);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -350,6 +465,8 @@ clutter_gst_content_class_init (ClutterGstContentClass *klass)
   gobject_class->dispose        = clutter_gst_content_dispose;
   gobject_class->finalize       = clutter_gst_content_finalize;
 
+  klass->has_painting_content   = clutter_gst_content_has_painting_content;
+
   g_type_class_add_private (klass, sizeof (ClutterGstContentPrivate));
 
   props[PROP_PLAYER] =
@@ -365,6 +482,20 @@ clutter_gst_content_class_init (ClutterGstContentClass *klass)
                          "Cogl Video Sink",
                          CLUTTER_GST_TYPE_VIDEO_SINK,
                          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+
+  props[PROP_PAINT_FRAME] =
+    g_param_spec_boolean ("paint-frame",
+                          "Paint Video Overlays",
+                          "Paint Video Overlays",
+                          TRUE,
+                          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+
+  props[PROP_PAINT_OVERLAYS] =
+    g_param_spec_boolean ("paint-overlays",
+                          "Paint Video Overlays",
+                          "Paint Video Overlays",
+                          TRUE,
+                          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
   g_object_class_install_properties (gobject_class, PROP_LAST, props);
 
 
@@ -398,6 +529,9 @@ clutter_gst_content_init (ClutterGstContent *self)
   content_set_sink (self,
                     CLUTTER_GST_VIDEO_SINK (clutter_gst_create_video_sink ()),
                     FALSE);
+
+  priv->paint_frame = TRUE;
+  priv->paint_overlays = TRUE;
 }
 
 
@@ -445,6 +579,22 @@ clutter_gst_content_get_frame (ClutterGstContent *self)
 }
 
 /**
+ * clutter_gst_content_get_overlays:
+ * @self: A #ClutterGstContent
+ *
+ * Returns: (transfer none) (element-type ClutterGst.Overlay): The #ClutterGstFrame currently attached to 
@self.
+ *
+ * Since: 3.0
+ */
+GPtrArray *
+clutter_gst_content_get_overlays (ClutterGstContent *self)
+{
+  g_return_val_if_fail (CLUTTER_GST_IS_CONTENT (self), NULL);
+
+  return self->priv->overlays;
+}
+
+/**
  * clutter_gst_content_get_sink:
  * @self: A #ClutterGstContent
  *
diff --git a/clutter-gst/clutter-gst-content.h b/clutter-gst/clutter-gst-content.h
index 124b2a8..f5a105a 100644
--- a/clutter-gst/clutter-gst-content.h
+++ b/clutter-gst/clutter-gst-content.h
@@ -74,6 +74,8 @@ struct _ClutterGstContentClass
   /*< private >*/
   GObjectClass parent_class;
 
+  gboolean (* has_painting_content) (ClutterGstContent *self);
+
   void *_padding_dummy[10];
 };
 
@@ -85,6 +87,8 @@ ClutterContent *          clutter_gst_content_new_with_sink (ClutterGstVideoSink
 
 ClutterGstFrame *         clutter_gst_content_get_frame     (ClutterGstContent *self);
 
+GPtrArray *               clutter_gst_content_get_overlays  (ClutterGstContent *self);
+
 void                      clutter_gst_content_set_sink      (ClutterGstContent   *self,
                                                              ClutterGstVideoSink *sink);
 
diff --git a/clutter-gst/clutter-gst-private.h b/clutter-gst/clutter-gst-private.h
index 25dcf5c..c1bbeac 100644
--- a/clutter-gst/clutter-gst-private.h
+++ b/clutter-gst/clutter-gst-private.h
@@ -70,6 +70,10 @@ ClutterGstFrame *clutter_gst_frame_new (void);
 
 ClutterGstFrame *clutter_gst_create_blank_frame (const ClutterColor *color);
 
+ClutterGstOverlay *clutter_gst_overlay_new (void);
+
+ClutterGstOverlays *clutter_gst_overlays_new (void);
+
 void clutter_gst_player_update_frame (ClutterGstPlayer *player,
                                       ClutterGstFrame **frame,
                                       ClutterGstFrame  *new_frame);
@@ -80,6 +84,10 @@ void clutter_gst_frame_update_pixel_aspect_ratio (ClutterGstFrame     *frame,
 void clutter_gst_video_resolution_from_video_info (ClutterGstVideoResolution *resolution,
                                                    GstVideoInfo              *info);
 
+
+gboolean clutter_gst_content_get_paint_frame (ClutterGstContent *content);
+gboolean clutter_gst_content_get_paint_overlays (ClutterGstContent *content);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_GST_PRIVATE_H__ */
diff --git a/clutter-gst/clutter-gst-types.c b/clutter-gst/clutter-gst-types.c
index bdfd827..1d0719e 100644
--- a/clutter-gst/clutter-gst-types.c
+++ b/clutter-gst/clutter-gst-types.c
@@ -70,6 +70,98 @@ G_DEFINE_BOXED_TYPE (ClutterGstFrame,
                      clutter_gst_frame_copy,
                      clutter_gst_frame_free);
 
+
+ClutterGstOverlay *
+clutter_gst_overlay_new (void)
+{
+  return g_slice_new0 (ClutterGstOverlay);
+}
+
+static gpointer
+clutter_gst_overlay_copy (gpointer data)
+{
+  if (G_LIKELY (data))
+    {
+      ClutterGstOverlay *overlay = g_slice_dup (ClutterGstOverlay, data);
+
+      if (overlay->pipeline != COGL_INVALID_HANDLE)
+        overlay->pipeline = cogl_object_ref (overlay->pipeline);
+
+      return overlay;
+    }
+
+  return NULL;
+}
+
+static void
+clutter_gst_overlay_free (gpointer data)
+{
+  if (G_LIKELY (data))
+    {
+      ClutterGstOverlay *overlay = (ClutterGstOverlay *) data;
+
+      if (overlay->pipeline != COGL_INVALID_HANDLE)
+        {
+          cogl_object_unref (overlay->pipeline);
+          overlay->pipeline = COGL_INVALID_HANDLE;
+        }
+      g_slice_free (ClutterGstOverlay, overlay);
+    }
+}
+
+G_DEFINE_BOXED_TYPE (ClutterGstOverlay,
+                     clutter_gst_overlay,
+                     clutter_gst_overlay_copy,
+                     clutter_gst_overlay_free);
+
+ClutterGstOverlays *
+clutter_gst_overlays_new (void)
+{
+  ClutterGstOverlays *overlays = g_slice_new0 (ClutterGstOverlays);
+
+  overlays->overlays = g_ptr_array_new_with_free_func (clutter_gst_overlay_free);
+
+  return overlays;
+}
+
+static gpointer
+clutter_gst_overlays_copy (gpointer data)
+{
+  if (G_LIKELY (data))
+    {
+      ClutterGstOverlays *overlays = g_slice_dup (ClutterGstOverlays, data);
+      GPtrArray *src_overlays = overlays->overlays;
+      guint i;
+
+      overlays->overlays = g_ptr_array_new_with_free_func (clutter_gst_overlay_free);
+      for (i = 0; i < src_overlays->len; i++)
+        g_ptr_array_add (overlays->overlays,
+                         clutter_gst_overlay_copy (g_ptr_array_index (src_overlays,
+                                                                      i)));
+      return overlays;
+    }
+
+  return NULL;
+}
+
+static void
+clutter_gst_overlays_free (gpointer data)
+{
+  if (G_LIKELY (data))
+    {
+      ClutterGstOverlays *overlays = (ClutterGstOverlays *) data;
+
+      g_ptr_array_unref (overlays->overlays);
+
+      g_slice_free (ClutterGstOverlays, overlays);
+    }
+}
+
+G_DEFINE_BOXED_TYPE (ClutterGstOverlays,
+                     clutter_gst_overlays,
+                     clutter_gst_overlays_copy,
+                     clutter_gst_overlays_free);
+
 static ClutterGstBox *
 clutter_gst_box_copy (const ClutterGstBox *box)
 {
diff --git a/clutter-gst/clutter-gst-types.h b/clutter-gst/clutter-gst-types.h
index 7124d90..c8b5019 100644
--- a/clutter-gst/clutter-gst-types.h
+++ b/clutter-gst/clutter-gst-types.h
@@ -39,6 +39,7 @@
 
 typedef struct _ClutterGstBox             ClutterGstBox;
 typedef struct _ClutterGstFrame           ClutterGstFrame;
+typedef struct _ClutterGstOverlay         ClutterGstOverlay;
 typedef struct _ClutterGstVideoResolution ClutterGstVideoResolution;
 
 /**
@@ -72,6 +73,25 @@ typedef enum _ClutterGstBufferingMode
 } ClutterGstBufferingMode;
 
 /**
+ * ClutterGstBox:
+ * @x1: X coordinate of the top left corner
+ * @y1: Y coordinate of the top left corner
+ * @x2: X coordinate of the bottom right corner
+ * @y2: Y coordinate of the bottom right corner
+ *
+ * Bounding box of an area in a video texture or actor's allocation.
+ * Coordinates are usually expressed in the [0, 1] interval.
+ */
+struct _ClutterGstBox
+{
+  gfloat x1;
+  gfloat y1;
+
+  gfloat x2;
+  gfloat y2;
+};
+
+/**
  * ClutterGstVideoResolution:
  * @width: the width, in pixels
  * @height: the height, in pixels
@@ -90,7 +110,7 @@ struct _ClutterGstVideoResolution
 /**
  * ClutterGstFrame:
  * @resolution: a #ClutterGstVideoResolution
- * @pipeline: a #CoglHandle to the pipeline to paint a frame
+ * @pipeline: a #CoglPipeline to paint a frame
  *
  * Represents a frame outputted by the #ClutterGstVideoSink.
  */
@@ -100,29 +120,27 @@ struct _ClutterGstFrame
   CoglPipeline              *pipeline;
 };
 
-
 /**
- * ClutterGstBox:
- * @x1: X coordinate of the top left corner
- * @y1: Y coordinate of the top left corner
- * @x2: X coordinate of the bottom right corner
- * @y2: Y coordinate of the bottom right corner
+ * ClutterGstOverlay:
+ * @position:
+ * @pipeline: a #CoglPipeline to paint an overlay
  *
- * Bounding box of an area in a video texture or actor's allocation.
- * Coordinates are usually expressed in the [0, 1] interval.
  */
-struct _ClutterGstBox
+struct _ClutterGstOverlay
 {
-  gfloat x1;
-  gfloat y1;
-
-  gfloat x2;
-  gfloat y2;
+  ClutterGstBox  position;
+  CoglPipeline  *pipeline;
 };
 
+struct _ClutterGstOverlays
+{
+  GPtrArray *overlays;
+};
 
-GType clutter_gst_frame_get_type (void) G_GNUC_CONST;
-GType clutter_gst_box_get_type   (void) G_GNUC_CONST;
+GType clutter_gst_frame_get_type     (void) G_GNUC_CONST;
+GType clutter_gst_box_get_type       (void) G_GNUC_CONST;
+GType clutter_gst_overlay_get_type   (void) G_GNUC_CONST;
+GType clutter_gst_overlays_get_type  (void) G_GNUC_CONST;
 
 gfloat clutter_gst_box_get_width     (const ClutterGstBox *box);
 gfloat clutter_gst_box_get_height    (const ClutterGstBox *box);
diff --git a/clutter-gst/clutter-gst-video-sink.c b/clutter-gst/clutter-gst-video-sink.c
index 1959c4e..30217ba 100644
--- a/clutter-gst/clutter-gst-video-sink.c
+++ b/clutter-gst/clutter-gst-video-sink.c
@@ -231,8 +231,92 @@ struct _ClutterGstVideoSinkPrivate
   guint8 *tabley;
   guint8 *tableu;
   guint8 *tablev;
+
+  /**/
+  GstVideoOverlayComposition *last_composition;
+  GPtrArray *overlays;
 };
 
+/* Overlays */
+
+static void
+clutter_gst_video_sink_upload_overlay (ClutterGstVideoSink *sink, GstBuffer *buffer)
+{
+  ClutterGstVideoSinkPrivate *priv = sink->priv;
+
+  GstVideoOverlayComposition *composition = NULL;
+  GstVideoOverlayCompositionMeta *composition_meta;
+  guint i, nb_rectangle;
+
+  composition_meta = gst_buffer_get_video_overlay_composition_meta (buffer);
+  if (composition_meta)
+    composition = composition_meta->overlay;
+
+  if (composition == NULL)
+    {
+      if (priv->last_composition != NULL)
+        {
+          gst_video_overlay_composition_unref (priv->last_composition);
+          priv->last_composition = NULL;
+
+          if (priv->overlays)
+            g_boxed_free (CLUTTER_GST_TYPE_OVERLAYS, priv->overlays);
+          priv->overlays = clutter_gst_overlays_new ();
+
+          /* TODO: Emit a new overlay signal */
+        }
+      return;
+    }
+
+  g_clear_pointer (priv->last_composition, gst_video_overlay_composition_unref);
+  priv->last_composition = gst_video_overlay_composition_ref (composition);
+  if (priv->overlays)
+    g_boxed_free (CLUTTER_GST_TYPE_OVERLAYS, priv->overlays);
+  priv->overlays = clutter_gst_overlays_new ();
+
+  nb_rectangle = gst_video_overlay_composition_n_rectangles (composition);
+  for (i = 0; i < nb_rectangle; i++)
+    {
+      ClutterGstOverlay *overlay;
+      GstVideoOverlayRectangle *rectangle;
+      GstBuffer *comp_buffer;
+      GstMapInfo info;
+      GstVideoMeta *vmeta;
+      gint comp_x, comp_y, stride;
+      guint comp_width, comp_height;
+
+      rectangle = gst_video_overlay_composition_get_rectangle (composition, i);
+      comp_buffer =
+        gst_video_overlay_rectangle_get_pixels_unscaled_argb (rectangle,
+                                                              
GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
+
+      gst_video_overlay_rectangle_get_render_rectangle (rectangle,
+                                                        &comp_x, &comp_y, &comp_width, &comp_height);
+
+      vmeta = gst_buffer_get_video_meta (comp_buffer);
+      gst_video_meta_map (vmeta, 0, &info, &data, &stride, GST_MAP_READ);
+
+      overlay = clutter_gst_overlay_new ();
+
+      tex =
+        cogl_texture_new_from_data (comp_width,
+                                    comp_height,
+                                    CLUTTER_GST_TEXTURE_FLAGS,
+                                    COGL_PIXEL_FORMAT_BGRA_8888,
+                                    COGL_PIXEL_FORMAT_BGRA_8888,
+                                    stride, data);
+
+      gst_video_meta_unmap (vmeta, 0, &info);
+      clutter_gst_overlay_effect_add_overlay (priv->overlay_effect,
+                                              comp_x, comp_y,
+                                              comp_width, comp_height,
+                                              tex);
+      cogl_object_unref (tex);
+    }
+
+  /* TODO: Emit a new overlay signal */
+}
+
 /* Snippet cache */
 
 static SnippetCacheEntry *
@@ -2092,6 +2176,8 @@ clutter_gst_video_sink_propose_allocation (GstBaseSink *base_sink, GstQuery *que
                                  GST_VIDEO_META_API_TYPE, NULL);
   gst_query_add_allocation_meta (query,
                                  GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL);
+  gst_query_add_allocation_meta (query,
+                                 GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
 
   return TRUE;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]