[clutter-gst: 9/11] contents: add overlay support



commit 3fe0658a4555abd324cff1bd0ea805a5f75bda63
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Sat Jun 7 07:31:48 2014 +0100

    contents: add overlay support

 clutter-gst/clutter-gst-aspectratio.c |  103 +++++++++++++--
 clutter-gst/clutter-gst-content.c     |  221 +++++++++++++++++++++++++++++----
 clutter-gst/clutter-gst-content.h     |    4 +
 clutter-gst/clutter-gst-crop.c        |  149 ++++++++++++++++++----
 4 files changed, 412 insertions(+), 65 deletions(-)
---
diff --git a/clutter-gst/clutter-gst-aspectratio.c b/clutter-gst/clutter-gst-aspectratio.c
index 21b3802..a31eb0e 100644
--- a/clutter-gst/clutter-gst-aspectratio.c
+++ b/clutter-gst/clutter-gst-aspectratio.c
@@ -133,6 +133,36 @@ clutter_gst_aspectratio_get_frame_box (ClutterGstAspectratio *self,
     }
 }
 
+static void
+clutter_gst_aspectratio_get_overlay_box (ClutterGstAspectratio *self,
+                                         ClutterGstBox         *input_box,
+                                         ClutterGstBox         *paint_box,
+                                         const ClutterGstBox   *frame_input,
+                                         const ClutterGstBox   *frame_box,
+                                         ClutterGstFrame       *frame,
+                                         ClutterGstOverlay     *overlay)
+{
+  gfloat box_width = frame_box->x2 - frame_box->x1,
+    box_height = frame_box->y2 - frame_box->y1;
+
+  /* texturing input */
+  input_box->x1 = (overlay->position.x1 - MAX (frame_input->x1 * frame->resolution.width, 
overlay->position.x1))
+    / (overlay->position.x2 - overlay->position.x1);
+  input_box->y1 = (overlay->position.y1 - MAX (frame_input->y1 * frame->resolution.height, 
overlay->position.y1))
+    / (overlay->position.y2 - overlay->position.y1);
+  input_box->x2 = 1 - (overlay->position.x2 - MIN (frame_input->x2 * frame->resolution.width, 
overlay->position.x2))
+    / (overlay->position.x2 - overlay->position.x1);
+  input_box->y2 = 1 - (overlay->position.y2 - MIN (frame_input->y2 * frame->resolution.height, 
overlay->position.y2))
+    / (overlay->position.y2 - overlay->position.y1);
+
+  /* vertex output */
+  /* TODO: need some clipping here */
+  paint_box->x1 = frame_box->x1 + overlay->position.x1 * box_width / frame->resolution.width;
+  paint_box->y1 = frame_box->y1 + overlay->position.y1 * box_height / frame->resolution.height;
+  paint_box->x2 = frame_box->x1 + overlay->position.x2 * box_width / frame->resolution.width;
+  paint_box->y2 = frame_box->y1 + overlay->position.y2 * box_height / frame->resolution.height;
+}
+
 /**/
 
 static gboolean
@@ -161,8 +191,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 +258,66 @@ 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))
+    {
+      ClutterGstOverlays *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->overlays->len; i++)
+            {
+              ClutterGstOverlay *overlay =
+                g_ptr_array_index (overlays->overlays, i);
+              ClutterGstBox overlay_box;
+              ClutterGstBox overlay_input_box;
+
+              clutter_gst_aspectratio_get_overlay_box (self,
+                                                       &overlay_input_box,
+                                                       &overlay_box,
+                                                       &input_box,
+                                                       &paint_box,
+                                                       frame,
+                                                       overlay);
+
+              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_custom (node,
+                                                               overlay_box.x1, overlay_box.y1,
+                                                               overlay_box.x2, overlay_box.y2,
+                                                               overlay_input_box.x1, overlay_input_box.y1,
+                                                               overlay_input_box.x2, overlay_input_box.y2);
+
+              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..83405a0 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;
+  ClutterGstOverlays *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->overlays->len > 0)
+    return TRUE;
+
+  return FALSE;
+}
+
+/**/
+
 static void
 update_frame (ClutterGstContent *self,
               ClutterGstFrame   *new_frame)
