diff options
author | Lionel Landwerlin <llandwerlin@gmail.com> | 2013-07-22 13:31:52 +0100 |
---|---|---|
committer | Lionel Landwerlin <llandwerlin@gmail.com> | 2013-07-22 13:31:52 +0100 |
commit | c23cdfc584b2051c2962673b9078a5c92d9b30a8 (patch) | |
tree | 583b4936958193560c7ac3f06d419a7e47ff8f84 | |
parent | 8b12180346be221cf25216f884d3a8b9f069141f (diff) | |
download | clutter-gst-c23cdfc584b2051c2962673b9078a5c92d9b30a8.tar.gz |
remove ClutterGstActor now replaced by ClutterGstContent
-rw-r--r-- | clutter-gst/Makefile.am | 2 | ||||
-rw-r--r-- | clutter-gst/clutter-gst-actor.c | 333 | ||||
-rw-r--r-- | clutter-gst/clutter-gst-actor.h | 120 | ||||
-rw-r--r-- | clutter-gst/clutter-gst-auto-video-sink.c | 930 | ||||
-rw-r--r-- | clutter-gst/clutter-gst-auto-video-sink.h | 19 | ||||
-rw-r--r-- | clutter-gst/clutter-gst-camera.h | 5 | ||||
-rw-r--r-- | clutter-gst/clutter-gst-crop.c | 1 | ||||
-rw-r--r-- | clutter-gst/clutter-gst-plugin.c | 12 | ||||
-rw-r--r-- | clutter-gst/clutter-gst.h | 1 | ||||
-rw-r--r-- | doc/reference/clutter-gst-docs.sgml | 3 | ||||
-rw-r--r-- | doc/reference/clutter-gst-sections.txt | 60 | ||||
-rw-r--r-- | examples/pieces.js | 12 | ||||
-rw-r--r-- | examples/video-sink-navigation.c | 51 | ||||
-rw-r--r-- | examples/video-sink.c | 12 |
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"); |