[clutter-gst] switch ClutterGst to use ClutterContent



commit 2b077e89c620c630e4fdaf2d9cb73ab141127ea9
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Mon Jul 1 16:10:55 2013 +0100

    switch ClutterGst to use ClutterContent

 clutter-gst/clutter-gst-aspectratio.c   |  413 +++++++++++++++++++-----------
 clutter-gst/clutter-gst-aspectratio.h   |   14 +-
 clutter-gst/clutter-gst-camera.c        |   21 ++-
 clutter-gst/clutter-gst-content.c       |  138 +++++++++--
 clutter-gst/clutter-gst-content.h       |   12 +-
 clutter-gst/clutter-gst-crop.c          |  181 ++++++++++----
 clutter-gst/clutter-gst-crop.h          |    6 +-
 clutter-gst/clutter-gst-playback.c      |   23 ++-
 clutter-gst/clutter-gst-player.c        |   24 ++
 clutter-gst/clutter-gst-player.h        |    5 +-
 clutter-gst/clutter-gst-private.h       |   14 +-
 clutter-gst/clutter-gst-types.c         |   36 +++
 clutter-gst/clutter-gst-types.h         |    3 +
 examples/camera-player.c                |   17 +-
 examples/pieces.js                      |   17 +-
 examples/video-flip.js                  |   56 +++--
 examples/video-flip2.js                 |   46 ++--
 examples/video-player.c                 |   10 +-
 examples/video-wall.js                  |   14 +-
 tests/test-alpha.c                      |   63 +----
 tests/test-rgb-upload.c                 |   56 +----
 tests/test-start-stop.c                 |   54 +----
 tests/test-video-actor-new-unref-loop.c |    8 +-
 tests/test-yuv-upload.c                 |   57 +----
 24 files changed, 781 insertions(+), 507 deletions(-)
---
diff --git a/clutter-gst/clutter-gst-aspectratio.c b/clutter-gst/clutter-gst-aspectratio.c
index 7baa127..c875a58 100644
--- a/clutter-gst/clutter-gst-aspectratio.c
+++ b/clutter-gst/clutter-gst-aspectratio.c
@@ -3,8 +3,9 @@
  *
  * GStreamer integration library for Clutter.
  *
- * clutter-gst-aspectratio.c - An actor rendering a video with respect
- * to its aspect ratio.
+ * clutter-gst-aspectratio.c - An object implementing the
+ * ClutterContent interface to render a video with respect to its
+ * aspect ratio.
  *
  * Authored by Lionel Landwerlin <lionel g landwerlin linux intel com>
  *
@@ -29,19 +30,21 @@
 #include "clutter-gst-aspectratio.h"
 #include "clutter-gst-private.h"
 
-G_DEFINE_TYPE (ClutterGstAspectratio, clutter_gst_aspectratio, CLUTTER_GST_TYPE_ACTOR)
+static void content_iface_init (ClutterContentIface *iface);
 
-#define ASPECTRATIO_PRIVATE(o) \
-  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CLUTTER_GST_TYPE_ASPECTRATIO, ClutterGstAspectratioPrivate))
+G_DEFINE_TYPE_WITH_CODE (ClutterGstAspectratio,
+                         clutter_gst_aspectratio,
+                         CLUTTER_GST_TYPE_CONTENT,
+                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
+                                                content_iface_init))
+
+#define ASPECTRATIO_PRIVATE(o)                                  \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o),                            \
+                                CLUTTER_GST_TYPE_ASPECTRATIO,   \
+                                ClutterGstAspectratioPrivate))
 
 struct _ClutterGstAspectratioPrivate
 {
-  ClutterGstPlayer *player;
-
-  gint frame_width;
-  gint frame_height;
-  ClutterActorBox paint_box;
-
   gboolean paint_borders;
 };
 
@@ -55,114 +58,22 @@ enum
 /**/
 
 static void
-clutter_gst_aspectratio_get_preferred_width (ClutterActor *actor,
-                                             gfloat        for_height,
-                                             gfloat       *min_width,
-                                             gfloat       *nat_width)
-{
-  ClutterGstAspectratioPrivate *priv = CLUTTER_GST_ASPECTRATIO (actor)->priv;
-
-  if (min_width)
-    *min_width = 0;
-  if (nat_width)
-    {
-      gdouble aspect = (gdouble) priv->frame_width / (gdouble) priv->frame_height;
-
-      if (for_height > 0)
-        *nat_width = for_height * aspect;
-      else
-        *nat_width = priv->frame_width;
-    }
-}
-
-static void
-clutter_gst_aspectratio_get_preferred_height (ClutterActor *actor,
-                                              gfloat        for_width,
-                                              gfloat       *min_height,
-                                              gfloat       *nat_height)
-{
-  ClutterGstAspectratioPrivate *priv = CLUTTER_GST_ASPECTRATIO (actor)->priv;
-
-  if (min_height)
-    *min_height = 0;
-  if (nat_height)
-    {
-      gdouble aspect = (gdouble) priv->frame_width / (gdouble) priv->frame_height;
-
-      if (for_width > 0)
-        *nat_height = for_width / aspect;
-      else
-        *nat_height = priv->frame_height;
-    }
-}
-
-
-static void
-clutter_gst_aspectratio_paint_frame (ClutterGstActor *self,
-                                     ClutterGstFrame *frame)
-{
-  ClutterGstAspectratioPrivate *priv = CLUTTER_GST_ASPECTRATIO (self)->priv;
-  guint8 paint_opacity;
-
-  paint_opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self));
-  cogl_pipeline_set_color4ub (frame->pipeline,
-                              paint_opacity,
-                              paint_opacity,
-                              paint_opacity,
-                              paint_opacity);
-  cogl_set_source (frame->pipeline);
-
-  cogl_rectangle (priv->paint_box.x1, priv->paint_box.y1,
-                  priv->paint_box.x2, priv->paint_box.y2);
-
-  if (priv->paint_borders)
-    {
-      ClutterColor bg_color;
-      ClutterActorBox box;
-      gfloat box_width, box_height;
-
-      clutter_actor_get_background_color (CLUTTER_ACTOR (self), &bg_color);
-      clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &box);
-
-      box_width = clutter_actor_box_get_width (&box);
-      box_height = clutter_actor_box_get_height (&box);
-
-      cogl_set_source_color4ub (bg_color.red,
-                                bg_color.green,
-                                bg_color.blue,
-                                paint_opacity);
-
-      if (box_width != clutter_actor_box_get_width (&priv->paint_box))
-        {
-          cogl_rectangle (0, 0, priv->paint_box.x1, box_height);
-          cogl_rectangle (priv->paint_box.x2, 0, box_width, box_height);
-        }
-      if (box_height != clutter_actor_box_get_height (&priv->paint_box))
-        {
-          cogl_rectangle (0, 0, box_width, priv->paint_box.y1);
-          cogl_rectangle (0, priv->paint_box.y2, box_width, box_height);
-        }
-    }
-}
-
-static void
-_recompute_paint_box (ClutterGstAspectratio *self)
+clutter_gst_aspectratio_get_frame_box (ClutterGstAspectratio *self,
+                                       ClutterGstBox         *paint_box,
+                                       ClutterActorBox       *content_box,
+                                       ClutterGstFrame       *frame)
 {
-  ClutterGstAspectratioPrivate *priv = self->priv;
-  ClutterActorBox box;
   gfloat actor_width, actor_height;
   gdouble new_width, new_height;
   gdouble frame_aspect, actor_aspect;
 
-  clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &box);
-
-  actor_width = box.x2 - box.x1;
-  actor_height = box.y2 - box.y1;
+  actor_width = clutter_actor_box_get_width (content_box);
+  actor_height = clutter_actor_box_get_height (content_box);
 
   if (actor_width <= 0 || actor_height <= 0)
     return;
 
-  frame_aspect = (gdouble) priv->frame_width / (gdouble) priv->frame_height;
+  frame_aspect = (gdouble) frame->resolution.width / (gdouble) frame->resolution.height;
   actor_aspect = actor_width / actor_height;
 
   if (actor_aspect < frame_aspect)
@@ -176,54 +87,255 @@ _recompute_paint_box (ClutterGstAspectratio *self)
       new_width = actor_height * frame_aspect;
     }
 
-  priv->paint_box.x1 = (actor_width - new_width) / 2;
-  priv->paint_box.y1 = (actor_height - new_height) / 2;
-  priv->paint_box.x2 = priv->paint_box.x1 + new_width;
-  priv->paint_box.y2 = priv->paint_box.y1 + new_height;
+  paint_box->x1 = (actor_width - new_width) / 2;
+  paint_box->y1 = (actor_height - new_height) / 2;
+  paint_box->x2 = paint_box->x1 + new_width;
+  paint_box->y2 = paint_box->y1 + new_height;
 }
 
-static void
-_player_size_changed (ClutterGstPlayer      *player,
-                      gint                   width,
-                      gint                   height,
-                      ClutterGstAspectratio *self)
+/**/
+
+static gboolean
+clutter_gst_aspectratio_get_preferred_size (ClutterContent *content,
+                                            gfloat         *width,
+                                            gfloat         *height)
 {
-  ClutterGstAspectratioPrivate *priv = self->priv;
+  ClutterGstFrame *frame =
+    clutter_gst_content_get_frame (CLUTTER_GST_CONTENT (content));
+
+  if (!frame)
+    return FALSE;
 
-  priv->frame_width = width;
-  priv->frame_height = height;
+  if (width)
+    *width = frame->resolution.width;
+  if (height)
+    *height = frame->resolution.height;
 
-  _recompute_paint_box (self);
-  clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
+  return TRUE;
 }
 
 static void