@@ -112,12 +169,38 @@ update_frame (ClutterGstContent *self,
 }
 
 static void
+update_overlays (ClutterGstContent  *self,
+                 ClutterGstOverlays *new_overlays)
+{
+  ClutterGstContentPrivate *priv = self->priv;
+
+  if (priv->overlays != NULL)
+    {
+      g_boxed_free (CLUTTER_GST_TYPE_OVERLAYS, priv->overlays);
+      priv->overlays = NULL;
+    }
+  if (new_overlays != NULL)
+    priv->overlays = g_boxed_copy (CLUTTER_GST_TYPE_OVERLAYS, new_overlays);
+}
+
+static void
 _new_frame_from_pipeline (ClutterGstVideoSink *sink,
                           ClutterGstContent   *self)
 {
   update_frame (self, clutter_gst_video_sink_get_frame (sink));
 
-  clutter_content_invalidate (CLUTTER_CONTENT (self));
+  if (CLUTTER_GST_CONTENT_GET_CLASS (self)->has_painting_content (self))
+    clutter_content_invalidate (CLUTTER_CONTENT (self));
+}
+
+static void
+_new_overlays_from_pipeline (ClutterGstVideoSink *sink,
+                             ClutterGstContent   *self)
+{
+  update_overlays (self, clutter_gst_video_sink_get_overlays (sink));
+
+  if (CLUTTER_GST_CONTENT_GET_CLASS (self)->has_painting_content (self))
+    clutter_content_invalidate (CLUTTER_CONTENT (self));
 }
 
 static void
@@ -183,14 +266,15 @@ content_set_sink (ClutterGstContent   *self,
       priv->sink = g_object_ref_sink (sink);
       g_signal_connect (priv->sink, "new-frame",
                         G_CALLBACK (_new_frame_from_pipeline), self);
+      g_signal_connect (priv->sink, "new-overlays",
+                        G_CALLBACK (_new_overlays_from_pipeline), self);
       g_signal_connect (priv->sink, "notify::pixel-aspect-ratio",
                         G_CALLBACK (_pixel_aspect_ratio_changed), self);
 
       if (clutter_gst_video_sink_is_ready (priv->sink))
         {
-          ClutterGstFrame *frame = clutter_gst_video_sink_get_frame (priv->sink);
-          if (frame)
-            update_frame (self, frame);
+          update_frame (self, clutter_gst_video_sink_get_frame (priv->sink));
+          update_overlays (self, clutter_gst_video_sink_get_overlays (priv->sink));
         }
     }
 
@@ -220,46 +304,82 @@ 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)
+  if (!CLUTTER_GST_CONTENT_GET_CLASS (self)->has_painting_content (self))
     return;
 
   clutter_actor_get_content_box (actor, &box);
   paint_opacity = clutter_actor_get_paint_opacity (actor);
   repeat = clutter_actor_get_content_repeat (actor);
 
+  if (priv->paint_frame && priv->current_frame)
+    {
+      cogl_pipeline_set_color4ub (priv->current_frame->pipeline,
+                                  paint_opacity, paint_opacity,
+                                  paint_opacity, paint_opacity);
 
-  cogl_pipeline_set_color4ub (priv->current_frame->pipeline,
-                              paint_opacity, paint_opacity,
-                              paint_opacity, paint_opacity);
+      node = clutter_pipeline_node_new (priv->current_frame->pipeline);
+      clutter_paint_node_set_name (node, "Video");
 
-  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
+        {
+          float t_w = 1.f, t_h = 1.f;
 
-  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_X_AXIS) != FALSE)
+            t_w = (box.x2 - box.x1) / priv->current_frame->resolution.width;
 
-      if ((repeat & CLUTTER_REPEAT_X_AXIS) != FALSE)
-        t_w = (box.x2 - box.x1) / priv->current_frame->resolution.width;
+          if ((repeat & CLUTTER_REPEAT_Y_AXIS) != FALSE)
+            t_h = (box.y2 - box.y1) / priv->current_frame->resolution.height;
 
