summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <llandwerlin@gmail.com>2013-07-22 13:31:52 +0100
committerLionel Landwerlin <llandwerlin@gmail.com>2013-07-22 13:31:52 +0100
commitc23cdfc584b2051c2962673b9078a5c92d9b30a8 (patch)
tree583b4936958193560c7ac3f06d419a7e47ff8f84
parent8b12180346be221cf25216f884d3a8b9f069141f (diff)
downloadclutter-gst-c23cdfc584b2051c2962673b9078a5c92d9b30a8.tar.gz
remove ClutterGstActor now replaced by ClutterGstContent
-rw-r--r--clutter-gst/Makefile.am2
-rw-r--r--clutter-gst/clutter-gst-actor.c333
-rw-r--r--clutter-gst/clutter-gst-actor.h120
-rw-r--r--clutter-gst/clutter-gst-auto-video-sink.c930
-rw-r--r--clutter-gst/clutter-gst-auto-video-sink.h19
-rw-r--r--clutter-gst/clutter-gst-camera.h5
-rw-r--r--clutter-gst/clutter-gst-crop.c1
-rw-r--r--clutter-gst/clutter-gst-plugin.c12
-rw-r--r--clutter-gst/clutter-gst.h1
-rw-r--r--doc/reference/clutter-gst-docs.sgml3
-rw-r--r--doc/reference/clutter-gst-sections.txt60
-rw-r--r--examples/pieces.js12
-rw-r--r--examples/video-sink-navigation.c51
-rw-r--r--examples/video-sink.c12
14 files changed, 216 insertions, 1345 deletions
diff --git a/clutter-gst/Makefile.am b/clutter-gst/Makefile.am
index ccb8e04..bfda4d8 100644
--- a/clutter-gst/Makefile.am
+++ b/clutter-gst/Makefile.am
@@ -25,7 +25,6 @@ source_h = \
$(srcdir)/clutter-gst-types.h \
$(srcdir)/clutter-gst-util.h \
$(srcdir)/clutter-gst-version.h \
- $(srcdir)/clutter-gst-actor.h \
$(srcdir)/clutter-gst-camera.h \
$(srcdir)/clutter-gst-camera-device.h \
$(srcdir)/clutter-gst-playback.h \
@@ -47,7 +46,6 @@ source_c = \
$(srcdir)/clutter-gst-types.c \
$(srcdir)/clutter-gst-marshal.c \
$(srcdir)/clutter-gst-player.c \
- $(srcdir)/clutter-gst-actor.c \
$(srcdir)/clutter-gst-camera.c \
$(srcdir)/clutter-gst-camera-device.c \
$(srcdir)/clutter-gst-playback.c \
diff --git a/clutter-gst/clutter-gst-actor.c b/clutter-gst/clutter-gst-actor.c
deleted file mode 100644
index e5b9f3c..0000000
--- a/clutter-gst/clutter-gst-actor.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Clutter-GStreamer.
- *
- * GStreamer integration library for Clutter.
- *
- * clutter-gst-actor.c - ClutterActor using GStreamer
- *
- * Authored By Matthew Allum <mallum@openedhand.com>
- * Damien Lespiau <damien.lespiau@intel.com>
- * Lionel Landwerlin <lionel.g.landwerlin@linux.intel.com>
- * Andre Moreira Magalhaes <andre.magalhaes@collabora.co.uk>
- *
- * Copyright (C) 2006 OpenedHand
- * Copyright (C) 2010-2013 Intel Corporation
- * Copyright (C) 2012 Collabora Ltd. <http://www.collabora.co.uk/>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:clutter-gst-video-actor
- * @short_description: Actor for playback of video files.
- *
- * #ClutterGstActor is a #ClutterActor that plays video files.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <gst/base/gstbasesink.h>
-#include <gst/video/video.h>
-
-#include "clutter-gst-actor.h"
-#include "clutter-gst-debug.h"
-#include "clutter-gst-enum-types.h"
-#include "clutter-gst-marshal.h"
-#include "clutter-gst-private.h"
-
-struct _ClutterGstActorPrivate
-{
- ClutterGstPlayer *player;
- ClutterGstFrame *frame;
-};
-
-enum {
- PROP_0,
-
- PROP_PLAYER
-};
-
-G_DEFINE_TYPE (ClutterGstActor, clutter_gst_actor, CLUTTER_TYPE_ACTOR)
-
-static void
-clutter_gst_actor_get_preferred_width (ClutterActor *actor,
- gfloat for_height,
- gfloat *min_width,
- gfloat *nat_width)
-{
- ClutterGstActorPrivate *priv = CLUTTER_GST_ACTOR (actor)->priv;
-
- if (min_width)
- *min_width = 0;
- if (nat_width)
- if (priv->frame)
- *nat_width = priv->frame->resolution.width;
-}
-
-static void
-clutter_gst_actor_get_preferred_height (ClutterActor *actor,
- gfloat for_width,
- gfloat *min_height,
- gfloat *nat_height)
-{
- ClutterGstActorPrivate *priv = CLUTTER_GST_ACTOR (actor)->priv;
-
- if (min_height)
- *min_height = 0;
- if (nat_height)
- if (priv->frame)
- *nat_height = priv->frame->resolution.height;
-}
-
-static void
-clutter_gst_actor_paint_frame (ClutterGstActor *self,
- ClutterGstFrame *frame)
-{
- ClutterActorBox box;
- guint8 paint_opacity;
-
- clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &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);
- cogl_set_source (frame->pipeline);
-
- cogl_rectangle (0, 0, box.x2 - box.x1, box.y2 - box.y1);
-}
-
-static void
-clutter_gst_actor_paint (ClutterActor *actor)
-{
- ClutterGstActor *self = CLUTTER_GST_ACTOR (actor);
- ClutterGstActorPrivate *priv = self->priv;
-
- if (priv->player)
- {
- ClutterGstFrame *frame = clutter_gst_player_get_frame (priv->player);
-
- if (frame)
- CLUTTER_GST_ACTOR_GET_CLASS (self)->paint_frame (self, frame);
- }
-}
-
-static void
-_player_new_frame (ClutterGstPlayer *player,
- ClutterGstFrame *frame,
- ClutterGstActor *self)
-{
- ClutterGstActorPrivate *priv = self->priv;
-
- if (priv->frame)
- g_boxed_free (CLUTTER_GST_TYPE_FRAME, priv->frame);
- priv->frame = g_boxed_copy (CLUTTER_GST_TYPE_FRAME, frame);
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
-}
-
-static void
-clutter_gst_actor_set_player_internal (ClutterGstActor *self,
- ClutterGstPlayer *player)
-{
- ClutterGstActorPrivate *priv = self->priv;
-
- if (priv->player) {
- g_boxed_free (CLUTTER_GST_TYPE_FRAME, priv->frame);
- priv->frame = NULL;
- g_signal_handlers_disconnect_by_func (priv->player,
- _player_new_frame,
- self);
-
- g_clear_object (&priv->player);
- }
-
- if (player != NULL) {
- priv->player = g_object_ref_sink (player);
- priv->frame = g_boxed_copy (CLUTTER_GST_TYPE_FRAME,
- clutter_gst_player_get_frame (player));
-
- g_signal_connect (priv->player, "new-frame",
- G_CALLBACK (_player_new_frame), self);
- }
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
- g_object_notify (G_OBJECT (self), "player");
-}
-
-/*
- * GObject implementation
- */
-
-static void
-clutter_gst_actor_dispose (GObject *object)
-{
- ClutterGstActorPrivate *priv = CLUTTER_GST_ACTOR (object)->priv;
-
- g_clear_object (&priv->player);
-
- if (priv->frame)
- {
- g_boxed_free (CLUTTER_GST_TYPE_FRAME, priv->frame);
- priv->frame = NULL;
- }
-
- G_OBJECT_CLASS (clutter_gst_actor_parent_class)->dispose (object);
-}
-
-static void
-clutter_gst_actor_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- ClutterGstActor *actor = CLUTTER_GST_ACTOR (object);
- ClutterGstActorPrivate *priv = actor->priv;
-
- switch (property_id)
- {
- case PROP_PLAYER:
- g_value_set_object (value, priv->player);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-clutter_gst_actor_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- ClutterGstActor *actor = CLUTTER_GST_ACTOR (object);
-
- switch (property_id)
- {
- case PROP_PLAYER:
- clutter_gst_actor_set_player_internal (actor,
- CLUTTER_GST_PLAYER (g_value_get_object (value)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-clutter_gst_actor_class_init (ClutterGstActorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
- GParamSpec *pspec;
-
- g_type_class_add_private (klass, sizeof (ClutterGstActorPrivate));
-
- object_class->dispose = clutter_gst_actor_dispose;
- object_class->set_property = clutter_gst_actor_set_property;
- object_class->get_property = clutter_gst_actor_get_property;
-
- actor_class->get_preferred_width = clutter_gst_actor_get_preferred_width;
- actor_class->get_preferred_height = clutter_gst_actor_get_preferred_height;
- actor_class->paint = clutter_gst_actor_paint;
-
- klass->paint_frame = clutter_gst_actor_paint_frame;
-
- pspec = g_param_spec_object ("player",
- "Player",
- "Player",
- G_TYPE_OBJECT,
- CLUTTER_GST_PARAM_READWRITE);
- g_object_class_install_property (object_class, PROP_PLAYER, pspec);
-}
-
-static void
-clutter_gst_actor_init (ClutterGstActor *actor)
-{
- actor->priv = G_TYPE_INSTANCE_GET_PRIVATE (actor,
- CLUTTER_GST_TYPE_ACTOR,
- ClutterGstActorPrivate);
-}
-
-/*
- * Public symbols
- */
-
-/**
- * clutter_gst_actor_new:
- *
- * Creates a new #ClutterGstActor.
- *
- * A newly created actor has a floating reference, which will be sunk
- * when it is added to another actor.
- *
- * Return value: the newly created #ClutterGstActor
- *
- * Since: 3.0
- */
-ClutterActor *
-clutter_gst_actor_new (void)
-{
- return g_object_new (CLUTTER_GST_TYPE_ACTOR,
- NULL);
-}
-
-/**
- * clutter_gst_actor_get_player:
- * @self: a #ClutterGstActor
- *
- * Retrieves the #ClutterGstPlayer used by the @self.
- *
- * Return value: (transfer none): the #ClutterGstPlayer element used by the actor
- *
- * Since: 3.0
- */
-ClutterGstPlayer *
-clutter_gst_actor_get_player (ClutterGstActor *self)
-{
- ClutterGstActorPrivate *priv;
-
- g_return_val_if_fail (CLUTTER_GST_IS_ACTOR (self), NULL);
-
- priv = self->priv;
-
- return priv->player;
-}
-
-/**
- * clutter_gst_actor_set_player:
- * @self: a #ClutterGstActor
- * @player: a #ClutterGstPlayer
- *
- * Set the #ClutterGstPlayer used by the @self.
- *
- * Since: 3.0
- */
-void
-clutter_gst_actor_set_player (ClutterGstActor *self,
- ClutterGstPlayer *player)
-{
- g_return_if_fail (CLUTTER_GST_IS_ACTOR (self));
- g_return_if_fail (CLUTTER_GST_IS_PLAYER (player) || player == NULL);
-
- clutter_gst_actor_set_player_internal (self, player);
-}
diff --git a/clutter-gst/clutter-gst-actor.h b/clutter-gst/clutter-gst-actor.h
deleted file mode 100644
index bce9e77..0000000
--- a/clutter-gst/clutter-gst-actor.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Clutter-GStreamer.
- *
- * GStreamer integration library for Clutter.
- *
- * clutter-gst-actor.h - ClutterActor using GStreamer
- *
- * Authored By Andre Moreira Magalhaes <andre.magalhaes@collabora.co.uk>
- * Lionel Landwerlin <lionel.g.landwerlin@linux.intel.com>
- *
- * Copyright (C) 2012 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2013 Intel Corporation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#if !defined(__CLUTTER_GST_H_INSIDE__) && !defined(CLUTTER_GST_COMPILATION)
-#error "Only <clutter-gst/clutter-gst.h> can be included directly."
-#endif
-
-#ifndef __CLUTTER_GST_ACTOR_H__
-#define __CLUTTER_GST_ACTOR_H__
-
-#include <glib-object.h>
-#include <clutter/clutter.h>
-
-#include <clutter-gst/clutter-gst-types.h>
-#include <clutter-gst/clutter-gst-player.h>
-
-G_BEGIN_DECLS
-
-#define CLUTTER_GST_TYPE_ACTOR clutter_gst_actor_get_type()
-
-#define CLUTTER_GST_ACTOR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- CLUTTER_GST_TYPE_ACTOR, \
- ClutterGstActor))
-
-#define CLUTTER_GST_ACTOR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- CLUTTER_GST_TYPE_ACTOR, \
- ClutterGstActorClass))
-
-#define CLUTTER_GST_IS_ACTOR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- CLUTTER_GST_TYPE_ACTOR))
-
-#define CLUTTER_GST_IS_ACTOR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- CLUTTER_GST_TYPE_ACTOR))
-
-#define CLUTTER_GST_ACTOR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- CLUTTER_GST_TYPE_ACTOR, \
- ClutterGstActorClass))
-
-typedef struct _ClutterGstActor ClutterGstActor;
-typedef struct _ClutterGstActorClass ClutterGstActorClass;
-typedef struct _ClutterGstActorPrivate ClutterGstActorPrivate;
-
-/**
- * ClutterGstActor:
- *
- * The #ClutterGstActor structure contains only private data and
- * should not be accessed directly.
- */
-struct _ClutterGstActor
-{
- /*< private >*/
- ClutterActor parent;
- ClutterGstActorPrivate *priv;
-};
-
-/**
- * ClutterGstActorClass:
- *
- * Base class for #ClutterGstActor.
- */
-struct _ClutterGstActorClass
-{
- /*< private >*/
- ClutterActorClass parent_class;
-
- /*< public >*/
- void (* paint_frame) (ClutterGstActor *actor, ClutterGstFrame *frame);
-
- /* Future padding */
- void (* _clutter_reserved2) (void);
- void (* _clutter_reserved3) (void);
- void (* _clutter_reserved4) (void);
- void (* _clutter_reserved5) (void);
- void (* _clutter_reserved6) (void);
- void (* _clutter_reserved7) (void);
- void (* _clutter_reserved8) (void);
-};
-
-GType clutter_gst_actor_get_type (void) G_GNUC_CONST;
-
-ClutterActor *clutter_gst_actor_new (void);
-
-ClutterGstPlayer *clutter_gst_actor_get_player (ClutterGstActor *self);
-void clutter_gst_actor_set_player (ClutterGstActor *self,
- ClutterGstPlayer *player);
-
-G_END_DECLS
-
-#endif /* __CLUTTER_GST_ACTOR_H__ */
diff --git a/clutter-gst/clutter-gst-auto-video-sink.c b/clutter-gst/clutter-gst-auto-video-sink.c
index c434e9a..4f0fd57 100644
--- a/clutter-gst/clutter-gst-auto-video-sink.c
+++ b/clutter-gst/clutter-gst-auto-video-sink.c
@@ -1,816 +1,266 @@
-/*
- * Clutter-GStreamer.
- *
- * GStreamer integration library for Clutter.
- *
- * clutter-gst-auto-video-sink.c - GStreamer Auto Clutter Video Sink bin.
- *
- * Authored by Josep Torra <support@fluendo.com>
- *
- * Copyright (C) 2011 Fluendo, S.A.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
+/* GStreamer
+ * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * (c) 2006 Jan Schmidt <thaytan@noraisin.net>
+ * (c) 2013 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:element-autovideosink
+ * @see_also: autoaudiosink, ximagesink, xvimagesink, sdlvideosink
+ *
+ * autovideosink is a video sink that automatically detects an appropriate
+ * video sink to use. It does so by scanning the registry for all elements
+ * that have <quote>Sink</quote> and <quote>Video</quote> in the class field
+ * of their element information, and also have a non-zero autoplugging rank.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch-1.0 -v -m videotestsrc ! clutterautovideosink
+ * ]|
+ * </refsect2>
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
-#include <clutter/clutter.h>
+#include "clutter-gst-aspectratio.h"
#include "clutter-gst-auto-video-sink.h"
-#include "clutter-gst-private.h"
+#include "clutter-gst-util.h"
-GST_DEBUG_CATEGORY_EXTERN (clutter_gst_auto_video_sink_debug);
-#define GST_CAT_DEFAULT clutter_gst_auto_video_sink_debug
-
-static GstStaticPadTemplate sink_template_factory =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
+#define DEFAULT_TS_OFFSET 0
+/* Properties */
enum
{
PROP_0,
- PROP_ACTOR,
- PROP_TS_OFFSET
+ PROP_TS_OFFSET,
+ PROP_CONTENT,
};
-#define DEFAULT_TS_OFFSET 0
-
-static gboolean clutter_gst_auto_video_sink_add (GstBin * bin,
- GstElement *element);
-static gboolean clutter_gst_auto_video_sink_remove (GstBin * bin,
- GstElement *element);
+static GstStateChangeReturn
+clutter_gst_auto_video_sink_change_state (GstElement *element,
+ GstStateChange transition);
+static void clutter_gst_auto_video_sink_dispose (ClutterGstAutoVideoSink *sink);
+static void clutter_gst_auto_video_sink_clear_kid (ClutterGstAutoVideoSink *sink);
+
+static void clutter_gst_auto_video_sink_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void clutter_gst_auto_video_sink_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+#define clutter_gst_auto_video_sink_parent_class parent_class
G_DEFINE_TYPE (ClutterGstAutoVideoSink,
- clutter_gst_auto_video_sink, GST_TYPE_BIN);
+ clutter_gst_auto_video_sink,
+ GST_TYPE_BIN)
-#define parent_class clutter_gst_auto_video_sink_parent_class
-
-typedef struct
-{
- const gchar *factory_name;
- GstElement *element;
- GstCaps *caps;
-} SinkElement;
-
-static GstCaps *
-_get_sink_caps (GstElement * sink)
-{
- GstPad *sinkpad;
- GstCaps *caps = NULL;
-
- /* try to activate */
- if (GST_STATE (sink) < GST_STATE_READY &&
- gst_element_set_state (sink, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE)
- {
- goto beach;
- }
-
- if ((sinkpad = gst_element_get_static_pad (sink, "sink"))) {
- /* Got the sink pad, now let's see which caps will be accepted */
- caps = gst_pad_query_caps (sinkpad, NULL);
- }
- gst_object_unref (sinkpad);
-
-beach:
- return caps;
-}
-
-static SinkElement *
-_sink_element_create (GstElement * element)
-{
- SinkElement *se = NULL;
- GstCaps *caps = NULL;
-
- /* Check if the sink can be set to READY and recover it's caps */
- if (!(caps = _get_sink_caps (element))) {
- gst_element_set_state (element, GST_STATE_NULL);
- gst_object_unref (element);
- goto beach;
- }
-
- if ((se = g_new0 (SinkElement, 1))) {
- gst_object_ref_sink (element);
- se->element = element;
- se->caps = caps;
- } else {
- gst_caps_unref (caps);
- gst_object_unref (element);
- }
-
-beach:
- return se;
-}
+static GstStaticPadTemplate sink_template =
+ GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS_ANY);
static void
-_sink_element_free (gpointer data, gpointer user_data)
+clutter_gst_auto_video_sink_class_init (ClutterGstAutoVideoSinkClass *klass)
{
- SinkElement *se = (SinkElement *) data;
-
- gst_element_set_state (se->element, GST_STATE_NULL);
- gst_caps_unref (se->caps);
- gst_object_unref (se->element);
- g_free (se);
-}
-
-static gboolean
-_factory_filter (GstPluginFeature * feature, gpointer data)
-{
- const gchar *klass;
- guint rank;
-
- /* we only care about element factories */
- if (!GST_IS_ELEMENT_FACTORY (feature))
- return FALSE;
-
- /* video sinks */
- klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY (feature),
- GST_ELEMENT_METADATA_KLASS);
- if (!(strstr (klass, "Sink") && strstr (klass, "Video")))
- return FALSE;
-
- /* only select elements with autoplugging rank */
- rank = gst_plugin_feature_get_rank (feature);
- if (rank < GST_RANK_MARGINAL)
- return FALSE;
-
- return TRUE;
-}
-
-static gint
-_factories_compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
-{
- gint diff;
-
- diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
-
- if (diff != 0)
- return diff;
-
- return strcmp (gst_plugin_feature_get_name (f2),
- gst_plugin_feature_get_name (f1));
-}
-
-static GstElement *
-_create_element_with_pretty_name (ClutterGstAutoVideoSink * bin,
- GstElementFactory * factory)
-{
- GstElement *element;
- gchar *name, *marker;
-
- marker =
- g_strdup (gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
- if (g_str_has_suffix (marker, "sink"))
- marker[strlen (marker) - 4] = '\0';
- if (g_str_has_prefix (marker, "gst"))
- g_memmove (marker, marker + 3, strlen (marker + 3) + 1);
- name = g_strdup_printf ("%s-actual-sink-%s", GST_OBJECT_NAME (bin), marker);
- g_free (marker);
-
- element = gst_element_factory_create (factory, name);
- g_free (name);
-
- return element;
-}
-
-static inline gboolean
-_is_clutter_sink (GstElement * element)
-{
- GParamSpec *pspec;
-
- pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
- "actor");
-
- if (pspec == NULL) {
- GST_DEBUG_OBJECT (element, "don't have an actor property");
- return FALSE;
- }
-
- if (CLUTTER_GST_TYPE_ACTOR == pspec->value_type ||
- g_type_is_a (pspec->value_type, CLUTTER_GST_TYPE_ACTOR)) {
- GST_DEBUG_OBJECT (element, "has an actor property");
- return TRUE;
- }
-
- GST_WARNING_OBJECT (element, "has actor property, but it's of type %s "
- "and we expected it to be of type CLUTTER_GST_TYPE_ACTOR",
- g_type_name (pspec->value_type));
-
- return FALSE;
-}
-
-static inline void
-_sinks_discover (ClutterGstAutoVideoSink * bin)
-{
- GstCaps *caps = gst_caps_new_empty ();
- GList *factories, *item;
-
- factories = gst_registry_feature_filter (gst_registry_get (),
- (GstPluginFeatureFilter) _factory_filter, FALSE, bin);
- factories = g_list_sort (factories, (GCompareFunc) _factories_compare_ranks);
-
- for (item = factories; item != NULL; item = item->next) {
- GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
- GstElement *el;
- SinkElement *se;
-
- if ((el = _create_element_with_pretty_name (bin, f))) {
- GST_DEBUG_OBJECT (bin, "Testing %s",
- gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (f)));
-
- /* Check for an actor property with CLUTTER_GST_TYPE_ACTOR type */
- if (!_is_clutter_sink (el)) {
- gst_object_unref (el);
- continue;
- }
- se = _sink_element_create (el);
- if (se) {
- GstCaps *caps_union = gst_caps_merge (caps, gst_caps_ref (se->caps));
- caps = caps_union;
- bin->sinks = g_slist_append (bin->sinks, se);
- GST_DEBUG_OBJECT (bin, "Added %s with caps %" GST_PTR_FORMAT,
- gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (f)), se->caps);
- } else {
- gst_object_unref (el);
- }
- }
- }
-
- if (!gst_caps_is_empty (caps)) {
- gst_caps_replace (&bin->video_caps, caps);
- GST_DEBUG_OBJECT (bin, "Supported caps %" GST_PTR_FORMAT, bin->video_caps);
- }
- gst_caps_unref (caps);
-}
-
-static inline void
-_sinks_destroy (ClutterGstAutoVideoSink * bin)
-{
- g_slist_foreach (bin->sinks, _sink_element_free, NULL);
- g_slist_free (bin->sinks);
- bin->sinks = NULL;
-}
-
-static inline GstElement *
-_sinks_find_sink_by_caps (ClutterGstAutoVideoSink * bin, GstCaps * caps)
-{
- GstElement *element = NULL;
- GSList *walk = bin->sinks;
-
- while (walk) {
- SinkElement *se = (SinkElement *) walk->data;
- if (se) {
- GstCaps *intersect = NULL;
-
- intersect = gst_caps_intersect (caps, se->caps);
- if (!gst_caps_is_empty (intersect)) {
- element = se->element;
- gst_caps_unref (intersect);
- GST_DEBUG_OBJECT (bin, "found sink %" GST_PTR_FORMAT, element);
- goto beach;
- }
- gst_caps_unref (intersect);
- }
- walk = g_slist_next (walk);
- }
-
-beach:
- return element;
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
+
+ gobject_class->dispose = (GObjectFinalizeFunc) clutter_gst_auto_video_sink_dispose;
+ gobject_class->set_property = clutter_gst_auto_video_sink_set_property;
+ gobject_class->get_property = clutter_gst_auto_video_sink_get_property;
+
+ eklass->change_state = GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_change_state);
+
+ g_object_class_install_property (gobject_class,
+ PROP_TS_OFFSET,
+ g_param_spec_int64 ("ts-offset",
+ "TS Offset",
+ "Timestamp offset in nanoseconds",
+ G_MININT64,
+ G_MAXINT64,
+ DEFAULT_TS_OFFSET,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CONTENT,
+ g_param_spec_object ("content",
+ "Clutter Content",
+ "Clutter Content",
+ CLUTTER_GST_TYPE_CONTENT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ gst_element_class_add_pad_template (eklass,
+ gst_static_pad_template_get (&sink_template));
+ gst_element_class_set_static_metadata (eklass, "Clutter Auto video sink",
+ "Sink/Video",
+ "Video sink using a Clutter as output",
+ "Lionel Landwerlin <lionel.g.landwerlin@linux.intel.com>");
}
static void
-clutter_gst_auto_video_sink_do_async_start (ClutterGstAutoVideoSink * bin)
+clutter_gst_auto_video_sink_dispose (ClutterGstAutoVideoSink *sink)
{
- GstMessage *message;
-
- if (!bin->need_async_start) {
- GST_DEBUG_OBJECT (bin, "no async_start needed");
- return;
- }
+ clutter_gst_auto_video_sink_clear_kid (sink);
- bin->async_pending = TRUE;
-
- GST_INFO_OBJECT (bin, "Sending async_start message");
- message = gst_message_new_async_start (GST_OBJECT_CAST (bin));
- GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (bin), message);
+ G_OBJECT_CLASS (parent_class)->dispose ((GObject *) sink);
}
static void
-clutter_gst_auto_video_sink_do_async_done (ClutterGstAutoVideoSink * bin)
-{
- GstMessage *message;
-
- if (bin->async_pending) {
- GST_INFO_OBJECT (bin, "Sending async_done message");
- message = gst_message_new_async_done (GST_OBJECT_CAST (bin), FALSE);
- GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (bin), message);
-
- bin->async_pending = FALSE;
- }
- bin->need_async_start = FALSE;
-}
-
-static gboolean
-clutter_gst_auto_video_sink_reconfigure (ClutterGstAutoVideoSink * bin,
- GstCaps * caps)
-{
- GstElement *sink;
- GstPad *sink_pad_target = NULL;
- gboolean ret = FALSE;
-
- GST_DEBUG_OBJECT (bin, "reconfigure the bin");
-
- sink = _sinks_find_sink_by_caps (bin, caps);
-
- if (sink && sink == bin->child) {
- GST_DEBUG_OBJECT (bin, "we already using that sink, done");
- ret = TRUE;
- goto beach;
- }
-
- if (bin->child) {
- /* Deactivate current child */
- GST_DEBUG_OBJECT (bin, "going to remove %" GST_PTR_FORMAT, bin->child);
- gst_ghost_pad_set_target (GST_GHOST_PAD (bin->sink_pad), NULL);
- gst_element_set_state (bin->child, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (bin), bin->child);
- bin->child = NULL;
- }
-
- /* This might have failed */
- if (!sink) {
- GST_ELEMENT_ERROR (bin, LIBRARY, INIT,
- ("No usable video rendering element found."),
- ("Failed detecting a video sink for the requested" " caps."));
- goto beach;
- }
-
- /* Now we are ready to add the sink to bin */
- bin->child = gst_object_ref (sink);
- g_object_set (G_OBJECT(bin->child), "actor", bin->actor,
- "ts-offset", bin->ts_offset, NULL);
-
- GST_DEBUG_OBJECT (bin, "going to add %" GST_PTR_FORMAT, bin->child);
- /* Add our child */
- gst_bin_add (GST_BIN (bin), bin->child);
- /* Bring all elements to the bin's state */
- gst_element_sync_state_with_parent (bin->child);
- /* Get the child's sink pad */
- sink_pad_target = gst_element_get_static_pad (bin->child, "sink");
-
- /* Ghost the sink pad to the appropriate element */
- GST_DEBUG_OBJECT (sink_pad_target, "ghosting pad as bin sink pad");
- gst_ghost_pad_set_target (GST_GHOST_PAD (bin->sink_pad), sink_pad_target);
- gst_object_unref (sink_pad_target);
- ret = TRUE;
-beach:
- return ret;
-}
-
-static GstPadProbeReturn
-clutter_gst_auto_video_sink_sink_pad_blocked_cb (GstPad * pad,
- GstPadProbeInfo * info, gpointer user_data)
+clutter_gst_auto_video_sink_clear_kid (ClutterGstAutoVideoSink *sink)
{
- ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK_CAST (user_data);
- GstCaps *caps = NULL;
-
- /* This only occurs when our bin is first initialised || stream changes */
- if (G_UNLIKELY (!bin->setup)) {
-
- caps = gst_pad_peer_query_caps (bin->sink_pad, NULL);
-
- if (G_UNLIKELY (!caps)) {
- GST_WARNING_OBJECT (bin, "no incoming caps defined, can't setup");
- goto beach;
- }
-
- if (G_UNLIKELY (gst_caps_is_empty (caps))) {
- GST_WARNING_OBJECT (bin, "caps empty, can't setup");
- goto beach;
- }
-
- GST_DEBUG_OBJECT (bin, "incoming caps %" GST_PTR_FORMAT, caps);
-
- if (!clutter_gst_auto_video_sink_reconfigure (bin, caps))
- goto beach;
-
- /* We won't be doing this again unless stream changes */
- bin->setup = TRUE;
- }
-
- /* Note that we finished our ASYNC state change but our children will have
- * posted their own messages on our bus. */
- clutter_gst_auto_video_sink_do_async_done (bin);
-
- GST_DEBUG_OBJECT (bin, "unblock the pad");
-
-beach:
- if (caps) {
- gst_caps_unref (caps);
- }
- bin->sink_block_id = 0;
- return GST_PAD_PROBE_REMOVE;
-}
-
-static GstCaps *
-clutter_gst_auto_video_sink_get_caps (ClutterGstAutoVideoSink * bin)
-{
- GstCaps *ret;
-
- if (bin->video_caps) {
- ret = gst_caps_ref (bin->video_caps);
- } else {
- ret = gst_static_pad_template_get_caps (&sink_template_factory);
- }
-
- return ret;
-}
-
-static gboolean
-clutter_gst_auto_video_sink_accept_caps (ClutterGstAutoVideoSink * bin,
- GstCaps * caps)
-{
- gboolean ret = FALSE;
- GstCaps *allowed_caps = clutter_gst_auto_video_sink_get_caps (bin);
-
- if (allowed_caps) {
- GstCaps *result = NULL;
-
- result = gst_caps_intersect (caps, allowed_caps);
-
- if (!gst_caps_is_empty (result))
- ret = TRUE;
-
- caps = result;
- }
-
- gst_caps_unref (allowed_caps);
-
- return ret;
-}
-
-static gboolean
-clutter_gst_auto_video_sink_query (GstPad * pad, GstObject * parent,
- GstQuery * query)
-{
- gboolean res;
- ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK (parent);
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_ACCEPT_CAPS:
- {
- GstCaps *caps;
-
- gst_query_parse_accept_caps (query, &caps);
- res = clutter_gst_auto_video_sink_accept_caps (bin, caps);
- gst_query_set_accept_caps_result (query, res);
- /* return TRUE, we have answered the query */
- res = TRUE;
- }
- break;
- case GST_QUERY_CAPS:
+ if (sink->kid)
{
- GstCaps *caps, *filter;
-
- gst_query_parse_caps (query, &filter);
- caps = clutter_gst_auto_video_sink_get_caps (bin);
- gst_query_set_caps_result (query, caps);
- gst_caps_unref (caps);
- res = TRUE;
+ gst_element_set_state (sink->kid, GST_STATE_NULL);
+ gst_bin_remove (GST_BIN (sink), sink->kid);
+ sink->kid = NULL;
+ /* Don't lose the SINK flag */
+ GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_FLAG_SINK);
}
- break;
- default:
- res = gst_pad_query_default (pad, parent, query);
- break;
- }
- return res;
-}
-
-
-static GstStateChangeReturn
-clutter_gst_auto_video_sink_change_state (GstElement * element,
- GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS, bret;
- ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- _sinks_discover (bin);
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- CLUTTER_GST_AUTO_VIDEO_SINK_LOCK (bin);
- bin->need_async_start = TRUE;
- /* Here we set our callback to intercept data flow on the first buffer */
- GST_DEBUG_OBJECT (bin, "try to block input pad to setup internal "
- "pipeline");
-
- if (bin->sink_block_id == 0)
- bin->sink_block_id =
- gst_pad_add_probe (bin->sink_block_pad,
- GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
- clutter_gst_auto_video_sink_sink_pad_blocked_cb, bin, NULL);
- ret = GST_STATE_CHANGE_ASYNC;
- clutter_gst_auto_video_sink_do_async_start (bin);
- CLUTTER_GST_AUTO_VIDEO_SINK_UNLOCK (bin);
- break;
- default:
- break;
- }
-
- /* do the state change of the children */
- bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- /* now look at the result of our children and adjust the return value */
- switch (bret) {
- case GST_STATE_CHANGE_FAILURE:
- /* failure, we stop */
- goto activate_failed;
- case GST_STATE_CHANGE_NO_PREROLL:
- /* some child returned NO_PREROLL. This is strange but we never know. We
- * commit our async state change (if any) and return the NO_PREROLL */
- clutter_gst_auto_video_sink_do_async_done (bin);
- ret = bret;
- break;
- case GST_STATE_CHANGE_ASYNC:
- /* some child was async, return this */
- ret = bret;
- break;
- default:
- /* return our previously configured return value */
- break;
- }
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- bin->need_async_start = TRUE;
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- CLUTTER_GST_AUTO_VIDEO_SINK_LOCK (bin);
-
- /* Unblock pad */
- if (bin->sink_block_id != 0) {
- gst_pad_remove_probe (bin->sink_block_pad, bin->sink_block_id);
- bin->sink_block_id = 0;
- }
- /* Unset ghost pad target */
- GST_DEBUG_OBJECT (bin, "setting ghost pad target to NULL");
- gst_ghost_pad_set_target (GST_GHOST_PAD (bin->sink_pad), NULL);
-
- /* Destroy our child */
- if (bin->child) {
- GST_DEBUG_OBJECT (bin->child, "removing child sink");
- gst_element_set_state (bin->child, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (bin), bin->child);
- bin->child = NULL;
- }
-
- bin->setup = FALSE;
- CLUTTER_GST_AUTO_VIDEO_SINK_UNLOCK (bin);
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- _sinks_destroy (bin);
- clutter_gst_auto_video_sink_do_async_done (bin);
- break;
- default:
- break;
- }
-
- return ret;
- /* ERRORS */
-activate_failed:
- {
- GST_DEBUG_OBJECT (bin,
- "element failed to change states -- activation problem?");
- return GST_STATE_CHANGE_FAILURE;
- }
-}
-
-/*
- * Call the base class implementation and make
- * sure that the GST_ELEMENT_FLAG_SINK flag is still
- * set afterwards.
- */
-static gboolean
-clutter_gst_auto_video_sink_add (GstBin * bin, GstElement * element)
-{
- gboolean result;
-
- result = GST_BIN_CLASS (parent_class)->add_element (bin, element);
- GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SINK);
- return result;
}
/*
- * Call the base class implementation and make
- * sure that the GST_ELEMENT_FLAG_SINK flag is still
- * set afterwards.
+ * Hack to make initial linking work; ideally, this'd work even when
+ * no target has been assigned to the ghostpad yet.
*/
-static gboolean
-clutter_gst_auto_video_sink_remove (GstBin * bin, GstElement * element) {
- gboolean result;
-
- result = GST_BIN_CLASS (parent_class)->remove_element (bin, element);
- GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SINK);
- return result;
-}
static void
-clutter_gst_auto_video_sink_dispose (GObject * object)
+clutter_gst_auto_video_sink_reset (ClutterGstAutoVideoSink *sink)
{
- ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK (object);
-
- GST_DEBUG_OBJECT (bin, "Disposing");
+ GstPad *targetpad;
- if (bin->child) {
- gst_element_set_state (bin->child, GST_STATE_NULL);
- gst_object_unref (bin->child);
- bin->child = NULL;
- }
-
- if (bin->sink_block_pad) {
- gst_object_unref (bin->sink_block_pad);
- bin->sink_block_pad = NULL;
- }
+ /* Remove any existing element */
+ clutter_gst_auto_video_sink_clear_kid (sink);
- bin->actor = NULL;
+ /* video sink */
+ sink->kid = clutter_gst_create_video_sink ();
+ gst_bin_add (GST_BIN (sink), sink->kid);
- G_OBJECT_CLASS (parent_class)->dispose ((GObject *) object);
+ /* pad, setting this target should always work */
+ targetpad = gst_element_get_static_pad (sink->kid, "sink");
+ gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
+ gst_object_unref (targetpad);
}
+static GstStaticCaps raw_caps = GST_STATIC_CAPS ("video/x-raw");
+
static void
-clutter_gst_auto_video_sink_finalize (GObject * object)
+clutter_gst_auto_video_sink_init (ClutterGstAutoVideoSink *sink)
{
- ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK (object);
-
- GST_DEBUG_OBJECT (bin, "Destroying");
+ sink->pad = gst_ghost_pad_new_no_target ("sink", GST_PAD_SINK);
+ gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
- _sinks_destroy (bin);
+ clutter_gst_auto_video_sink_reset (sink);
- g_mutex_clear (&bin->lock);
-
- GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
-}
+ sink->ts_offset = DEFAULT_TS_OFFSET;
-static void
-clutter_gst_auto_video_sink_set_actor (ClutterGstAutoVideoSink * bin,
- ClutterGstActor * actor)
-{
- bin->actor = actor;
- if (bin->setup) {
- g_object_set (G_OBJECT (bin->child), "actor", actor, NULL);
- }
+ /* mark as sink */
+ GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_FLAG_SINK);
}
static void
-clutter_gst_auto_video_sink_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec)
+clutter_gst_auto_video_sink_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK (object);
+ ClutterGstAutoVideoSink *sink = CLUTTER_GST_AUTO_VIDEO_SINK (object);
- switch (prop_id) {
- case PROP_ACTOR:
- clutter_gst_auto_video_sink_set_actor (bin, g_value_get_object (value));
- break;
+ switch (prop_id)
+ {
case PROP_TS_OFFSET:
- bin->ts_offset = g_value_get_int64 (value);
- if (bin->child) {
- g_object_set_property (G_OBJECT (bin->child), pspec->name,
- value);
- }
+ sink->ts_offset = g_value_get_int64 (value);
+ if (sink->kid)
+ g_object_set_property (G_OBJECT (sink->kid), pspec->name, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
- }
+ }
}
static void
-clutter_gst_auto_video_sink_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
+clutter_gst_auto_video_sink_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK (object);
+ ClutterGstAutoVideoSink *sink = CLUTTER_GST_AUTO_VIDEO_SINK (object);
- switch (prop_id) {
- case PROP_ACTOR:
- g_value_set_object (value, bin->actor);
- break;
+ switch (prop_id)
+ {
case PROP_TS_OFFSET:
- g_value_set_int64 (value, bin->ts_offset);
+ g_value_set_int64 (value, sink->ts_offset);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
- }
+ }
}
-static void
-clutter_gst_auto_video_sink_class_init (ClutterGstAutoVideoSinkClass * klass)
+static GstStateChangeReturn
+clutter_gst_auto_video_sink_change_state (GstElement *element,
+ GstStateChange transition)
{
- GObjectClass *oclass = G_OBJECT_CLASS (klass);
- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
- GstBinClass *gstbin_class = GST_BIN_CLASS (klass);
- GParamSpec *pspec;
-
- oclass->dispose = clutter_gst_auto_video_sink_dispose;
- oclass->finalize = clutter_gst_auto_video_sink_finalize;
- oclass->set_property = clutter_gst_auto_video_sink_set_property;
- oclass->get_property = clutter_gst_auto_video_sink_get_property;
-
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&sink_template_factory));
-
- gst_element_class_set_metadata (gstelement_class,
- "Auto Clutter Sink",
- "Sink/Video",
- "Autoplug clutter capable video sinks",
- "Josep Torra <support@fluendo.com>");
-
- /**
- * ClutterGstAutoVideoSink:actor:
- *
- * This is the actor the video is decoded into. It can be any
- * #ClutterGstActor, however Cluter-Gst has a handy subclass,
- * #ClutterGstVideoActor, that implements the #ClutterGstPlayer
- * interface.
- */
- pspec = g_param_spec_object ("actor",
- "Actor",
- "Actor the video will be decoded into",
- CLUTTER_GST_TYPE_ACTOR,
- CLUTTER_GST_PARAM_READWRITE);
-
- g_object_class_install_property (oclass, PROP_ACTOR, pspec);
-
- g_object_class_install_property (oclass, PROP_TS_OFFSET,
- g_param_spec_int64 ("ts-offset", "TS Offset",
- "Timestamp offset in nanoseconds", G_MININT64, G_MAXINT64,
- DEFAULT_TS_OFFSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_change_state);
-
- gstbin_class->add_element =
- GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_add);
- gstbin_class->remove_element =
- GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_remove);
-}
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+ ClutterGstAutoVideoSink *sink = CLUTTER_GST_AUTO_VIDEO_SINK (element);
-static void
-clutter_gst_auto_video_sink_init (ClutterGstAutoVideoSink * bin)
-{
- GstPad *proxypad;
- GstPadTemplate *template;
- GValue val = { 0, };
-
- bin->setup = FALSE;
- bin->actor = NULL;
- bin->ts_offset = DEFAULT_TS_OFFSET;
-
- /* Create a ghost pad with no target at first */
- template = gst_static_pad_template_get (&sink_template_factory);
- bin->sink_pad = gst_ghost_pad_new_no_target_from_template ("sink", template);
- gst_object_unref (template);
-
- gst_pad_set_active (bin->sink_pad, TRUE);
-
- proxypad = NULL;
-
- if (bin->sink_pad) {
- GstIterator *it = gst_pad_iterate_internal_links (bin->sink_pad);
- if (G_UNLIKELY (!it ||
- gst_iterator_next (it,
- &val) !=
- GST_ITERATOR_OK || g_value_get_object (&val) == NULL)) {
- GST_ERROR_OBJECT (bin,
- "failed to get internally linked pad from sinkpad");
- }
- if (it)
- gst_iterator_free (it);
- proxypad = GST_PAD_CAST (g_value_get_object (&val));
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ if (!sink->content)
+ {
+ ClutterActor *stage = clutter_stage_new ();
+ ClutterActor *actor = clutter_actor_new ();
+ sink->content = clutter_gst_aspectratio_new ();
+
+ clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
+ clutter_actor_set_layout_manager (stage,
+ clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FILL,
+ CLUTTER_BIN_ALIGNMENT_FILL));
+
+ clutter_actor_add_child (stage, actor);
+
+ clutter_actor_set_content (actor, sink->content);
+ clutter_actor_show (stage);
+ }
+ clutter_gst_content_set_sink (CLUTTER_GST_CONTENT (sink->content),
+ COGL_GST_VIDEO_SINK (sink->kid));
+ break;
+ default:
+ break;
}
- bin->sink_block_pad = proxypad;
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ /* switch (transition) { */
+ /* case GST_STATE_CHANGE_READY_TO_NULL: */
+ /* gst_auto_video_sink_reset (sink); */
+ /* break; */
+ /* default: */
+ /* break; */
+ /* } */
- gst_pad_set_query_function (bin->sink_pad,
- GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_query));
- gst_element_add_pad (GST_ELEMENT (bin), bin->sink_pad);
- /* Setup the element */
- GST_OBJECT_FLAG_SET (GST_OBJECT (bin), GST_ELEMENT_FLAG_SINK);
- g_mutex_init (&bin->lock);
+ return ret;
}
diff --git a/clutter-gst/clutter-gst-auto-video-sink.h b/clutter-gst/clutter-gst-auto-video-sink.h
index cfb0d27..7c0f396 100644
--- a/clutter-gst/clutter-gst-auto-video-sink.h
+++ b/clutter-gst/clutter-gst-auto-video-sink.h
@@ -30,7 +30,6 @@
#include <gst/gst.h>
#include <clutter/clutter.h>
-#include <clutter-gst/clutter-gst-actor.h>
G_BEGIN_DECLS
@@ -86,23 +85,11 @@ struct _ClutterGstAutoVideoSink
{
GstBin parent;
- GstPad *sink_pad;
- GstPad *sink_block_pad;
- guint sink_block_id;
-
- GstElement *child;
-
- GstCaps *video_caps;
- GSList *sinks;
-
- gboolean need_async_start;
- gboolean async_pending;
- gboolean setup;
-
- ClutterGstActor *actor;
+ GstElement *kid;
+ GstPad *pad;
GstClockTimeDiff ts_offset;
- GMutex lock;
+ ClutterContent *content;
};
struct _ClutterGstAutoVideoSinkClass
diff --git a/clutter-gst/clutter-gst-camera.h b/clutter-gst/clutter-gst-camera.h
index f348ab0..902905b 100644
--- a/clutter-gst/clutter-gst-camera.h
+++ b/clutter-gst/clutter-gst-camera.h
@@ -39,7 +39,6 @@
#include <gst/gstelement.h>
#include <gst/pbutils/encoding-profile.h>
-#include <clutter-gst/clutter-gst-actor.h>
#include <clutter-gst/clutter-gst-camera-device.h>
#include <clutter-gst/clutter-gst-types.h>
@@ -82,7 +81,7 @@ typedef struct _ClutterGstCameraPrivate ClutterGstCameraPrivate;
struct _ClutterGstCamera
{
/*< private >*/
- ClutterGstActor parent;
+ GObject parent;
ClutterGstCameraPrivate *priv;
};
@@ -94,7 +93,7 @@ struct _ClutterGstCamera
struct _ClutterGstCameraClass
{
/*< private >*/
- ClutterGstActorClass parent_class;
+ GObjectClass parent_class;
void (* ready_for_capture) (ClutterGstCamera *self,
gboolean ready);
diff --git a/clutter-gst/clutter-gst-crop.c b/clutter-gst/clutter-gst-crop.c
index da5f110..2e01295 100644
--- a/clutter-gst/clutter-gst-crop.c
+++ b/clutter-gst/clutter-gst-crop.c
@@ -300,7 +300,6 @@ static void
clutter_gst_crop_class_init (ClutterGstCropClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ClutterGstActorClass *gst_actor_class = CLUTTER_GST_ACTOR_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (ClutterGstCropPrivate));
diff --git a/clutter-gst/clutter-gst-plugin.c b/clutter-gst/clutter-gst-plugin.c
index 866b599..7f24d46 100644
--- a/clutter-gst/clutter-gst-plugin.c
+++ b/clutter-gst/clutter-gst-plugin.c
@@ -37,7 +37,6 @@
#include "clutter-gst-auto-video-sink.h"
-GST_DEBUG_CATEGORY (clutter_gst_video_sink_debug);
GST_DEBUG_CATEGORY (clutter_gst_auto_video_sink_debug);
/* entry point to initialize the plug-in
@@ -51,7 +50,7 @@ plugin_init (GstPlugin *plugin)
gboolean ret;
GST_DEBUG_CATEGORY_INIT (clutter_gst_auto_video_sink_debug,
- "autocluttersink",
+ "clutterautovideosink",
0,
"clutter auto video sink");
@@ -64,15 +63,8 @@ plugin_init (GstPlugin *plugin)
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
return FALSE;
- /* ret = gst_element_register (plugin, */
- /* "cluttersink", */
- /* GST_RANK_MARGINAL, */
- /* CLUTTER_GST_TYPE_VIDEO_SINK); */
- /* if (!ret) */
- /* return FALSE; */
-
ret = gst_element_register (plugin,
- "autocluttersink",
+ "clutterautovideosink",
GST_RANK_NONE,
CLUTTER_GST_TYPE_AUTO_VIDEO_SINK);
if (!ret)
diff --git a/clutter-gst/clutter-gst.h b/clutter-gst/clutter-gst.h
index be2aadc..5cb1bed 100644
--- a/clutter-gst/clutter-gst.h
+++ b/clutter-gst/clutter-gst.h
@@ -32,7 +32,6 @@
#include "clutter-gst-types.h"
#include "clutter-gst-enum-types.h"
-#include "clutter-gst-actor.h"
#include "clutter-gst-aspectratio.h"
#include "clutter-gst-camera-device.h"
#include "clutter-gst-camera.h"
diff --git a/doc/reference/clutter-gst-docs.sgml b/doc/reference/clutter-gst-docs.sgml
index c1bc271..780a4fc 100644
--- a/doc/reference/clutter-gst-docs.sgml
+++ b/doc/reference/clutter-gst-docs.sgml
@@ -55,12 +55,9 @@
<chapter>
<title>Clutter Actors And Objects</title>
- <xi:include href="xml/clutter-gst-actor.xml"/>
<xi:include href="xml/clutter-gst-player.xml"/>
- <xi:include href="xml/clutter-gst-video-actor.xml"/>
<xi:include href="xml/clutter-gst-camera-actor.xml"/>
<xi:include href="xml/clutter-gst-camera-device.xml"/>
- <xi:include href="xml/clutter-gst-video-sink.xml"/>
<xi:include href="xml/clutter-gst-types.xml"/>
<xi:include href="xml/clutter-gst-util.xml"/>
<xi:include href="xml/clutter-gst-version.xml"/>
diff --git a/doc/reference/clutter-gst-sections.txt b/doc/reference/clutter-gst-sections.txt
index 6f2edca..7e2c39c 100644
--- a/doc/reference/clutter-gst-sections.txt
+++ b/doc/reference/clutter-gst-sections.txt
@@ -65,66 +65,6 @@ ClutterGstPlayerIfacePrivate
</SECTION>
<SECTION>
-<FILE>clutter-gst-actor</FILE>
-<TITLE>ClutterGstActor</TITLE>
-ClutterGstActor
-ClutterGstActorClass
-clutter_gst_actor_get_cogl_texture
-clutter_gst_actor_set_cogl_texture
-clutter_gst_actor_get_cogl_material
-clutter_gst_actor_set_cogl_material
-clutter_gst_actor_is_idle
-clutter_gst_actor_get_idle_material
-clutter_gst_actor_set_idle_material
-<SUBSECTION Standard>
-CLUTTER_GST_ACTOR
-CLUTTER_GST_IS_ACTOR
-CLUTTER_GST_TYPE_ACTOR
-clutter_gst_actor_get_type
-CLUTTER_GST_ACTOR_CLASS
-CLUTTER_GST_IS_ACTOR_CLASS
-CLUTTER_GST_ACTOR_GET_CLASS
-<SUBSECTION Private>
-ClutterGstActorPrivate
-</SECTION>
-
-<SECTION>
-<FILE>clutter-gst-video-actor</FILE>
-<TITLE>ClutterGstVideoActor</TITLE>
-ClutterGstVideoActor
-ClutterGstVideoActorClass
-clutter_gst_video_actor_new
-<SUBSECTION Standard>
-CLUTTER_GST_VIDEO_ACTOR
-CLUTTER_GST_IS_VIDEO_ACTOR
-CLUTTER_GST_TYPE_VIDEO_ACTOR
-clutter_gst_video_actor_get_type
-CLUTTER_GST_VIDEO_ACTOR_CLASS
-CLUTTER_GST_IS_VIDEO_ACTOR_CLASS
-CLUTTER_GST_VIDEO_ACTOR_GET_CLASS
-<SUBSECTION Private>
-ClutterGstVideoActorPrivate
-</SECTION>
-
-<SECTION>
-<FILE>clutter-gst-video-sink</FILE>
-<TITLE>ClutterGstVideoSink</TITLE>
-ClutterGstVideoSink
-ClutterGstVideoSinkClass
-clutter_gst_video_sink_new
-<SUBSECTION Standard>
-CLUTTER_GST_VIDEO_SINK
-CLUTTER_GST_IS_VIDEO_SINK
-CLUTTER_GST_TYPE_VIDEO_SINK
-clutter_gst_video_sink_get_type
-CLUTTER_GST_VIDEO_SINK_CLASS
-CLUTTER_GST_IS_VIDEO_SINK_CLASS
-CLUTTER_GST_VIDEO_SINK_GET_CLASS
-<SUBSECTION Private>
-ClutterGstVideoSinkPrivate
-</SECTION>
-
-<SECTION>
<FILE>clutter-gst-camera-actor</FILE>
<TITLE>ClutterGstCameraActor</TITLE>
ClutterGstCameraActor
diff --git a/examples/pieces.js b/examples/pieces.js
index 34606c3..89c5f50 100644
--- a/examples/pieces.js
+++ b/examples/pieces.js
@@ -33,8 +33,8 @@ const ROWS = 3;
const BIT_WIDTH = 200;
const BIT_HEIGHT = 200;
-if (ARGV.length < 1)
- throw "Needs 1 arguments : piece.js videofile";
+//if (ARGV.length < 1)
+// throw "Needs 1 arguments : piece.js videofile";
//
@@ -115,10 +115,10 @@ let stage = new Clutter.Stage();
stage.set_size(BIT_WIDTH * 3, BIT_HEIGHT * 3);
stage.set_user_resizable(true);
-let player = new ClutterGst.Playback();
-player.set_filename(ARGV[0]);
-player.set_audio_volume(0.25);
-//let player = new ClutterGst.Camera();
+//let player = new ClutterGst.Playback();
+//player.set_filename(ARGV[0]);
+//player.set_audio_volume(0.25);
+let player = new ClutterGst.Camera();
let pieces = new Pieces(ROWS, COLUMNS);
for (let i = 0; i < ROWS; i++) {
diff --git a/examples/video-sink-navigation.c b/examples/video-sink-navigation.c
index 8cf5321..e4d3cc9 100644
--- a/examples/video-sink-navigation.c
+++ b/examples/video-sink-navigation.c
@@ -28,43 +28,6 @@
#include <clutter-gst/clutter-gst.h>
-void
-size_change (ClutterActor *actor,
- gint width,
- gint height,
- gpointer user_data)
-{
- 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[])
{
@@ -99,11 +62,9 @@ main (int argc, char *argv[])
timeline = clutter_timeline_new (1000);
g_object_set(timeline, "loop", TRUE, NULL);
- actor = g_object_new (CLUTTER_GST_TYPE_ACTOR, NULL);
-
- g_signal_connect (actor,
- "size-change",
- G_CALLBACK (size_change), NULL);
+ actor = g_object_new (CLUTTER_TYPE_ACTOR,
+ "content", clutter_gst_content_new (),
+ NULL);
/* Set up pipeline */
pipeline = GST_PIPELINE(gst_pipeline_new (NULL));
@@ -113,13 +74,13 @@ main (int argc, char *argv[])
test = gst_element_factory_make ("navigationtest", NULL);
colorspace = gst_element_factory_make ("videoconvert", NULL);
- sink = gst_element_factory_make ("cluttersink", NULL);
- g_object_set (sink, "actor", actor, NULL);
// g_object_set (src , "pattern", 10, NULL);
gst_bin_add_many (GST_BIN (pipeline), src, filter, test, colorspace, sink, NULL);
- gst_element_link_many (src, filter, test, colorspace, sink, NULL);
+ gst_element_link_many (src, filter, test, colorspace,
+ GST_ELEMENT (clutter_gst_content_get_sink (CLUTTER_GST_CONTENT (clutter_actor_get_content (actor)))),
+ NULL);
gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_PLAYING);
/* Resize with the window */
diff --git a/examples/video-sink.c b/examples/video-sink.c
index 9fc7ab6..7389a4d 100644
--- a/examples/video-sink.c
+++ b/examples/video-sink.c
@@ -96,15 +96,17 @@ main (int argc, char *argv[])
timeline = clutter_timeline_new (1000);
g_object_set(timeline, "loop", TRUE, NULL);
- actor = g_object_new (CLUTTER_GST_TYPE_ACTOR, NULL);
-
- /* Set up pipeline */
player = clutter_gst_playback_new ();
- pipeline = clutter_gst_player_get_pipeline (CLUTTER_GST_PLAYER (player));
-
+ actor = g_object_new (CLUTTER_TYPE_ACTOR,
+ "content", g_object_new (CLUTTER_GST_TYPE_CONTENT,
+ "player", player, NULL),
+ NULL);
g_signal_connect (player, "size-change",
G_CALLBACK (size_change), actor);
+ /* Set up pipeline */
+ pipeline = clutter_gst_player_get_pipeline (CLUTTER_GST_PLAYER (player));
+
src = gst_element_factory_make ("videotestsrc", NULL);
warp = gst_element_factory_make ("warptv", NULL);
bin = gst_bin_new ("video-test-source");