-_player_changed (ClutterGstAspectratio *self,
-                 GParamSpec            *spec,
-                 gpointer               user_data)
+clutter_gst_aspectratio_paint_content (ClutterContent   *content,
+                                       ClutterActor     *actor,
+                                       ClutterPaintNode *root)
 {
+  ClutterGstAspectratio *self = CLUTTER_GST_ASPECTRATIO (content);
   ClutterGstAspectratioPrivate *priv = self->priv;
-  ClutterGstPlayer *player = clutter_gst_actor_get_player (CLUTTER_GST_ACTOR (self));
+  ClutterGstFrame *frame =
+    clutter_gst_content_get_frame (CLUTTER_GST_CONTENT (content));
+  ClutterGstBox paint_box;
+  ClutterActorBox content_box;
+  ClutterPaintNode *node;
+  guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
+  ClutterColor color;
+
+  clutter_actor_get_content_box (actor, &content_box);
+
+  if (!frame)
+    {
+      /* No frame to paint, just paint the background color of the
+         actor. */
+      if (priv->paint_borders)
+        {
+          clutter_actor_get_background_color (actor, &color);
+          color.alpha = paint_opacity;
+
+          clutter_paint_node_add_rectangle_custom (node,
+                                                   content_box.x1, content_box.y1,
+                                                   content_box.x2, content_box.y2);
+          clutter_paint_node_add_child (root, node);
+          clutter_paint_node_unref (node);
+        }
+
+      return;
+    }
+
+  clutter_gst_aspectratio_get_frame_box (self, &paint_box, &content_box, frame);
 
-  if (priv->player)
-    g_signal_handlers_disconnect_by_func (priv->player, _player_size_changed, self);
-  priv->player = player;
-  if (priv->player)
+  if (priv->paint_borders)
     {
-      ClutterGstFrame *frame = clutter_gst_player_get_frame (player);
+      clutter_actor_get_background_color (actor, &color);
+      color.alpha = paint_opacity;
 
-      priv->frame_width = frame->resolution.width;
-      priv->frame_height = frame->resolution.height;
+      node = clutter_color_node_new (&color);
+      clutter_paint_node_set_name (node, "AspectRatioVideoBorders");
 
-      g_signal_connect (priv->player, "size-change",
-                        G_CALLBACK (_player_size_changed), self);
+      if (clutter_actor_box_get_width (&content_box) !=
+          clutter_gst_box_get_width (&paint_box))
+        {
+          clutter_paint_node_add_rectangle_custom (node,
+                                                   content_box.x1, content_box.y1,
+                                                   paint_box.x1, content_box.y2);
+          clutter_paint_node_add_rectangle_custom (node,
+                                                   paint_box.x2, content_box.y1,
+                                                   content_box.x2, content_box.y2);
+        }
+      if (clutter_actor_box_get_height (&content_box) !=
+          clutter_gst_box_get_height (&paint_box))
+        {
+          clutter_paint_node_add_rectangle_custom (node,
+                                                   content_box.x1, content_box.y1,
+                                                   content_box.x2, paint_box.y1);
+          clutter_paint_node_add_rectangle_custom (node,
+                                                   content_box.x1, paint_box.y2,
+                                                   content_box.x2, content_box.y2);
+        }
+
+      clutter_paint_node_add_child (root, node);
+      clutter_paint_node_unref (node);
     }
 
-  _recompute_paint_box (self);
+  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");
+
+  clutter_paint_node_add_rectangle_custom (node,
+                                           paint_box.x1, paint_box.y1,
+                                           paint_box.x2, paint_box.y2);
+
+  clutter_paint_node_add_child (root, node);
+  clutter_paint_node_unref (node);
+}
+
+static void
+content_iface_init (ClutterContentIface *iface)
+{
+  iface->get_preferred_size = clutter_gst_aspectratio_get_preferred_size;
+  iface->paint_content = clutter_gst_aspectratio_paint_content;
 }
 
 /**/
 