-      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_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->overlays->len; i++)
+        {
+          ClutterGstOverlay *overlay =
+            g_ptr_array_index (priv->overlays->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 +408,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 +440,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 +486,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 +503,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 +550,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 +600,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
+ */
+ClutterGstOverlays *
+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..dfd0633 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);
 
+ClutterGstOverlays *      clutter_gst_content_get_overlays  (ClutterGstContent *self);
+
 void                      clutter_gst_content_set_sink      (ClutterGstContent   *self,
                                                              ClutterGstVideoSink *sink);
 
diff --git a/clutter-gst/clutter-gst-crop.c b/clutter-gst/clutter-gst-crop.c
index 77b964c..6e8dd64 100644
--- a/clutter-gst/clutter-gst-crop.c
+++ b/clutter-gst/clutter-gst-crop.c
@@ -87,6 +87,50 @@ clutter_gst_crop_get_preferred_size (ClutterContent *content,
   return TRUE;
 }
 
+static gboolean
+clutter_gst_crop_get_overlay_box (ClutterGstCrop      *self,
+                                  ClutterGstBox       *input_box,
+                                  ClutterGstBox       *paint_box,
+                                  const ClutterGstBox *frame_box,
+                                  ClutterGstFrame     *frame,
+                                  ClutterGstOverlay   *overlay)
+{
+  ClutterGstCropPrivate *priv = self->priv;
+  ClutterGstBox overlay_input_box;
+  ClutterGstBox frame_input_box;
+
+  /* Clamped frame input */
+  frame_input_box.x1 = priv->input_region.x1 * frame->resolution.width;
+  frame_input_box.y1 = priv->input_region.y1 * frame->resolution.height;
+  frame_input_box.x2 = priv->input_region.x2 * frame->resolution.width;
+  frame_input_box.y2 = priv->input_region.y2 * frame->resolution.height;
+
+  /* Clamp overlay box to frame's clamping */
+  overlay_input_box.x1 = MAX (priv->input_region.x1 * frame->resolution.width, overlay->position.x1);
+  overlay_input_box.y1 = MAX (priv->input_region.y1 * frame->resolution.height, overlay->position.y1);
+  overlay_input_box.x2 = MIN (priv->input_region.x2 * frame->resolution.width, overlay->position.x2);
+  overlay_input_box.y2 = MIN (priv->input_region.y2 * frame->resolution.height, overlay->position.y2);
+
+  /* normalize overlay input */
+  input_box->x1 = (overlay_input_box.x1 - overlay->position.x1) / (overlay->position.x2 - 
overlay->position.x1);
+  input_box->y1 = (overlay_input_box.y1 - overlay->position.y1) / (overlay->position.y2 - 
overlay->position.y1);
+  input_box->x2 = (overlay_input_box.x2 - overlay->position.x1) / (overlay->position.x2 - 
overlay->position.x1);
+  input_box->y2 = (overlay_input_box.y2 - overlay->position.y1) / (overlay->position.y2 - 
overlay->position.y1);
+
+  /* bail if not in the visible scope */
+  if (input_box->x1 >= input_box->x2 ||
+      input_box->y1 >= input_box->y2)
+    return FALSE;
+
+  /* Clamp overlay output */
+  paint_box->x1 = frame_box->x1 + (frame_box->x2 - frame_box->x1) * ((overlay_input_box.x1 - 
frame_input_box.x1) / (frame_input_box.x2 - frame_input_box.x1));
+  paint_box->y1 = frame_box->y1 + (frame_box->y2 - frame_box->y1) * ((overlay_input_box.y1 - 
frame_input_box.y1) / (frame_input_box.y2 - frame_input_box.y1));
+  paint_box->x2 = frame_box->x1 + (frame_box->x2 - frame_box->x1) * ((overlay_input_box.x2 - 
frame_input_box.x1) / (frame_input_box.x2 - frame_input_box.x1));
+  paint_box->y2 = frame_box->y1 + (frame_box->y2 - frame_box->y1) * ((overlay_input_box.y2 - 
frame_input_box.y1) / (frame_input_box.y2 - frame_input_box.y1));
+
+  return TRUE;
+}
+
 static void
 clutter_gst_crop_paint_content (ClutterContent   *content,
                                 ClutterActor     *actor,
@@ -94,10 +138,11 @@ clutter_gst_crop_paint_content (ClutterContent   *content,
 {
   ClutterGstCrop *self = CLUTTER_GST_CROP (content);
   ClutterGstCropPrivate *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);
   guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
   ClutterActorBox content_box;
+  ClutterGstBox frame_box;
   gfloat box_width, box_height;
   ClutterColor color;
   ClutterPaintNode *node;
@@ -171,30 +216,82 @@ clutter_gst_crop_paint_content (ClutterContent   *content,
     }
 
 
-  cogl_pipeline_set_color4ub (frame->pipeline,
-                              paint_opacity,
-                              paint_opacity,
-                              paint_opacity,
-                              paint_opacity);
-  if (priv->cull_backface)
-    cogl_pipeline_set_cull_face_mode (frame->pipeline,
-                                      COGL_PIPELINE_CULL_FACE_MODE_BACK);
-
-  node = clutter_pipeline_node_new (frame->pipeline);
-  clutter_paint_node_set_name (node, "CropVideoFrame");
-
-  clutter_paint_node_add_texture_rectangle_custom (node,
-                                                   content_box.x1 + box_width * priv->output_region.x1,
-                                                   content_box.y1 + box_height * priv->output_region.y1,
-                                                   content_box.x1 + box_width * priv->output_region.x2,
-                                                   content_box.y1 + box_height * priv->output_region.y2,
-                                                   priv->input_region.x1,
-                                                   priv->input_region.y1,
-                                                   priv->input_region.x2,
-                                                   priv->input_region.y2);
-
-  clutter_paint_node_add_child (root, node);
-  clutter_paint_node_unref (node);
+  frame_box.x1 = content_box.x1 + box_width * priv->output_region.x1;
+  frame_box.y1 = content_box.y1 + box_height * priv->output_region.y1;
+  frame_box.x2 = content_box.x1 + box_width * priv->output_region.x2;
+  frame_box.y2 = content_box.y1 + box_height * priv->output_region.y2;
+
+  if (clutter_gst_content_get_paint_frame (gst_content))
+    {
+      cogl_pipeline_set_color4ub (frame->pipeline,
+                                  paint_opacity,
+                                  paint_opacity,
+                                  paint_opacity,
+                                  paint_opacity);
+      if (priv->cull_backface)
+        cogl_pipeline_set_cull_face_mode (frame->pipeline,
+                                          COGL_PIPELINE_CULL_FACE_MODE_BACK);
+
+      node = clutter_pipeline_node_new (frame->pipeline);
+      clutter_paint_node_set_name (node, "CropVideoFrame");
+
+      clutter_paint_node_add_texture_rectangle_custom (node,
+                                                       frame_box.x1,
+                                                       frame_box.y1,
+                                                       frame_box.x2,
+                                                       frame_box.y2,
+                                                       priv->input_region.x1,
+                                                       priv->input_region.y1,
+                                                       priv->input_region.x2,
+                                                       priv->input_region.y2);
+      clutter_paint_node_add_child (root, node);
+      clutter_paint_node_unref (node);
+    }
+
+
+  if (clutter_gst_content_get_paint_overlays (gst_content))
+    {
+      ClutterGstOverlays *overlays = clutter_gst_content_get_overlays (gst_content);
+
+      if (overlays)
+        {
+          guint i;
+
+          for (i = 0; i < overlays->overlays->len; i++)
+            {
+              ClutterGstOverlay *overlay =
+                g_ptr_array_index (overlays->overlays, i);
+              ClutterGstBox overlay_box;
+              ClutterGstBox overlay_input_box;
+
+              /* overlay outside the visible scope? -> next */
+              if (!clutter_gst_crop_get_overlay_box (self,
+                                                     &overlay_input_box,
+                                                     &overlay_box,
+                                                     /* &content_box, */
+                                                     &frame_box,
+                                                     frame,
+                                                     overlay))
+                continue;
+
+              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_custom (node,
+                                                               overlay_box.x1, overlay_box.y1,
+                                                               overlay_box.x2, overlay_box.y2,
+                                                               overlay_input_box.x1, overlay_input_box.y1,
+                                                               overlay_input_box.x2, overlay_input_box.y2);
+
+              clutter_paint_node_add_child (root, node);
+              clutter_paint_node_unref (node);
+            }
+        }
+    }
 }
 
 static void


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