+/* static void */
+/* clutter_gst_aspectratio_paint_frame (ClutterGstActor *self, */
+/*                                      ClutterGstFrame *frame) */
+/* { */
+/*   ClutterGstAspectratioPrivate *priv = CLUTTER_GST_ASPECTRATIO (self)->priv; */
+/*   guint8 paint_opacity; */
+
+/*   paint_opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)); */
+/*   cogl_pipeline_set_color4ub (frame->pipeline, */
+/*                               paint_opacity, */
+/*                               paint_opacity, */
+/*                               paint_opacity, */
+/*                               paint_opacity); */
+/*   cogl_set_source (frame->pipeline); */
+
+/*   cogl_rectangle (priv->paint_box.x1, priv->paint_box.y1, */
+/*                   priv->paint_box.x2, priv->paint_box.y2); */
+
+/*   if (priv->paint_borders) */
+/*     { */
+/*       ClutterColor bg_color; */
+/*       ClutterActorBox box; */
+/*       gfloat box_width, box_height; */
+
+/*       clutter_actor_get_background_color (CLUTTER_ACTOR (self), &bg_color); */
+/*       clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &box); */
+
+/*       box_width = clutter_actor_box_get_width (&box); */
+/*       box_height = clutter_actor_box_get_height (&box); */
+
+/*       cogl_set_source_color4ub (bg_color.red, */
+/*                                 bg_color.green, */
+/*                                 bg_color.blue, */
+/*                                 paint_opacity); */
+
+/*       if (box_width != clutter_actor_box_get_width (&priv->paint_box)) */
+/*         { */
+/*           cogl_rectangle (0, 0, priv->paint_box.x1, box_height); */
+/*           cogl_rectangle (priv->paint_box.x2, 0, box_width, box_height); */
+/*         } */
+/*       if (box_height != clutter_actor_box_get_height (&priv->paint_box)) */
+/*         { */
+/*           cogl_rectangle (0, 0, box_width, priv->paint_box.y1); */
+/*           cogl_rectangle (0, priv->paint_box.y2, box_width, box_height); */
+/*         } */
+/*     } */
+/* } */
+
+/* static void */
+/* _recompute_paint_box (ClutterGstAspectratio *self) */
+/* { */
+/*   ClutterGstAspectratioPrivate *priv = self->priv; */
+/*   ClutterActorBox box; */
+/*   gfloat actor_width, actor_height; */
+/*   gdouble new_width, new_height; */
+/*   gdouble frame_aspect, actor_aspect; */
+
+/*   clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &box); */
+
+/*   actor_width = box.x2 - box.x1; */
+/*   actor_height = box.y2 - box.y1; */
+
+/*   if (actor_width <= 0 || actor_height <= 0) */
+/*     return; */
+
+/*   frame_aspect = (gdouble) priv->frame_width / (gdouble) priv->frame_height; */
+/*   actor_aspect = actor_width / actor_height; */
+
+/*   if (actor_aspect < frame_aspect) */
+/*     { */
+/*       new_width = actor_width; */
+/*       new_height = actor_width / frame_aspect; */
+/*     } */
+/*   else */
+/*     { */
+/*       new_height = actor_height; */
+/*       new_width = actor_height * frame_aspect; */
+/*     } */
+
+/*   priv->paint_box.x1 = (actor_width - new_width) / 2; */
+/*   priv->paint_box.y1 = (actor_height - new_height) / 2; */
+/*   priv->paint_box.x2 = priv->paint_box.x1 + new_width; */
+/*   priv->paint_box.y2 = priv->paint_box.y1 + new_height; */
+/* } */
+
+/* static void */
+/* _player_size_changed (ClutterGstPlayer      *player, */
+/*                       gint                   width, */
+/*                       gint                   height, */
+/*                       ClutterGstAspectratio *self) */
+/* { */
+/*   ClutterGstAspectratioPrivate *priv = self->priv; */
+
+/*   priv->frame_width = width; */
+/*   priv->frame_height = height; */
+
+/*   _recompute_paint_box (self); */
+/*   clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); */
+/* } */
+
+/* static void */
+/* _player_changed (ClutterGstAspectratio *self, */
+/*                  GParamSpec            *spec, */
+/*                  gpointer               user_data) */
+/* { */
+/*   ClutterGstAspectratioPrivate *priv = self->priv; */
+/*   ClutterGstPlayer *player = clutter_gst_actor_get_player (CLUTTER_GST_ACTOR (self)); */
+
+/*   if (priv->player) */
+/*     g_signal_handlers_disconnect_by_func (priv->player, _player_size_changed, self); */
+/*   priv->player = player; */
+/*   if (priv->player) */
+/*     { */
+/*       ClutterGstFrame *frame = clutter_gst_player_get_frame (player); */
+
+/*       priv->frame_width = frame->resolution.width; */
+/*       priv->frame_height = frame->resolution.height; */
+
+/*       g_signal_connect (priv->player, "size-change", */
+/*                         G_CALLBACK (_player_size_changed), self); */
+/*     } */
+
+/*   _recompute_paint_box (self); */
+/* } */
+
+/**/
+
 static void
 clutter_gst_aspectratio_get_property (GObject    *object,
                                       guint       property_id,
@@ -253,7 +365,11 @@ clutter_gst_aspectratio_set_property (GObject      *object,
   switch (property_id)
     {
     case PROP_PAINT_BORDERS:
-      priv->paint_borders = g_value_get_boolean (value);
+      if (priv->paint_borders != g_value_get_boolean (value))
+        {
+          priv->paint_borders = g_value_get_boolean (value);
+          clutter_content_invalidate (CLUTTER_CONTENT (object));
+        }
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -276,8 +392,6 @@ static void
 clutter_gst_aspectratio_class_init (ClutterGstAspectratioClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-  ClutterGstActorClass *gst_actor_class = CLUTTER_GST_ACTOR_CLASS (klass);
   GParamSpec *pspec;
 
   g_type_class_add_private (klass, sizeof (ClutterGstAspectratioPrivate));
@@ -287,11 +401,6 @@ clutter_gst_aspectratio_class_init (ClutterGstAspectratioClass *klass)
   object_class->dispose = clutter_gst_aspectratio_dispose;
   object_class->finalize = clutter_gst_aspectratio_finalize;
 
-  actor_class->get_preferred_width = clutter_gst_aspectratio_get_preferred_width;
-  actor_class->get_preferred_height = clutter_gst_aspectratio_get_preferred_height;
-
-  gst_actor_class->paint_frame = clutter_gst_aspectratio_paint_frame;
-
   /**
    * ClutterGstAspectratio:paint-borders:
    *
@@ -311,14 +420,14 @@ static void
 clutter_gst_aspectratio_init (ClutterGstAspectratio *self)
 {
   self->priv = ASPECTRATIO_PRIVATE (self);
-
-  g_signal_connect (self, "notify::player",
-                    G_CALLBACK (_player_changed), NULL);
-  g_signal_connect_swapped (self, "allocation-changed",
-                            G_CALLBACK (_recompute_paint_box), self);
 }
 
-ClutterActor *
+/**
+ * clutter_gst_aspectratio_new:
+ *
+ * Returns: (transfer full): a new #ClutterGstAspectratio instance
+ */
+ClutterContent *
 clutter_gst_aspectratio_new (void)
 {
   return g_object_new (CLUTTER_GST_TYPE_ASPECTRATIO, NULL);
diff --git a/clutter-gst/clutter-gst-aspectratio.h b/clutter-gst/clutter-gst-aspectratio.h
index fa9d8c1..3f30dad 100644
--- a/clutter-gst/clutter-gst-aspectratio.h
+++ b/clutter-gst/clutter-gst-aspectratio.h
@@ -3,8 +3,9 @@
  *
  * GStreamer integration library for Clutter.
  *
- * clutter-gst-aspectratio.c - An actor rendering a video with respect
- * to its aspect ratio.
+ * clutter-gst-aspectratio.c - An object implementing the
+ * ClutterContent interface to render a video with respect to its
+ * aspect ratio.
  *
  * Authored by Lionel Landwerlin <lionel g landwerlin linux intel com>
  *
@@ -35,7 +36,7 @@
 
 #include <glib-object.h>
 
-#include <clutter-gst/clutter-gst-actor.h>
+#include <clutter-gst/clutter-gst-content.h>
 
 G_BEGIN_DECLS
 
@@ -67,19 +68,20 @@ typedef struct _ClutterGstAspectratioPrivate ClutterGstAspectratioPrivate;
 
 struct _ClutterGstAspectratio
 {
-  ClutterGstActor parent;
+  /*< private >*/
+  ClutterGstContent parent;
 
   ClutterGstAspectratioPrivate *priv;
 };
 
 struct _ClutterGstAspectratioClass
 {
-  ClutterGstActorClass parent_class;
+  ClutterGstContentClass parent_class;
 };
 
 GType clutter_gst_aspectratio_get_type (void) G_GNUC_CONST;
 
-ClutterActor *clutter_gst_aspectratio_new (void);
+ClutterContent *clutter_gst_aspectratio_new (void);
 
 G_END_DECLS
 
diff --git a/clutter-gst/clutter-gst-camera.c b/clutter-gst/clutter-gst-camera.c
index 142eb48..a5736db 100644
--- a/clutter-gst/clutter-gst-camera.c
+++ b/clutter-gst/clutter-gst-camera.c
@@ -70,6 +70,7 @@ struct _ClutterGstCameraPrivate
   GstBus *bus;
   GstElement *camerabin;
   GstElement *camera_source;
+  CoglGstVideoSink *video_sink;
 
   /* video filter */
   GstElement *video_filter_bin;
@@ -137,6 +138,14 @@ clutter_gst_camera_get_pipeline (ClutterGstPlayer *player)
   return priv->camerabin;
 }
 
+static CoglGstVideoSink *
+clutter_gst_camera_get_video_sink (ClutterGstPlayer *player)
+{
+  ClutterGstCameraPrivate *priv = CLUTTER_GST_CAMERA (player)->priv;
+
+  return priv->video_sink;
+}
+
 static gboolean
 clutter_gst_camera_get_idle (ClutterGstPlayer *player)
 {
@@ -198,6 +207,8 @@ player_iface_init (ClutterGstPlayerIface *iface)
 {
   iface->get_frame = clutter_gst_camera_get_frame;
   iface->get_pipeline = clutter_gst_camera_get_pipeline;
+  iface->get_video_sink = clutter_gst_camera_get_video_sink;
+
   iface->get_idle = clutter_gst_camera_get_idle;
 
   iface->get_audio_volume = clutter_gst_camera_get_audio_volume;
@@ -863,18 +874,18 @@ setup_pipeline (ClutterGstCamera *self)
       return FALSE;
     }
 
-  video_sink = cogl_gst_video_sink_new (clutter_gst_get_cogl_context ());
+  priv->video_sink = cogl_gst_video_sink_new (clutter_gst_get_cogl_context ());
 
-  g_signal_connect (video_sink, "new-frame",
+  g_signal_connect (priv->video_sink, "new-frame",
                     G_CALLBACK (_new_frame_from_pipeline), self);
-  g_signal_connect (video_sink, "pipeline-ready",
+  g_signal_connect (priv->video_sink, "pipeline-ready",
                     G_CALLBACK (_ready_from_pipeline), self);
-  g_signal_connect (video_sink, "notify::pixel-aspect-ratio",
+  g_signal_connect (priv->video_sink, "notify::pixel-aspect-ratio",
                     G_CALLBACK (_pixel_aspect_ratio_changed), self);
 
 
   g_object_set (priv->camerabin,
-                "viewfinder-sink", video_sink,
+                "viewfinder-sink", priv->video_sink,
                 NULL);
 
   set_video_profile (self);
diff --git a/clutter-gst/clutter-gst-content.c b/clutter-gst/clutter-gst-content.c
index 2a8fea7..b1e819f 100644
--- a/clutter-gst/clutter-gst-content.c
+++ b/clutter-gst/clutter-gst-content.c
@@ -33,11 +33,12 @@
 #include "clutter-gst-private.h"
 #include "clutter-gst-marshal.h"
 
-static void clutter_content_iface_init (ClutterContentIface *iface);
+static void content_iface_init (ClutterContentIface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (ClutterGstContent, clutter_gst_content, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
-                                                clutter_content_iface_init));
+G_DEFINE_TYPE_WITH_CODE (ClutterGstContent,
+                         clutter_gst_content,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, content_iface_init))
 
 #define CLUTTER_GST_CONTENT_GET_PRIVATE(obj)\
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
@@ -48,6 +49,7 @@ G_DEFINE_TYPE_WITH_CODE (ClutterGstContent, clutter_gst_content, G_TYPE_OBJECT,
 struct _ClutterGstContentPrivate
 {
   CoglGstVideoSink *sink;
+  ClutterGstPlayer *player;
   ClutterGstFrame *current_frame;
 };
 
@@ -56,6 +58,7 @@ enum
   PROP_0,
 
   PROP_VIDEO_SINK,
+  PROP_PLAYER,
 
   PROP_LAST
 };
@@ -115,15 +118,50 @@ _pixel_aspect_ratio_changed (CoglGstVideoSink  *sink,
                                                sink);
 }
 
+static void content_set_sink (ClutterGstContent *self,
+                              CoglGstVideoSink  *sink,
+                              gboolean           set_from_player);
+
+static void
+content_set_player (ClutterGstContent *self,
+                    ClutterGstPlayer  *player)
+{
+  ClutterGstContentPrivate *priv = self->priv;
+
+  if (priv->player == player)
+    return;
+
+  if (priv->player)
+    g_clear_object (&priv->sink);
+
+  if (player)
+    {
+      priv->player = g_object_ref_sink (player);
+      content_set_sink (self, clutter_gst_player_get_video_sink (player), TRUE);
+      /* g_signal_connect (priv->player, "new-frame", */
+      /*                   G_CALLBACK (_new_frame_from_pipeline), self); */
+      /* g_signal_connect (priv->player, "notify::pixel-aspect-ratio", */
+      /*                   G_CALLBACK (_pixel_aspect_ratio_changed), self); */
+    }
+  else
+    content_set_sink (self, NULL, TRUE);
+
+  g_object_notify (G_OBJECT (self), "player");
+}
+
 static void
 content_set_sink (ClutterGstContent *self,
-                  CoglGstVideoSink  *sink)
+                  CoglGstVideoSink  *sink,
+                  gboolean           set_from_player)
 {
   ClutterGstContentPrivate *priv = self->priv;
 
   if (priv->sink == sink)
     return;
 
+  if (!set_from_player)
+    content_set_player (self, NULL);
+
   if (priv->sink)
     {
       g_signal_handlers_disconnect_by_func (priv->sink,
@@ -217,7 +255,7 @@ clutter_gst_content_paint_content (ClutterContent   *content,
 }
 
 static void
-clutter_content_iface_init (ClutterContentIface *iface)
+content_iface_init (ClutterContentIface *iface)
 {
   iface->get_preferred_size = clutter_gst_content_get_preferred_size;
   iface->paint_content = clutter_gst_content_paint_content;
@@ -234,7 +272,12 @@ clutter_gst_content_set_property (GObject      *object,
   switch (prop_id)
     {
     case PROP_VIDEO_SINK:
-      content_set_sink (self, g_value_get_object (value));
+      content_set_sink (self, g_value_get_object (value), FALSE);
+      break;
+
+    case PROP_PLAYER:
+      content_set_player (self,
+                          CLUTTER_GST_PLAYER (g_value_get_object (value)));
       break;
 
     default:
@@ -257,6 +300,10 @@ clutter_gst_content_get_property (GObject    *object,
       g_value_set_object (value, priv->sink);
       break;
 
+    case PROP_PLAYER:
+      g_value_set_object (value, priv->player);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -297,10 +344,17 @@ clutter_gst_content_class_init (ClutterGstContentClass *klass)
 
   g_type_class_add_private (klass, sizeof (ClutterGstContentPrivate));
 
+  props[PROP_PLAYER] =
+    g_param_spec_object ("player",
+                         "ClutterGst Player",
+                         "ClutterGst Player",
+                         G_TYPE_OBJECT,
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+
   props[PROP_VIDEO_SINK] =
     g_param_spec_object ("video-sink",
-                         "video-sink",
-                         "video-sink",
+                         "Cogl Video Sink",
+                         "Cogl Video Sink",
                          COGL_GST_TYPE_VIDEO_SINK,
                          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
   g_object_class_install_properties (gobject_class, PROP_LAST, props);
@@ -357,6 +411,8 @@ clutter_gst_content_new (void)
  * clutter_gst_content_new_with_sink:
  *
  * Returns: (transfer full): a new #ClutterGstContent instance
+ *
+ * Since: 3.0
  */
 ClutterContent *
 clutter_gst_content_new_with_sink (CoglGstVideoSink *sink)
@@ -366,11 +422,44 @@ clutter_gst_content_new_with_sink (CoglGstVideoSink *sink)
                        NULL);
 }
 
+/**
+ * clutter_gst_content_get_frame:
+ * @self: A #ClutterGstContent
+ *
+ * Returns: (transfer none): The #ClutterGstFrame currently attached to @self.
+ *
+ * Since: 3.0
+ */
+ClutterGstFrame *
+clutter_gst_content_get_frame (ClutterGstContent *self)
+{
+  g_return_val_if_fail (CLUTTER_GST_IS_CONTENT (self), NULL);
+
+  return self->priv->current_frame;
+}
+
+/**
+ * clutter_gst_content_get_sink:
+ * @self: A #ClutterGstContent
+ *
+ * Returns: (transfer none): The #CoglGstVideoSink currently attached to @self.
+ *
+ * Since: 3.0
+ */
+CoglGstVideoSink *
+clutter_gst_content_get_sink (ClutterGstContent *self)
+{
+  g_return_val_if_fail (CLUTTER_GST_IS_CONTENT (self), NULL);
+
+  return self->priv->sink;
+}
 
 /**
  * clutter_gst_content_set_sink:
  * @self: A #ClutterGstContent
  * @sink: A #CoglGstVideoSink or %NULL
+ *
+ * Since: 3.0
  */
 void
 clutter_gst_content_set_sink (ClutterGstContent *self,
@@ -379,19 +468,38 @@ clutter_gst_content_set_sink (ClutterGstContent *self,
   g_return_if_fail (CLUTTER_GST_IS_CONTENT (self));
   g_return_if_fail (sink == NULL || COGL_GST_IS_VIDEO_SINK (sink));
 
-  content_set_sink (self, sink);
+  content_set_sink (self, sink, FALSE);
 }
 
 /**
- * clutter_gst_content_get_sink:
+ * clutter_gst_content_get_player:
  * @self: A #ClutterGstContent
  *
- * Returns: (transfer none):
+ * Returns: (transfer none): The #ClutterGstPlayer currently attached to @self.
+ *
+ * Since: 3.0
  */
-CoglGstVideoSink *
-clutter_gst_content_get_sink (ClutterGstContent *self)
+ClutterGstPlayer *
+clutter_gst_content_get_player (ClutterGstContent *self)
 {
   g_return_val_if_fail (CLUTTER_GST_IS_CONTENT (self), NULL);
 
-  return self->priv->sink;
+  return self->priv->player;
+}
+
+/**
+ * clutter_gst_content_set_player:
+ * @self: A #ClutterGstContent
+ * @player: A #ClutterGstPlayer or %NULL
+ *
+ * Since: 3.0
+ */
+void
+clutter_gst_content_set_player (ClutterGstContent *self,
+                                ClutterGstPlayer  *player)
+{
+  g_return_if_fail (CLUTTER_GST_IS_CONTENT (self));
+  g_return_if_fail (player == NULL || CLUTTER_GST_IS_PLAYER (player));
+
+  content_set_player (self, player);
 }
diff --git a/clutter-gst/clutter-gst-content.h b/clutter-gst/clutter-gst-content.h
index 15d1337..c362782 100644
--- a/clutter-gst/clutter-gst-content.h
+++ b/clutter-gst/clutter-gst-content.h
@@ -28,6 +28,7 @@
 
 #include <cogl-gst/cogl-gst.h>
 #include <clutter/clutter.h>
+#include <clutter-gst/clutter-gst-player.h>
 
 G_BEGIN_DECLS
 
@@ -56,7 +57,7 @@ typedef struct _ClutterGstContentClass       ClutterGstContentClass;
 struct _ClutterGstContent
 {
   /*< private >*/
-  GObject parent_instance;
+  GObject parent;
 
   ClutterGstContentPrivate *priv;
 };
@@ -77,15 +78,18 @@ struct _ClutterGstContentClass
 
 GType                     clutter_gst_content_get_type      (void) G_GNUC_CONST;
 
-ClutterContent *          clutter_gst_content_new           (void);
-
-ClutterContent *          clutter_gst_content_new_with_sink (CoglGstVideoSink *sink);
+ClutterGstFrame *         clutter_gst_content_get_frame     (ClutterGstContent *self);
 
 void                      clutter_gst_content_set_sink      (ClutterGstContent *self,
                                                              CoglGstVideoSink  *sink);
 
 CoglGstVideoSink *        clutter_gst_content_get_sink      (ClutterGstContent *self);
 
+ClutterGstPlayer *        clutter_gst_content_get_player    (ClutterGstContent *self);
+
+void                      clutter_gst_content_set_player    (ClutterGstContent *self,
+                                                             ClutterGstPlayer  *player);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_GST_CONTENT_H__ */
diff --git a/clutter-gst/clutter-gst-crop.c b/clutter-gst/clutter-gst-crop.c
index c608cdb..da5f110 100644
--- a/clutter-gst/clutter-gst-crop.c
+++ b/clutter-gst/clutter-gst-crop.c
@@ -29,7 +29,13 @@
 #include "clutter-gst-crop.h"
 #include "clutter-gst-private.h"
 
-G_DEFINE_TYPE (ClutterGstCrop, clutter_gst_crop, CLUTTER_GST_TYPE_ACTOR)
+static void content_iface_init (ClutterContentIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (ClutterGstCrop,
+                         clutter_gst_crop,
+                         CLUTTER_GST_TYPE_CONTENT,
+                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
+                                                content_iface_init))
 
 #define CROP_PRIVATE(o) \
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), CLUTTER_GST_TYPE_CROP, ClutterGstCropPrivate))
@@ -55,38 +61,63 @@ enum
 
 /**/
 
+static gboolean
+clutter_gst_crop_get_preferred_size (ClutterContent *content,
+                                     gfloat         *width,
+                                     gfloat         *height)
+{
+  ClutterGstFrame *frame =
+    clutter_gst_content_get_frame (CLUTTER_GST_CONTENT (content));
+
+  if (!frame)
+    return FALSE;
+
+  if (width)
+    *width = frame->resolution.width;
+  if (height)
+    *height = frame->resolution.height;
+
+  return TRUE;
+}
+
 static void
-clutter_gst_crop_paint_frame (ClutterGstActor *self,
-                              ClutterGstFrame *frame)
+clutter_gst_crop_paint_content (ClutterContent   *content,
+                                ClutterActor     *actor,
+                                ClutterPaintNode *root)
 {
-  ClutterGstCropPrivate *priv = CLUTTER_GST_CROP (self)->priv;
-  guint8 paint_opacity;
-  ClutterActorBox box;
+  ClutterGstCrop *self = CLUTTER_GST_CROP (content);
+  ClutterGstCropPrivate *priv = self->priv;
+  ClutterGstFrame *frame =
+    clutter_gst_content_get_frame (CLUTTER_GST_CONTENT (content));
+  guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
+  ClutterActorBox content_box;
   gfloat box_width, box_height;
+  ClutterColor color;
+  ClutterPaintNode *node;
 
-  clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &box);
-  box_width = clutter_actor_box_get_width (&box);
-  box_height = clutter_actor_box_get_height (&box);
+  clutter_actor_get_content_box (actor, &content_box);
 
-  paint_opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self));
-  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);
-  cogl_set_source (frame->pipeline);
+  if (!frame)
+    {
+      /* No frame to paint, just paint the background color of the
+         actor. */
+      if (priv->paint_borders)
+        {
+          clutter_actor_get_background_color (actor, &color);
+          color.alpha = paint_opacity;
+
+          clutter_paint_node_add_rectangle_custom (node,
+                                                   content_box.x1, content_box.y1,
+                                                   content_box.x2, content_box.y2);
+          clutter_paint_node_add_child (root, node);
+          clutter_paint_node_unref (node);
+        }
+
+      return;
+    }
 
-  cogl_rectangle_with_texture_coords (priv->output_region.x1 * box_width,
-                                      priv->output_region.y1 * box_height,
-                                      priv->output_region.x2 * box_width,
-                                      priv->output_region.y2 * box_height,
-                                      priv->input_region.x1,
-                                      priv->input_region.y1,
-                                      priv->input_region.x2,
-                                      priv->input_region.y2);
+  box_width = clutter_actor_box_get_width (&content_box);
+  box_height = clutter_actor_box_get_height (&content_box);
 
   if (priv->paint_borders &&
       (priv->output_region.x1 > 0 ||
@@ -94,32 +125,77 @@ clutter_gst_crop_paint_frame (ClutterGstActor *self,
        priv->output_region.y1 > 0 ||
        priv->output_region.y2 < 1))
     {
-      ClutterColor bg_color;
+      clutter_actor_get_background_color (actor, &color);
+      color.alpha = paint_opacity;
 
-      clutter_actor_get_background_color (CLUTTER_ACTOR (self), &bg_color);
-
-      cogl_set_source_color4ub (bg_color.red,
-                                bg_color.green,
-                                bg_color.blue,
-                                paint_opacity);
+      node = clutter_color_node_new (&color);
+      clutter_paint_node_set_name (node, "CropVideoBorders");
 
       if (priv->output_region.x1 > 0)
-        cogl_rectangle (0, 0, priv->output_region.x1 * box_width, 1);
+        clutter_paint_node_add_rectangle_custom (node,
+                                                 content_box.x1,
+                                                 content_box.y1,
+                                                 content_box.x1 + box_width * priv->output_region.x1,
+                                                 content_box.y2);
       if (priv->output_region.x2 < 1)
-        cogl_rectangle (priv->output_region.x2 * box_width, 0, 1, 1);
+        clutter_paint_node_add_rectangle_custom (node,
+                                                 content_box.x1 + box_width * priv->output_region.x2,
+                                                 content_box.y1,
+                                                 content_box.x2,
+                                                 content_box.y2);
       if (priv->output_region.y1 > 0)
-        cogl_rectangle (priv->output_region.x1 * box_width,
-                        0,
-                        priv->output_region.x2 * box_width,
-                        priv->output_region.y1 * box_height);
+        clutter_paint_node_add_rectangle_custom (node,
+                                                 content_box.x1 + box_width * priv->output_region.x1,
+                                                 content_box.y1,
+                                                 content_box.x1 + box_width * priv->output_region.x2,
+                                                 content_box.y1 + box_height * priv->output_region.y1);
       if (priv->output_region.y2 < 1)
-        cogl_rectangle (priv->output_region.x1 * box_width,
-                        priv->output_region.y2 * box_height,
-                        priv->output_region.x2 * box_width,
-                        0);
+        clutter_paint_node_add_rectangle_custom (node,
+                                                 content_box.x1 + box_width * priv->output_region.x1,
+                                                 content_box.y1 + box_height * priv->output_region.y2,
+                                                 content_box.x1 + box_width * priv->output_region.x2,
+                                                 content_box.y2);
+
+      clutter_paint_node_add_child (root, node);
+      clutter_paint_node_unref (node);
     }
+
+
+  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);
 }
 
+static void
+content_iface_init (ClutterContentIface *iface)
+{
+  iface->get_preferred_size = clutter_gst_crop_get_preferred_size;
+  iface->paint_content = clutter_gst_crop_paint_content;
+}
+
+/**/
+
 static gboolean
 _validate_box (ClutterGstBox *box)
 {
@@ -178,7 +254,11 @@ clutter_gst_crop_set_property (GObject      *object,
   switch (property_id)
     {
     case PROP_PAINT_BORDERS:
-      priv->paint_borders = g_value_get_boolean (value);
+      if (priv->paint_borders != g_value_get_boolean (value))
+        {
+          priv->paint_borders = g_value_get_boolean (value);
+          clutter_content_invalidate (CLUTTER_CONTENT (object));
+        }
       break;
     case PROP_CULL_BACKFACE:
       priv->cull_backface = g_value_get_boolean (value);
@@ -187,7 +267,7 @@ clutter_gst_crop_set_property (GObject      *object,
       box = (ClutterGstBox *) g_value_get_boxed (value);
       if (_validate_box (box)) {
         priv->input_region = *box;
-        clutter_actor_queue_redraw (CLUTTER_ACTOR (object));
+        clutter_content_invalidate (CLUTTER_CONTENT (object));
       } else
         g_warning ("Input region must be given in [0, 1] values.");
       break;
@@ -195,7 +275,7 @@ clutter_gst_crop_set_property (GObject      *object,
       box = (ClutterGstBox *) g_value_get_boxed (value);
       if (_validate_box (box)) {
         priv->output_region = *box;
-        clutter_actor_queue_redraw (CLUTTER_ACTOR (object));
+        clutter_content_invalidate (CLUTTER_CONTENT (object));
       } else
         g_warning ("Output region must be given in [0, 1] values.");
       break;
@@ -230,8 +310,6 @@ clutter_gst_crop_class_init (ClutterGstCropClass *klass)
   object_class->dispose = clutter_gst_crop_dispose;
   object_class->finalize = clutter_gst_crop_finalize;
 
-  gst_actor_class->paint_frame = clutter_gst_crop_paint_frame;
-
   /**
    * ClutterGstCrop:paint-borders:
    *
@@ -304,6 +382,11 @@ clutter_gst_crop_init (ClutterGstCrop *self)
   priv->output_region = priv->input_region;
 }
 
+/**
+ * clutter_gst_crop_new:
+ *
+ * Returns: (transfer full): a new #ClutterGstCrop instance
+ */
 ClutterActor *
 clutter_gst_crop_new (void)
 {
diff --git a/clutter-gst/clutter-gst-crop.h b/clutter-gst/clutter-gst-crop.h
index 41a5fdf..0ec830d 100644
--- a/clutter-gst/clutter-gst-crop.h
+++ b/clutter-gst/clutter-gst-crop.h
@@ -35,7 +35,7 @@
 
 #include <glib-object.h>
 
-#include <clutter-gst/clutter-gst-actor.h>
+#include <clutter-gst/clutter-gst-content.h>
 
 G_BEGIN_DECLS
 
@@ -67,14 +67,14 @@ typedef struct _ClutterGstCropPrivate ClutterGstCropPrivate;
 
 struct _ClutterGstCrop
 {
-  ClutterGstActor parent;
+  ClutterGstContent parent;
 
   ClutterGstCropPrivate *priv;
 };
 
 struct _ClutterGstCropClass
 {
-  ClutterGstActorClass parent_class;
+  ClutterGstContentClass parent_class;
 };
 
 GType clutter_gst_crop_get_type (void) G_GNUC_CONST;
diff --git a/clutter-gst/clutter-gst-playback.c b/clutter-gst/clutter-gst-playback.c
index a368de1..7939fbb 100644
--- a/clutter-gst/clutter-gst-playback.c
+++ b/clutter-gst/clutter-gst-playback.c
@@ -116,6 +116,7 @@ struct _ClutterGstPlaybackPrivate
 {
   GstElement *pipeline;
   GstBus *bus;
+  CoglGstVideoSink *video_sink;
 
   ClutterGstFrame *current_frame;
 
@@ -1378,6 +1379,14 @@ clutter_gst_playback_get_pipeline (ClutterGstPlayer *self)
   return priv->pipeline;
 }
 
+static CoglGstVideoSink *
+clutter_gst_playback_get_video_sink (ClutterGstPlayer *self)
+{
+  ClutterGstPlaybackPrivate *priv = CLUTTER_GST_PLAYBACK (self)->priv;
+
+  return priv->video_sink;
+}
+
 static gboolean
 clutter_gst_playback_get_idle (ClutterGstPlayer *self)
 {
@@ -1417,6 +1426,8 @@ player_iface_init (ClutterGstPlayerIface *iface)
 {
   iface->get_frame = clutter_gst_playback_get_frame;
   iface->get_pipeline = clutter_gst_playback_get_pipeline;
+  iface->get_video_sink = clutter_gst_playback_get_video_sink;
+
   iface->get_idle = clutter_gst_playback_get_idle;
 
   iface->get_audio_volume = clutter_gst_playback_get_audio_volume;
@@ -1911,8 +1922,8 @@ _pixel_aspect_ratio_changed (CoglGstVideoSink   *sink,
 static GstElement *
 get_pipeline (ClutterGstPlayback *self)
 {
+  ClutterGstPlaybackPrivate *priv = self->priv;
   GstElement *pipeline, *audio_sink;
-  CoglGstVideoSink *video_sink;
 
   pipeline = gst_element_factory_make ("playbin", "pipeline");
   if (!pipeline)
@@ -1937,18 +1948,18 @@ get_pipeline (ClutterGstPlayback *self)
        }
     }
 
-  video_sink = cogl_gst_video_sink_new (clutter_gst_get_cogl_context ());
+  priv->video_sink = cogl_gst_video_sink_new (clutter_gst_get_cogl_context ());
 
-  g_signal_connect (video_sink, "new-frame",
+  g_signal_connect (priv->video_sink, "new-frame",
                     G_CALLBACK (_new_frame_from_pipeline), self);
-  g_signal_connect (video_sink, "pipeline-ready",
+  g_signal_connect (priv->video_sink, "pipeline-ready",
                     G_CALLBACK (_ready_from_pipeline), self);
-  g_signal_connect (video_sink, "notify::pixel-aspect-ratio",
+  g_signal_connect (priv->video_sink, "notify::pixel-aspect-ratio",
                     G_CALLBACK (_pixel_aspect_ratio_changed), self);
 
   g_object_set (G_OBJECT (pipeline),
                 "audio-sink", audio_sink,
-                "video-sink", video_sink,
+                "video-sink", priv->video_sink,
                 "subtitle-font-desc", "Sans 16",
                 NULL);
 
diff --git a/clutter-gst/clutter-gst-player.c b/clutter-gst/clutter-gst-player.c
index 7fea14e..186ff9a 100644
--- a/clutter-gst/clutter-gst-player.c
+++ b/clutter-gst/clutter-gst-player.c
@@ -118,6 +118,7 @@ clutter_gst_player_default_init (ClutterGstPlayerIface *iface)
   /**
    * ClutterGstPlayer::new-frame:
    * @player: the #ClutterGstPlayer instance that received the signal
+   * @frame: the #ClutterGstFrame newly receive from the video sink
    *
    * The ::ready signal is emitted each time the gstreamer pipeline
    * becomes ready.
@@ -245,6 +246,29 @@ clutter_gst_player_get_pipeline (ClutterGstPlayer *self)
 }
 
 /**
+ * clutter_gst_player_get_video_sink:
+ * @self: a #ClutterGstPlayer
+ *
+ * Retrieves the #CoglGstVideoSink used by the @self.
+ *
+ * Return value: (transfer none): the #CoglGstVideoSink element used by the player
+ *
+ * Since: 3.0
+ */
+CoglGstVideoSink *
+clutter_gst_player_get_video_sink (ClutterGstPlayer *self)
+{
+  ClutterGstPlayerIface *iface;
+
+  g_return_val_if_fail (CLUTTER_GST_IS_PLAYER (self), NULL);
+
+  iface = CLUTTER_GST_PLAYER_GET_INTERFACE (self);
+
+  return iface->get_video_sink (self);
+
+}
+
+/**
  * clutter_gst_player_get_playing:
  * @self: A #ClutterGstPlayer object
  *
diff --git a/clutter-gst/clutter-gst-player.h b/clutter-gst/clutter-gst-player.h
index ede3f64..5d0ea7f 100644
--- a/clutter-gst/clutter-gst-player.h
+++ b/clutter-gst/clutter-gst-player.h
@@ -39,8 +39,8 @@
 #define __CLUTTER_GST_PLAYER_H__
 
 #include <glib-object.h>
-#include <cogl/cogl.h>
 #include <gst/gst.h>
+#include <cogl-gst/cogl-gst.h>
 
 #include <clutter-gst/clutter-gst-types.h>
 
@@ -93,6 +93,7 @@ struct _ClutterGstPlayerIface
   /*< public >*/
   ClutterGstFrame * (* get_frame)        (ClutterGstPlayer *self);
   GstElement *      (* get_pipeline)     (ClutterGstPlayer *self);
+  CoglGstVideoSink *(* get_video_sink)   (ClutterGstPlayer *self);
 
   gboolean          (* get_idle)         (ClutterGstPlayer *self);
 
@@ -136,6 +137,8 @@ ClutterGstFrame *         clutter_gst_player_get_frame        (ClutterGstPlayer
 
 GstElement *              clutter_gst_player_get_pipeline     (ClutterGstPlayer        *self);
 
+CoglGstVideoSink *        clutter_gst_player_get_video_sink   (ClutterGstPlayer        *self);
+
 gboolean                  clutter_gst_player_get_idle         (ClutterGstPlayer        *self);
 
 gboolean                  clutter_gst_player_get_playing      (ClutterGstPlayer        *self);
diff --git a/clutter-gst/clutter-gst-private.h b/clutter-gst/clutter-gst-private.h
index 9fa9939..6483329 100644
--- a/clutter-gst/clutter-gst-private.h
+++ b/clutter-gst/clutter-gst-private.h
@@ -47,6 +47,19 @@ G_BEGIN_DECLS
 #define CLUTTER_GST_PARAM_READWRITE     \
   (G_PARAM_READABLE | G_PARAM_WRITABLE | CLUTTER_GST_PARAM_STATIC)
 
+#define clutter_paint_node_add_rectangle_custom(node,x1,y1,x2,y2) \
+  do {                                                            \
+    ClutterActorBox _box = { x1, y1, x2, y2 };                    \
+    clutter_paint_node_add_rectangle (node, &_box);               \
+  } while (0)
+
+#define clutter_paint_node_add_texture_rectangle_custom(node,x1,y1,x2,y2,tx1,ty1,tx2,ty2) \
+  do {                                                                  \
+    ClutterActorBox _box = { x1, y1, x2, y2 };                          \
+    clutter_paint_node_add_texture_rectangle (node, &_box,              \
+                                              tx1, ty1, tx2, ty2);      \
+  } while (0)
+
 gboolean
 _internal_plugin_init (GstPlugin *plugin);
 
@@ -64,7 +77,6 @@ void clutter_gst_player_update_frame (ClutterGstPlayer *player,
 void clutter_gst_frame_update_pixel_aspect_ratio (ClutterGstFrame  *frame,
                                                   CoglGstVideoSink *sink);
 
-
 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 00b8a1b..ebab80e 100644
--- a/clutter-gst/clutter-gst-types.c
+++ b/clutter-gst/clutter-gst-types.c
@@ -98,3 +98,39 @@ G_DEFINE_BOXED_TYPE (ClutterGstBox,
                      clutter_gst_box,
                      clutter_gst_box_copy,
                      clutter_gst_box_free);
+
+/**
+ * clutter_gst_box_get_width:
+ * @box: a #ClutterGstBox
+ *
+ * Retrieves the width of the @box
+ *
+ * Return value: the width of the box
+ *
+ * Since: 3.0
+ */
+gfloat
+clutter_gst_box_get_width (const ClutterGstBox *box)
+{
+  g_return_val_if_fail (box != NULL, 0.);
+
+  return box->x2 - box->x1;
+}
+
+/**
+ * clutter_gst_box_get_height:
+ * @box: a #ClutterGstBox
+ *
+ * Retrieves the height of the @box
+ *
+ * Return value: the height of the box
+ *
+ * Since: 3.0
+ */
+gfloat
+clutter_gst_box_get_height (const ClutterGstBox *box)
+{
+  g_return_val_if_fail (box != NULL, 0.);
+
+  return box->y2 - box->y1;
+}
diff --git a/clutter-gst/clutter-gst-types.h b/clutter-gst/clutter-gst-types.h
index 8a38106..0aeb94d 100644
--- a/clutter-gst/clutter-gst-types.h
+++ b/clutter-gst/clutter-gst-types.h
@@ -124,4 +124,7 @@ struct _ClutterGstBox
 GType clutter_gst_frame_get_type (void) G_GNUC_CONST;
 GType clutter_gst_box_get_type   (void) G_GNUC_CONST;
 
+gfloat clutter_gst_box_get_width     (const ClutterGstBox *box);
+gfloat clutter_gst_box_get_height    (const ClutterGstBox *box);
+
 #endif /* __CLUTTER_GST_TYPES_H__ */
diff --git a/examples/camera-player.c b/examples/camera-player.c
index e601d50..e5e25a1 100644
--- a/examples/camera-player.c
+++ b/examples/camera-player.c
@@ -329,9 +329,8 @@ size_change (ClutterGstPlayer *player,
   /* base_width and base_height are the actual dimensions of the buffers before
    * taking the pixel aspect ratio into account. We need to get the actual
    * size of the texture to display */
-  clutter_actor_get_preferred_size (app->camera_actor,
-                                    NULL, NULL,
-                                    &frame_width, &frame_height);
+  clutter_content_get_preferred_size (clutter_actor_get_content (app->camera_actor),
+                                      &frame_width, &frame_height);
 
   new_height = (frame_height * stage_width) / frame_width;
   if (new_height <= stage_height)
@@ -386,7 +385,6 @@ main (int argc, char *argv[])
 
   app = g_new0(CameraApp, 1);
   app->stage = stage;
-  app->camera_actor = clutter_gst_aspectratio_new ();
 
   app->camera_player = clutter_gst_camera_new ();
   if (app->camera_player == NULL)
@@ -395,6 +393,13 @@ main (int argc, char *argv[])
       return EXIT_FAILURE;
     }
 
+  app->camera_actor = g_object_new (CLUTTER_TYPE_ACTOR,
+                                    "content", g_object_new (CLUTTER_GST_TYPE_ASPECTRATIO,
+                                                             "player", app->camera_player,
+                                                             NULL),
+                                    NULL);
+
+
   app->camera_devices = clutter_gst_camera_get_camera_devices (app->camera_player);
   if (!app->camera_devices)
     {
@@ -429,10 +434,6 @@ main (int argc, char *argv[])
                           "size-change",
                           G_CALLBACK (size_change), app);
 
-
-  clutter_gst_actor_set_player (CLUTTER_GST_ACTOR (app->camera_actor),
-                                CLUTTER_GST_PLAYER (app->camera_player));
-
   /* Add control UI to stage */
   clutter_actor_add_child (stage, app->camera_actor);
 
diff --git a/examples/pieces.js b/examples/pieces.js
index 5642752..34606c3 100644
--- a/examples/pieces.js
+++ b/examples/pieces.js
@@ -131,13 +131,16 @@ for (let i = 0; i < ROWS; i++) {
                                          y1: i / ROWS,
                                          y2: (i + 1) / ROWS,
                                        })
-        let actor = new ClutterGst.Crop({ width: BIT_WIDTH,
-                                          height: BIT_HEIGHT,
-                                          player: player,
-                                          x: BIT_WIDTH * j,
-                                          y: BIT_HEIGHT * i,
-                                          input_region: input,
-                                        });
+        let actor = new Clutter.Actor({
+            width: BIT_WIDTH,
+            height: BIT_HEIGHT,
+            x: BIT_WIDTH * j,
+            y: BIT_HEIGHT * i,
+            content: new ClutterGst.Crop({
+                player: player,
+                input_region: input,
+            }),
+        });
         stage.add_actor(actor);
 
         pieces.array[i][j] = actor;
diff --git a/examples/video-flip.js b/examples/video-flip.js
index f320cef..4776750 100644
--- a/examples/video-flip.js
+++ b/examples/video-flip.js
@@ -45,12 +45,12 @@ stage.set_background_color(new Clutter.Color({ red: 0,
 stage.connect('destroy',
               Lang.bind(this, function() { Clutter.main_quit(); }));
 
-player1 = new ClutterGst.Playback();
+let player1 = new ClutterGst.Playback();
 player1.set_filename(ARGV[0]);
 player1.set_audio_volume(0);
 player1.set_progress(0.20);
 
-player2 = new ClutterGst.Playback();
+let player2 = new ClutterGst.Playback();
 player2.set_filename(ARGV[1]);
 player2.set_audio_volume(0);
 player2.set_progress(0.20);
@@ -125,30 +125,36 @@ for (let i = 0; i < ROWS; i++) {
                                          y2: (i + 1) / ROWS,
                                        })
         let actor =
-            new ClutterGst.Crop({ reactive: true,
-                                  cull_backface: true,
-                                  pivot_point: new Clutter.Point({ x: 0.5,
-                                                                   y: 0.5 }),
-                                  width: 200,
-                                  height: 200,
-                                  x: -200,
-                                  y: -200,
-                                  input_region: input,
-                                  player: player1,
-                                });
+            new Clutter.Actor({
+                reactive: true,
+                pivot_point: new Clutter.Point({ x: 0.5,
+                                                 y: 0.5 }),
+                width: 200,
+                height: 200,
+                x: -200,
+                y: -200,
+                content: new ClutterGst.Crop({
+                    cull_backface: true,
+                    input_region: input,
+                    player: player1,
+                }),
+            });
         actor._backActor =
-            new ClutterGst.Crop({ reactive: false,
-                                  cull_backface: true,
-                                  pivot_point: new Clutter.Point({ x: 0.5,
-                                                                   y: 0.5 }),
-                                  rotation_angle_y: 180,
-                                  width: 200,
-                                  height: 200,
-                                  x: -200,
-                                  y: -200,
-                                  input_region: input,
-                                  player: player2,
-                                });
+            new Clutter.Actor({
+                reactive: false,
+                pivot_point: new Clutter.Point({ x: 0.5,
+                                                 y: 0.5 }),
+                rotation_angle_y: 180,
+                width: 200,
+                height: 200,
+                x: -200,
+                y: -200,
+                content: new ClutterGst.Crop({
+                    cull_backface: true,
+                    input_region: input,
+                    player: player2,
+                }),
+            });
         stage.add_child(actor);
         stage.add_child(actor._backActor);
 
diff --git a/examples/video-flip2.js b/examples/video-flip2.js
index 25ae4b8..98966ec 100644
--- a/examples/video-flip2.js
+++ b/examples/video-flip2.js
@@ -119,27 +119,27 @@ Players.prototype = {
     updateActorsCurrent: function(actors, back) {
         for (let i in actors) {
             if (back)
-                actors[i]._backActor.player = this.getCurrentPlayer();
+                actors[i]._backActor.content.player = this.getCurrentPlayer();
             else
-                actors[i].player = this.getCurrentPlayer();
+                actors[i].content.player = this.getCurrentPlayer();
         }
     },
 
     updateActorsNext: function(actors, back) {
         for (let i in actors) {
             if (back)
-                actors[i]._backActor.player = this.getNextPlayer();
+                actors[i]._backActor.content.player = this.getNextPlayer();
             else
-                actors[i].player = this.getNextPlayer();
+                actors[i].content.player = this.getNextPlayer();
         }
     },
 
     updateActorsPrevious: function(actors, back) {
         for (let i in actors) {
             if (back)
-                actors[i]._backActor.player = this.getPreviousPlayer();
+                actors[i]._backActor.content.player = this.getPreviousPlayer();
             else
-                actors[i].player = this.getPreviousPlayer();
+                actors[i].content.player = this.getPreviousPlayer();
         }
     },
 
@@ -241,22 +241,26 @@ for (let i = 0; i < ROWS; i++) {
                                          y2: (i + 1) / ROWS,
                                        })
         let actor =
-            new ClutterGst.Crop({ cull_backface: true,
-                                  pivot_point: new Clutter.Point({ x: 0.5,
-                                                                   y: 0.5 }),
-                                  width: TILE_WIDTH,
-                                  height: TILE_HEIGHT,
-                                  input_region: input,
-                                });
+            new Clutter.Actor({
+                pivot_point: new Clutter.Point({ x: 0.5,
+                                                 y: 0.5 }),
+                width: TILE_WIDTH,
+                height: TILE_HEIGHT,
+                content: new ClutterGst.Crop({ cull_backface: true,
+                                               input_region: input,
+                                             }),
+            });
         actor._backActor =
-            new ClutterGst.Crop({ cull_backface: true,
-                                  pivot_point: new Clutter.Point({ x: 0.5,
-                                                                   y: 0.5 }),
-                                  rotation_angle_y: 180,
-                                  width: TILE_WIDTH,
-                                  height: TILE_HEIGHT,
-                                  input_region: input,
-                                });
+            new Clutter.Actor({
+                pivot_point: new Clutter.Point({ x: 0.5,
+                                                 y: 0.5 }),
+                rotation_angle_y: 180,
+                width: TILE_WIDTH,
+                height: TILE_HEIGHT,
+                content: new ClutterGst.Crop({ cull_backface: true,
+                                               input_region: input,
+                                             }),
+            });
         stage.add_child(actor);
         stage.add_child(actor._backActor);
 
diff --git a/examples/video-player.c b/examples/video-player.c
index e9435c1..b3e1317 100644
--- a/examples/video-player.c
+++ b/examples/video-player.c
@@ -469,11 +469,15 @@ main (int argc, char *argv[])
 
   app = g_new0(VideoApp, 1);
   app->stage = stage;
-  app->vactor = g_object_new (CLUTTER_GST_TYPE_ASPECTRATIO, NULL);
-  clutter_actor_set_size (app->vactor, clutter_actor_get_width (stage), clutter_actor_get_height (stage));
   app->player = clutter_gst_playback_new ();
 
-  clutter_gst_actor_set_player (CLUTTER_GST_ACTOR (app->vactor), CLUTTER_GST_PLAYER (app->player));
+  app->vactor = g_object_new (CLUTTER_TYPE_ACTOR,
+                              "width", clutter_actor_get_width (stage),
+                              "height", clutter_actor_get_height (stage),
+                              "content", g_object_new (CLUTTER_GST_TYPE_ASPECTRATIO,
+                                                       "player", app->player,
+                                                       NULL),
+                              NULL);
 
   if (app->vactor == NULL)
     g_error("failed to create vactor");
diff --git a/examples/video-wall.js b/examples/video-wall.js
index adb39a4..151f11c 100644
--- a/examples/video-wall.js
+++ b/examples/video-wall.js
@@ -45,7 +45,7 @@ stage.set_background_color(new Clutter.Color({ red: 0,
 stage.connect('destroy',
               Lang.bind(this, function() { Clutter.main_quit(); }));
 
-player = new ClutterGst.Playback();
+let player = new ClutterGst.Playback();
 player.set_filename(ARGV[0]);
 player.set_audio_volume(0);
 player.set_progress(0.20);
@@ -136,11 +136,13 @@ for (let i = 0; i < ROWS; i++) {
                                          y1: i / ROWS,
                                          y2: (i + 1) / ROWS,
                                        })
-        let subActor = new ClutterGst.Crop({ width: 200,
-                                             height: 200,
-                                             player: player,
-                                             input_region: input,
-                                           });
+        let subActor = new Clutter.Actor({
+            width: 200,
+            height: 200,
+            content: new ClutterGst.Crop({ player: player,
+                                           input_region: input,
+                                         }),
+        });
         let actor = new Clutter.Actor();
         actor.add_child(subActor);
 
diff --git a/tests/test-alpha.c b/tests/test-alpha.c
index 6faaac5..f15e0e8 100644
--- a/tests/test-alpha.c
+++ b/tests/test-alpha.c
@@ -32,6 +32,7 @@
 
 #include <glib/gprintf.h>
 #include <clutter-gst/clutter-gst.h>
+#include <cogl-gst/cogl-gst.h>
 
 static gint   opt_framerate = 30;
 static gchar *opt_fourcc    = "I420";
@@ -65,44 +66,6 @@ parse_fourcc (const gchar *fourcc)
   return GST_STR_FOURCC (fourcc);
 }
 
-static void
-size_change (ClutterGstPlayer *player,
-             gint              width,
-             gint              height,
-             ClutterActor     *actor)
-{
-  ClutterActor *stage;
-  gfloat new_x, new_y, new_width, new_height;
-  gfloat stage_width, stage_height;
-
-  stage = clutter_actor_get_stage (actor);
-  if (stage == NULL)
-    return;
-
-  clutter_actor_get_size (stage, &stage_width, &stage_height);
-
-  new_height = (height * stage_width) / width;
-  if (new_height <= stage_height)
-    {
-      new_width = stage_width;
-
-      new_x = 0;
-      new_y = (stage_height - new_height) / 2;
-    }
-  else
-    {
-      new_width  = (width * stage_height) / height;
-      new_height = stage_height;
-
-      new_x = (stage_width - new_width) / 2;
-      new_y = 0;
-    }
-
-  g_message ("resize %fx%f @ %fx%f", new_width, new_height, new_x, new_y);
-  clutter_actor_set_position (actor, new_x, new_y);
-  clutter_actor_set_size (actor, new_width, new_height);
-}
-
 int
 main (int argc, char *argv[])
 {
@@ -116,7 +79,6 @@ main (int argc, char *argv[])
   ClutterActor          *actor;
   ClutterActor          *rectangle;
   ClutterTransition     *animation;
-  ClutterGstPlayer      *player;
 
   GstPipeline           *pipeline;
   GstElement            *src;
@@ -152,9 +114,6 @@ main (int argc, char *argv[])
                           rectangle_geom.size.width,
                           rectangle_geom.size.height);
 
-  actor = clutter_gst_actor_new ();
-  clutter_actor_set_opacity (actor, 0);
-
   /* Set up pipeline */
   pipeline = GST_PIPELINE(gst_pipeline_new (NULL));
 
@@ -163,6 +122,16 @@ main (int argc, char *argv[])
   capsfilter = gst_element_factory_make ("capsfilter", NULL);
   sink = clutter_gst_create_video_sink ();
 
+  /* Video actor */
+  actor = g_object_new (CLUTTER_TYPE_ACTOR,
+                        "content", g_object_new (CLUTTER_GST_TYPE_CONTENT,
+                                                 "video-sink", sink,
+                                                 NULL),
+                        "width", clutter_actor_get_width (stage),
+                        "height", clutter_actor_get_height (stage),
+                        NULL);
+  clutter_actor_set_opacity (actor, 0);
+
   /* make videotestsrc spit the format we want */
   if (g_strcmp0 (opt_fourcc, "RGB ") == 0)
     {
@@ -192,20 +161,10 @@ main (int argc, char *argv[])
     g_critical("Could not link elements");
   gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_PLAYING);
 
-  player = CLUTTER_GST_PLAYER (g_object_new (CLUTTER_GST_TYPE_PIPELINE,
-                                             "video-sink", sink, NULL));
-
-  g_signal_connect (player,
-                    "size-change",
-                    G_CALLBACK (size_change), actor);
-
   clutter_actor_add_child (stage, rectangle);
   clutter_actor_add_child (stage, actor);
   clutter_actor_show (stage);
 
-  clutter_gst_actor_set_player (CLUTTER_GST_ACTOR (actor), player);
-
-
   clutter_actor_save_easing_state (actor);
   clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR);
   clutter_actor_set_easing_duration (actor, 6000);
diff --git a/tests/test-rgb-upload.c b/tests/test-rgb-upload.c
index eae4d5d..aa8f202 100644
--- a/tests/test-rgb-upload.c
+++ b/tests/test-rgb-upload.c
@@ -63,43 +63,6 @@ static GOptionEntry options[] =
   { NULL }
 };
 
-void
-size_change (ClutterGstPlayer *player,
-             gint              width,
-             gint              height,
-             ClutterActor     *actor)
-{
-  ClutterActor *stage;
-  gfloat new_x, new_y, new_width, new_height;
-  gfloat stage_width, stage_height;
-
-  stage = clutter_actor_get_stage (actor);
-  if (stage == NULL)
-    return;
-
-  clutter_actor_get_size (stage, &stage_width, &stage_height);
-
-  new_height = (height * stage_width) / width;
-  if (new_height <= stage_height)
-    {
-      new_width = stage_width;
-
-      new_x = 0;
-      new_y = (stage_height - new_height) / 2;
-    }
-  else
-    {
-      new_width  = (width * stage_height) / height;
-      new_height = stage_height;
-
-      new_x = (stage_height - new_width) / 2;
-      new_y = 0;
-    }
-
-  clutter_actor_set_position (actor, new_x, new_y);
-  clutter_actor_set_size (actor, new_width, new_height);
-}
-
 int
 main (int argc, char *argv[])
 {
@@ -132,7 +95,6 @@ main (int argc, char *argv[])
   stage = clutter_stage_new ();
   clutter_actor_set_size (CLUTTER_ACTOR (stage), 320.0f, 240.0f);
 
-  actor = clutter_gst_actor_new ();
 
   /* Set up pipeline */
   pipeline = GST_PIPELINE(gst_pipeline_new (NULL));
@@ -141,6 +103,16 @@ main (int argc, char *argv[])
   capsfilter = gst_element_factory_make ("capsfilter", NULL);
   sink = clutter_gst_create_video_sink ();
 
+  /* Video actor */
+  actor = g_object_new (CLUTTER_TYPE_ACTOR,
+                        "content", g_object_new (CLUTTER_GST_TYPE_CONTENT,
+                                                 "video-sink", sink,
+                                                 NULL),
+                        "width", clutter_actor_get_width (stage),
+                        "height", clutter_actor_get_height (stage),
+                        NULL);
+
+
   format = gst_video_format_from_masks(opt_depth, opt_bpp, G_BIG_ENDIAN,
                                       0xff0000,
                                       0x00ff00,
@@ -160,14 +132,6 @@ main (int argc, char *argv[])
     g_critical("Could not link elements");
   gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_PLAYING);
 
-
-  player = CLUTTER_GST_PLAYER (g_object_new (CLUTTER_GST_TYPE_PIPELINE,
-                                             "video-sink", sink, NULL));
-  clutter_gst_actor_set_player (CLUTTER_GST_ACTOR (actor), player);
-  g_signal_connect (player,
-                    "size-change",
-                    G_CALLBACK (size_change), actor);
-
   clutter_actor_add_child (stage, actor);
   clutter_actor_show (stage);
 
diff --git a/tests/test-start-stop.c b/tests/test-start-stop.c
index a9efe4d..9bc1ea9 100644
--- a/tests/test-start-stop.c
+++ b/tests/test-start-stop.c
@@ -33,45 +33,6 @@
 char *video_files[] = {NULL, NULL};
 
 void
-size_change (ClutterGstPlayer *player,
-             gint              width,
-             gint              height,
-             ClutterActor     *actor)
-{
-  ClutterActor *stage = clutter_actor_get_stage (actor);
-  gfloat new_x, new_y, new_width, new_height;
-  gfloat stage_width, stage_height;
-
-  g_message ("size change %ix%i", width, height);
-
-  clutter_actor_get_size (stage, &stage_width, &stage_height);
-
-  /* new_height = (height * stage_width) / width; */
-  /* if (new_height <= stage_height) */
-  /*   { */
-  /*     new_width = stage_width; */
-
-  /*     new_x = 0; */
-  /*     new_y = (stage_height - new_height) / 2; */
-  /*   } */
-  /* else */
-  /*   { */
-  /*     new_width  = (width * stage_height) / height; */
-  /*     new_height = stage_height; */
-
-  /*     new_x = (stage_width - new_width) / 2; */
-  /*     new_y = 0; */
-  /*   } */
-
-  /* clutter_actor_set_position (actor, new_x, new_y); */
-  clutter_actor_set_size (actor, stage_width, stage_height);
-
-  g_message (" new pos/size -> x,y=%.2fx%.2f w,h=%.2fx%.2f",
-             new_x, new_y, stage_width, stage_height);
-
-}
-
-void
 on_error (ClutterGstPlayer *player)
 {
   g_print ("error\n");
@@ -151,17 +112,18 @@ main (int argc, char *argv[])
   stage = clutter_stage_new ();
   clutter_actor_set_background_color (stage, &stage_color);
 
-  video = clutter_gst_aspectratio_new ();
-
   player = clutter_gst_playback_new ();
-  clutter_gst_actor_set_player (CLUTTER_GST_ACTOR (video), CLUTTER_GST_PLAYER (player));
+
+  video = g_object_new (CLUTTER_TYPE_ACTOR,
+                        "content", g_object_new (CLUTTER_GST_TYPE_ASPECTRATIO,
+                                                 "player", player,
+                                                 NULL),
+                        "width", clutter_actor_get_width (stage),
+                        "height", clutter_actor_get_height (stage),
+                        NULL);
   clutter_actor_add_child (stage, video);
 
   g_signal_connect (player,
-                    "size-change",
-                    G_CALLBACK(size_change),
-                    video);
-  g_signal_connect (player,
                     "error",
                     G_CALLBACK(on_error),
                     video);
diff --git a/tests/test-video-actor-new-unref-loop.c b/tests/test-video-actor-new-unref-loop.c
index fd98a6a..15714e6 100644
--- a/tests/test-video-actor-new-unref-loop.c
+++ b/tests/test-video-actor-new-unref-loop.c
@@ -35,7 +35,7 @@
 int
 main (int argc, char *argv[])
 {
-  ClutterActor *vactor;
+  ClutterGstPlayer *player;
   int i;
 
   clutter_gst_init (&argc, &argv);
@@ -43,9 +43,9 @@ main (int argc, char *argv[])
   for (i = 0; ; i++)
   {
     g_debug("VideoActor #%d", i);
-    vactor = clutter_gst_actor_new ();
-    g_object_ref_sink (vactor);
-    g_object_unref (vactor);
+    player = CLUTTER_GST_PLAYER (clutter_gst_playback_new ());
+    g_object_ref_sink (player);
+    g_object_unref (player);
   }
 
   return EXIT_SUCCESS;
diff --git a/tests/test-yuv-upload.c b/tests/test-yuv-upload.c
index 1a451bf..347bcd0 100644
--- a/tests/test-yuv-upload.c
+++ b/tests/test-yuv-upload.c
@@ -52,43 +52,6 @@ static GOptionEntry options[] =
   { NULL }
 };
 
-void
-size_change (ClutterGstPlayer *player,
-             gint              width,
-             gint              height,
-             ClutterActor     *actor)
-{
-  ClutterActor *stage;
-  gfloat new_x, new_y, new_width, new_height;
-  gfloat stage_width, stage_height;
-
-  stage = clutter_actor_get_stage (actor);
-  if (stage == NULL)
-    return;
-
-  clutter_actor_get_size (stage, &stage_width, &stage_height);
-
-  new_height = (height * stage_width) / width;
-  if (new_height <= stage_height)
-    {
-      new_width = stage_width;
-
-      new_x = 0;
-      new_y = (stage_height - new_height) / 2;
-    }
-  else
-    {
-      new_width  = (width * stage_height) / height;
-      new_height = stage_height;
-
-      new_x = (stage_width - new_width) / 2;
-      new_y = 0;
-    }
-
-  clutter_actor_set_position (actor, new_x, new_y);
-  clutter_actor_set_size (actor, new_width, new_height);
-}
-
 int
 main (int argc, char *argv[])
 {
@@ -118,9 +81,8 @@ main (int argc, char *argv[])
     }
 
   stage = clutter_stage_new ();
-  clutter_actor_set_size (CLUTTER_ACTOR(stage), 320.0f, 240.0f);
+  clutter_actor_set_size (CLUTTER_ACTOR (stage), 320.0f, 240.0f);
 
-  actor = g_object_new (CLUTTER_GST_TYPE_ACTOR, NULL);
 
   /* Set up pipeline */
   pipeline = GST_PIPELINE(gst_pipeline_new (NULL));
@@ -129,6 +91,15 @@ main (int argc, char *argv[])
   capsfilter = gst_element_factory_make ("capsfilter", NULL);
   sink = clutter_gst_create_video_sink ();
 
+  /* Video actor */
+  actor = g_object_new (CLUTTER_TYPE_ACTOR,
+                        "content", g_object_new (CLUTTER_GST_TYPE_CONTENT,
+                                                 "video-sink", sink,
+                                                 NULL),
+                        "width", clutter_actor_get_width (stage),
+                        "height", clutter_actor_get_height (stage),
+                        NULL);
+
   /* make videotestsrc spit the format we want */
   caps = gst_caps_new_simple ("video/x-raw",
                               "format", G_TYPE_STRING, opt_fourcc,
@@ -143,15 +114,7 @@ main (int argc, char *argv[])
     g_critical("Could not link elements");
   gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_PLAYING);
 
-  player = CLUTTER_GST_PLAYER (g_object_new (CLUTTER_GST_TYPE_PIPELINE,
-                                             "video-sink", sink, NULL));
-  clutter_gst_actor_set_player (CLUTTER_GST_ACTOR (actor), player);
-  g_signal_connect (player,
-                    "size-change",
-                    G_CALLBACK (size_change), actor);
-
   clutter_actor_add_child (stage, actor);
-  /* clutter_actor_set_opacity (texture, 0x11); */
   clutter_actor_show (stage);
 
   clutter_main();


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