From e02d8c7a3a140fb9f607ed14f8f233843b09d757 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 20 Oct 2011 12:11:45 +0200 Subject: port to GStreamer 1.0 Contributions from: Alban Browaeys --- clutter-gst.pc.in | 2 +- clutter-gst/Makefile.am | 16 +- clutter-gst/clutter-gst-auto-video-sink.c | 212 +++++++++------------ clutter-gst/clutter-gst-auto-video-sink.h | 55 +++--- clutter-gst/clutter-gst-player.c | 23 ++- clutter-gst/clutter-gst-plugin.c | 2 +- clutter-gst/clutter-gst-private.h | 3 + clutter-gst/clutter-gst-util.c | 21 +++ clutter-gst/clutter-gst-video-sink.c | 300 +++++++++++++++--------------- clutter-gst/clutter-gst-video-sink.h | 5 + clutter-gst/clutter-gst-video-texture.c | 11 +- configure.ac | 11 +- tests/test-alpha.c | 11 +- tests/test-rgb-upload.c | 23 +-- tests/test-yuv-upload.c | 14 +- 15 files changed, 349 insertions(+), 360 deletions(-) diff --git a/clutter-gst.pc.in b/clutter-gst.pc.in index 9f2ec22..413666b 100644 --- a/clutter-gst.pc.in +++ b/clutter-gst.pc.in @@ -8,5 +8,5 @@ Description: Clutter GStreamer integration Version: @VERSION@ Libs: -L${libdir} -lclutter-gst-@CLUTTER_GST_MAJORMINOR@ Cflags: -I${includedir}/clutter-@CLUTTER_API_VERSION@ -Requires: clutter-@CLUTTER_API_VERSION@ >= 1.3.12 gstreamer-0.10 gstreamer-base-0.10 gstreamer-plugins-base-0.10 +Requires: clutter-@CLUTTER_API_VERSION@ >= 1.3.12 gstreamer-1.0 gstreamer-base-1.0 gstreamer-plugins-base-1.0 Requires.private: gio-2.0 diff --git a/clutter-gst/Makefile.am b/clutter-gst/Makefile.am index 95922f8..f25640f 100644 --- a/clutter-gst/Makefile.am +++ b/clutter-gst/Makefile.am @@ -127,24 +127,24 @@ ClutterGst-@CLUTTER_GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libclutter-gs --namespace ClutterGst --nsversion=@CLUTTER_GST_API_VERSION@ \ $(INCLUDES) \ $(AM_CPPFLAGS) \ + -D GST_USE_UNSTABLE_API \ --quiet --warn-all \ --add-include-path=$(srcdir) --add-include=path=. \ --c-include="clutter-gst/clutter-gst.h" \ --include=GObject-2.0 \ --include=Clutter-1.0 \ - --include=Gst-0.10 \ - --include=GstBase-0.10 \ - --include=GstInterfaces-0.10 \ - --include=GstVideo-0.10 \ - --include=GstAudio-0.10 \ + --include=Gst-1.0 \ + --include=GstBase-1.0 \ + --include=GstVideo-1.0 \ + --include=GstAudio-1.0 \ --add-init-section="clutter_gst_init(0,NULL);" \ - --library=clutter-gst-@CLUTTER_GST_API_VERSION@ \ + --library=libclutter-gst-@CLUTTER_GST_API_VERSION@.la \ --libtool="$(top_builddir)/libtool" \ --output $@ \ --pkg gobject-2.0 \ --pkg clutter-1.0 \ - --pkg gstreamer-0.10 \ - --pkg gstreamer-base-0.10 \ + --pkg gstreamer-1.0 \ + --pkg gstreamer-base-1.0 \ --pkg-export clutter-gst-@CLUTTER_GST_API_VERSION@ \ $(cluttergstheaders_HEADERS) \ $(source_c) diff --git a/clutter-gst/clutter-gst-auto-video-sink.c b/clutter-gst/clutter-gst-auto-video-sink.c index 61d0d1c..83a6410 100644 --- a/clutter-gst/clutter-gst-auto-video-sink.c +++ b/clutter-gst/clutter-gst-auto-video-sink.c @@ -38,13 +38,6 @@ GST_DEBUG_CATEGORY_EXTERN (clutter_gst_auto_video_sink_debug); #define GST_CAT_DEFAULT clutter_gst_auto_video_sink_debug -static GstElementDetails clutter_gst_auto_video_sink_details = { - "Auto Clutter Sink", - "Sink/Video", - "Autoplug clutter capable video sinks", - "Josep Torra " -}; - static GstStaticPadTemplate sink_template_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, @@ -57,11 +50,12 @@ enum PROP_TEXTURE }; -GST_BOILERPLATE (ClutterGstAutoVideoSink, +G_DEFINE_TYPE (ClutterGstAutoVideoSink, clutter_gst_auto_video_sink, - GstBin, GST_TYPE_BIN); +#define parent_class clutter_gst_auto_video_sink_parent_class + typedef struct { const gchar *factory_name; @@ -85,7 +79,7 @@ _get_sink_caps (GstElement *sink) 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_get_caps (sinkpad); + caps = gst_pad_query_caps (sinkpad, NULL); } gst_object_unref (sinkpad); @@ -178,7 +172,7 @@ _create_element_with_pretty_name (ClutterGstAutoVideoSink *bin, GstElement *element; gchar *name, *marker; - marker = g_strdup (GST_PLUGIN_FEATURE (factory)->name); + 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")) @@ -226,7 +220,7 @@ _sinks_discover (ClutterGstAutoVideoSink *bin) GstCaps *caps = gst_caps_new_empty (); GList *factories, *item; - factories = gst_default_registry_feature_filter ( + factories = gst_registry_feature_filter (gst_registry_get(), (GstPluginFeatureFilter)_factory_filter, FALSE, bin); factories = g_list_sort (factories, (GCompareFunc)_factories_compare_ranks); @@ -238,7 +232,8 @@ _sinks_discover (ClutterGstAutoVideoSink *bin) if ((el = _create_element_with_pretty_name (bin, f))) { - GST_DEBUG_OBJECT (bin, "Testing %s", GST_PLUGIN_FEATURE (f)->name); + GST_DEBUG_OBJECT (bin, "Testing %s", gst_plugin_feature_get_name( + GST_PLUGIN_FEATURE (f))); /* Check for a texture property with CLUTTER_TYPE_TEXTURE type */ if (!_is_clutter_sink (el)) @@ -249,12 +244,11 @@ _sinks_discover (ClutterGstAutoVideoSink *bin) se = _sink_element_create (el); if (se) { - GstCaps *caps_union = gst_caps_union (caps, se->caps); - gst_caps_unref (caps); + 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 (f)->name, se->caps); + gst_plugin_feature_get_name(GST_PLUGIN_FEATURE (f)), se->caps); } else { @@ -324,8 +318,9 @@ clutter_gst_auto_video_sink_do_async_start (ClutterGstAutoVideoSink *bin) bin->async_pending = TRUE; GST_INFO_OBJECT (bin, "Sending async_start message"); - message = gst_message_new_async_start (GST_OBJECT_CAST (bin), FALSE); - GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (bin), message); + message = gst_message_new_async_start (GST_OBJECT_CAST (bin)); + GST_BIN_CLASS (parent_class)->handle_message ( + GST_BIN_CAST (bin), message); } static void @@ -336,9 +331,9 @@ clutter_gst_auto_video_sink_do_async_done (ClutterGstAutoVideoSink *bin) if (bin->async_pending) { GST_INFO_OBJECT (bin, "Sending async_done message"); - message = gst_message_new_async_done (GST_OBJECT_CAST (bin)); - GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (bin), - 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; } @@ -405,27 +400,18 @@ beach: return ret; } -static void -clutter_gst_auto_video_sink_sink_pad_blocked_cb (GstPad *pad, gboolean blocked, +static GstPadProbeReturn +clutter_gst_auto_video_sink_sink_pad_blocked_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data) { ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK_CAST (user_data); GstCaps *caps = NULL; - /* In case the pad is not blocked we should not do anything but return */ - if (!blocked) - { - GST_DEBUG_OBJECT (bin, "pad successfully unblocked"); - return; - } - - CLUTTER_GST_AUTO_VIDEO_SINK_LOCK (bin); - /* This only occurs when our bin is first initialised || stream changes */ if (G_UNLIKELY (!bin->setup)) { - caps = gst_pad_peer_get_caps_reffed (bin->sink_pad); + caps = gst_pad_peer_query_caps (bin->sink_pad, NULL); if (G_UNLIKELY (!caps)) { @@ -459,56 +445,14 @@ beach: { gst_caps_unref (caps); } - gst_pad_set_blocked_async (bin->sink_block_pad, FALSE, - clutter_gst_auto_video_sink_sink_pad_blocked_cb, - bin); - CLUTTER_GST_AUTO_VIDEO_SINK_UNLOCK (bin); - return; -} - -static gboolean -clutter_gst_auto_video_sink_set_caps (GstPad *pad, GstCaps *caps) -{ - ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK ( - gst_pad_get_parent (pad)); - gboolean ret = TRUE; - GstPad *target = NULL; - - GST_DEBUG_OBJECT (pad, "Setting caps: %" GST_PTR_FORMAT, caps); - - target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (bin->sink_pad)); - - CLUTTER_GST_AUTO_VIDEO_SINK_LOCK (bin); - - if (target && gst_pad_accept_caps (target, caps)) - { - GST_DEBUG_OBJECT (pad, "Target accepts caps"); - ret = bin->sink_setcaps (pad, caps); - CLUTTER_GST_AUTO_VIDEO_SINK_UNLOCK (bin); - goto out; - } - - GST_DEBUG_OBJECT (pad, "Target did not accept caps"); - - bin->setup = FALSE; - gst_pad_set_blocked_async (bin->sink_block_pad, TRUE, - clutter_gst_auto_video_sink_sink_pad_blocked_cb, - bin); - CLUTTER_GST_AUTO_VIDEO_SINK_UNLOCK (bin); - -out: - if (target) - gst_object_unref (target); - gst_object_unref (bin); - return ret; + bin->sink_block_id = 0; + return GST_PAD_PROBE_REMOVE; } static GstCaps * -clutter_gst_auto_video_sink_get_caps (GstPad *pad) +clutter_gst_auto_video_sink_get_caps (ClutterGstAutoVideoSink *bin) { GstCaps *ret; - ClutterGstAutoVideoSink *bin = CLUTTER_GST_AUTO_VIDEO_SINK ( - gst_pad_get_parent (pad)); if (bin->video_caps) { @@ -519,15 +463,14 @@ clutter_gst_auto_video_sink_get_caps (GstPad *pad) ret = gst_static_pad_template_get_caps (&sink_template_factory); } - gst_object_unref (bin); return ret; } static gboolean -clutter_gst_auto_video_sink_accept_caps (GstPad *pad, GstCaps *caps) +clutter_gst_auto_video_sink_accept_caps (ClutterGstAutoVideoSink *bin, GstCaps *caps) { gboolean ret = FALSE; - GstCaps *allowed_caps = clutter_gst_auto_video_sink_get_caps (pad); + GstCaps *allowed_caps = clutter_gst_auto_video_sink_get_caps (bin); if (allowed_caps) { @@ -538,7 +481,7 @@ clutter_gst_auto_video_sink_accept_caps (GstPad *pad, GstCaps *caps) if (!gst_caps_is_empty (result)) ret = TRUE; - gst_caps_unref (result); + caps = result; } gst_caps_unref (allowed_caps); @@ -546,6 +489,43 @@ clutter_gst_auto_video_sink_accept_caps (GstPad *pad, GstCaps *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: + { + 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; + } + 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) @@ -564,10 +544,11 @@ clutter_gst_auto_video_sink_change_state (GstElement *element, /* 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"); - gst_pad_set_blocked_async ( - bin->sink_block_pad, TRUE, - clutter_gst_auto_video_sink_sink_pad_blocked_cb, - bin); + + 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); @@ -608,10 +589,10 @@ clutter_gst_auto_video_sink_change_state (GstElement *element, CLUTTER_GST_AUTO_VIDEO_SINK_LOCK (bin); /* Unblock pad */ - gst_pad_set_blocked_async ( - bin->sink_block_pad, FALSE, - clutter_gst_auto_video_sink_sink_pad_blocked_cb, - bin); + 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); @@ -668,7 +649,7 @@ clutter_gst_auto_video_sink_dispose (GObject *object) bin->texture = NULL; - GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); + G_OBJECT_CLASS (parent_class)->dispose((GObject *) object); } static void @@ -738,23 +719,11 @@ clutter_gst_auto_video_sink_get_property (GObject *object, } } -static void -clutter_gst_auto_video_sink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template_factory)); - - gst_element_class_set_details (element_class, - &clutter_gst_auto_video_sink_details); -} - static void clutter_gst_auto_video_sink_class_init (ClutterGstAutoVideoSinkClass *klass) { GObjectClass *oclass = G_OBJECT_CLASS (klass); - GstElementClass *gstelement_class; + GstElementClass *gstelement_class = GST_ELEMENT_CLASS(klass); GParamSpec *pspec; oclass->dispose = clutter_gst_auto_video_sink_dispose; @@ -762,6 +731,15 @@ clutter_gst_auto_video_sink_class_init (ClutterGstAutoVideoSinkClass *klass) 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_details_simple (gstelement_class, + "Auto Clutter Sink", + "Sink/Video", + "Autoplug clutter capable video sinks", + "Josep Torra "); + /** * ClutterGstAutoVideoSink:texture: * @@ -778,24 +756,22 @@ clutter_gst_auto_video_sink_class_init (ClutterGstAutoVideoSinkClass *klass) g_object_class_install_property (oclass, PROP_TEXTURE, pspec); - gstelement_class = (GstElementClass *)klass; gstelement_class->change_state = GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_change_state); } static void -clutter_gst_auto_video_sink_init (ClutterGstAutoVideoSink *bin, - ClutterGstAutoVideoSinkClass *g_class) +clutter_gst_auto_video_sink_init (ClutterGstAutoVideoSink *bin) { GstPad *proxypad; GstPadTemplate *template; + GValue val = {0, }; bin->setup = FALSE; bin->texture = NULL; /* Create a ghost pad with no target at first */ - template = gst_static_pad_template_get ( - &sink_template_factory); + 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); @@ -808,32 +784,26 @@ clutter_gst_auto_video_sink_init (ClutterGstAutoVideoSink *bin, GstIterator *it = gst_pad_iterate_internal_links (bin->sink_pad); if (G_UNLIKELY (!it || gst_iterator_next (it, - (gpointer) & proxypad) != + &val) != GST_ITERATOR_OK || - proxypad == NULL)) + 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)); } bin->sink_block_pad = proxypad; - bin->sink_setcaps = GST_PAD_SETCAPSFUNC (bin->sink_pad); - gst_pad_set_setcaps_function (bin->sink_pad, - GST_DEBUG_FUNCPTR ( - clutter_gst_auto_video_sink_set_caps)); - gst_pad_set_getcaps_function (bin->sink_pad, + gst_pad_set_query_function (bin->sink_pad, GST_DEBUG_FUNCPTR ( - clutter_gst_auto_video_sink_get_caps)); - gst_pad_set_acceptcaps_function (bin->sink_pad, - GST_DEBUG_FUNCPTR ( - clutter_gst_auto_video_sink_accept_caps)); + 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_IS_SINK); + GST_OBJECT_FLAG_SET (GST_OBJECT (bin), GST_ELEMENT_FLAG_SINK); bin->lock = g_mutex_new (); return; } diff --git a/clutter-gst/clutter-gst-auto-video-sink.h b/clutter-gst/clutter-gst-auto-video-sink.h index 716728f..bcee56d 100644 --- a/clutter-gst/clutter-gst-auto-video-sink.h +++ b/clutter-gst/clutter-gst-auto-video-sink.h @@ -1,29 +1,29 @@ /* - * Clutter-GStreamer. - * - * GStreamer integration library for Clutter. - * - * clutter-gst-auto-video-sink.c - GStreamer Auto Clutter Video Sink bin. - * - * Authored by Josep Torra - * - * 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. - */ + * Clutter-GStreamer. + * + * GStreamer integration library for Clutter. + * + * clutter-gst-auto-video-sink.c - GStreamer Auto Clutter Video Sink bin. + * + * Authored by Josep Torra + * + * 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. + */ #ifndef __CLUTTER_GST_AUTO_VIDEO_SINK_H__ #define __CLUTTER_GST_AUTO_VIDEO_SINK_H__ @@ -32,7 +32,8 @@ #include G_BEGIN_DECLS -#define CLUTTER_GST_TYPE_AUTO_VIDEO_SINK clutter_gst_auto_video_sink_get_type() + +#define CLUTTER_GST_TYPE_AUTO_VIDEO_SINK (clutter_gst_auto_video_sink_get_type()) #define CLUTTER_GST_AUTO_VIDEO_SINK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), \ @@ -86,7 +87,7 @@ struct _ClutterGstAutoVideoSink GstPad *sink_pad; GstPad *sink_block_pad; - GstPadSetCapsFunction sink_setcaps; + guint sink_block_id; GstElement *child; diff --git a/clutter-gst/clutter-gst-player.c b/clutter-gst/clutter-gst-player.c index e156032..341c861 100644 --- a/clutter-gst/clutter-gst-player.c +++ b/clutter-gst/clutter-gst-player.c @@ -3,7 +3,7 @@ * * GStreamer integration library for Clutter. * - * clutter-gst-player.c - Wrap some convenience functions around playbin2 + * clutter-gst-player.c - Wrap some convenience functions around playbin * * Authored By Damien Lespiau * Lionel Landwerlin @@ -49,7 +49,7 @@ #include #include -#include +#include #include "clutter-gst-debug.h" #include "clutter-gst-enum-types.h" @@ -714,7 +714,7 @@ get_progress (ClutterGstPlayer *player) if (!priv->pipeline) return 0.0; - /* when hitting an error or after an EOS, playbin2 has some weird values when + /* when hitting an error or after an EOS, playbin has some weird values when * querying the duration and progress. We default to 0.0 on error and 1.0 on * EOS */ if (priv->in_error) @@ -729,7 +729,7 @@ get_progress (ClutterGstPlayer *player) return 1.0; } - /* When seeking, the progress returned by playbin2 is 0.0. We want that to be + /* When seeking, the progress returned by playbin is 0.0. We want that to be * the last known position instead as returning 0.0 will have some ugly * effects, say on a progress bar getting updated from the progress tick. */ if (priv->in_seek || priv->is_changing_uri) @@ -924,7 +924,7 @@ bus_message_error_cb (GstBus *bus, /* * This is what's intented in the EOS callback: - * - receive EOS from playbin 2 + * - receive EOS from playbin * - fire the EOS signal, the user can install a signal handler to loop the * video for instance. * - after having emitted the signal, check the state of the pipeline @@ -981,7 +981,7 @@ bus_message_buffering_cb (GstBus *bus, CLUTTER_GST_NOTE (BUFFERING, "buffer-fill: %.02f", priv->buffer_fill); - /* The playbin2 documentation says that we need to pause the pipeline + /* The playbin documentation says that we need to pause the pipeline * when there's not enough data yet. We try to limit the calls to * gst_element_set_state() */ gst_element_get_state (priv->pipeline, ¤t_state, NULL, 0); @@ -1054,12 +1054,11 @@ query_duration (ClutterGstPlayer *player) { ClutterGstPlayerPrivate *priv = PLAYER_GET_PRIVATE (player); gboolean success; - GstFormat format = GST_FORMAT_TIME; gint64 duration; gdouble new_duration, difference; success = gst_element_query_duration (priv->pipeline, - &format, + GST_FORMAT_TIME, &duration); if (G_UNLIKELY (success != TRUE)) return; @@ -1218,7 +1217,7 @@ on_volume_changed_main_context (gpointer data) return FALSE; } -/* playbin2 proxies the volume property change notification directly from +/* playbin proxies the volume property change notification directly from * the element having the "volume" property. This means this callback is * called from the thread that runs the element, potentially different from * the main thread */ @@ -1619,10 +1618,10 @@ get_pipeline (void) { GstElement *pipeline, *audio_sink; - pipeline = gst_element_factory_make ("playbin2", "pipeline"); + pipeline = gst_element_factory_make ("playbin", "pipeline"); if (!pipeline) { - g_critical ("Unable to create playbin2 element"); + g_critical ("Unable to create playbin element"); return NULL; } @@ -2074,7 +2073,7 @@ clutter_gst_player_init (ClutterGstPlayer *player) #if defined(CLUTTER_WINDOWING_X11) && defined (HAVE_HW_DECODER_SUPPORT) gst_bus_set_sync_handler (priv->bus, on_sync_message, - clutter_x11_get_default_display ()); + clutter_x11_get_default_display (), NULL); #endif gst_object_unref (GST_OBJECT (priv->bus)); diff --git a/clutter-gst/clutter-gst-plugin.c b/clutter-gst/clutter-gst-plugin.c index 74d04f9..9eabbaf 100644 --- a/clutter-gst/clutter-gst-plugin.c +++ b/clutter-gst/clutter-gst-plugin.c @@ -84,7 +84,7 @@ plugin_init (GstPlugin *plugin) GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, - "clutter", + clutter, "Elements to render to Clutter textures", plugin_init, VERSION, diff --git a/clutter-gst/clutter-gst-private.h b/clutter-gst/clutter-gst-private.h index 7d63899..a7e08e7 100644 --- a/clutter-gst/clutter-gst-private.h +++ b/clutter-gst/clutter-gst-private.h @@ -44,6 +44,9 @@ G_BEGIN_DECLS #define CLUTTER_GST_PARAM_READWRITE \ (G_PARAM_READABLE | G_PARAM_WRITABLE | CLUTTER_GST_PARAM_STATIC) +gboolean +_internal_plugin_init (GstPlugin *plugin); + G_END_DECLS #endif /* __CLUTTER_GST_PRIVATE_H__ */ diff --git a/clutter-gst/clutter-gst-util.c b/clutter-gst/clutter-gst-util.c index 9c858ec..4391372 100644 --- a/clutter-gst/clutter-gst-util.c +++ b/clutter-gst/clutter-gst-util.c @@ -103,6 +103,7 @@ #include #endif +#include "clutter-gst-private.h" #include "clutter-gst-debug.h" #include "clutter-gst-video-sink.h" #include "clutter-gst-util.h" @@ -143,6 +144,16 @@ clutter_gst_init (int *argc, #ifdef CLUTTER_GST_ENABLE_DEBUG _clutter_gst_debug_init(); #endif + gst_plugin_register_static (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "cluttersink", + "Element to render to Clutter textures", + _internal_plugin_init, + VERSION, + "LGPL", /* license */ + "clutter-gst", PACKAGE, + "http://www.clutter-project.org"); + clutter_gst_is_initialized = TRUE; @@ -213,6 +224,16 @@ clutter_gst_init_with_args (int *argc, #ifdef CLUTTER_GST_ENABLE_DEBUG _clutter_gst_debug_init (); #endif + gst_plugin_register_static (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "cluttersink", + "Element to render to Clutter textures", + _internal_plugin_init, + VERSION, + "LGPL", /* license */ + "clutter-gst", PACKAGE, + "http://www.clutter-project.org"); + clutter_gst_is_initialized = TRUE; diff --git a/clutter-gst/clutter-gst-video-sink.c b/clutter-gst/clutter-gst-video-sink.c index bb8317e..397fe84 100644 --- a/clutter-gst/clutter-gst-video-sink.c +++ b/clutter-gst/clutter-gst-video-sink.c @@ -57,16 +57,12 @@ #include #include #include -#include +#include #include #ifdef HAVE_HW_DECODER_SUPPORT #define GST_USE_UNSTABLE_API 1 -#include -#endif - -#if defined (CLUTTER_WINDOWING_X11) -#include +#include #endif #include @@ -116,19 +112,16 @@ static gchar *yv12_to_rgba_shader = \ FRAGMENT_SHADER_END "}"; -#define BASE_SINK_CAPS GST_VIDEO_CAPS_YUV("AYUV") ";" \ - GST_VIDEO_CAPS_YUV("YV12") ";" \ - GST_VIDEO_CAPS_YUV("I420") ";" \ - GST_VIDEO_CAPS_RGBA ";" \ - GST_VIDEO_CAPS_BGRA ";" \ - GST_VIDEO_CAPS_RGB ";" \ - GST_VIDEO_CAPS_BGR +#define BASE_SINK_CAPS "{ AYUV," \ + "YV12," \ + "I420," \ + "RGBA," \ + "BGRA," \ + "RGB," \ + "BGR }" -#ifdef HAVE_HW_DECODER_SUPPORT -#define SINK_CAPS GST_VIDEO_CAPS_SURFACE ", opengl = true;" BASE_SINK_CAPS -#else -#define SINK_CAPS BASE_SINK_CAPS -#endif + +#define SINK_CAPS GST_VIDEO_CAPS_MAKE(BASE_SINK_CAPS) static GstStaticPadTemplate sinktemplate_all = GST_STATIC_PAD_TEMPLATE ("sink", @@ -139,13 +132,6 @@ static GstStaticPadTemplate sinktemplate_all GST_DEBUG_CATEGORY_STATIC (clutter_gst_video_sink_debug); #define GST_CAT_DEFAULT clutter_gst_video_sink_debug -static GstElementDetails clutter_gst_video_sink_details = - GST_ELEMENT_DETAILS ("Clutter video sink", - "Sink/Video", - "Sends video data from a GStreamer pipeline to a Clutter texture", - "Jonathan Matthew , " - "Matthew Allum "); enum { @@ -246,14 +232,13 @@ struct _ClutterGstVideoSinkPrivate #endif }; -#define GstNavigationClass GstNavigationInterface -GST_BOILERPLATE_WITH_INTERFACE (ClutterGstVideoSink, - clutter_gst_video_sink, - GstBaseSink, - GST_TYPE_BASE_SINK, - GstNavigation, - GST_TYPE_NAVIGATION, - clutter_gst_navigation); +static void +clutter_gst_navigation_interface_init (GstNavigationInterface *iface); + +#define clutter_gst_video_sink_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (ClutterGstVideoSink, clutter_gst_video_sink, GST_TYPE_BASE_SINK, + G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, + clutter_gst_navigation_interface_init)); static void clutter_gst_video_sink_set_texture (ClutterGstVideoSink *sink, ClutterTexture *texture); @@ -367,13 +352,10 @@ clutter_gst_parse_caps (GstCaps *caps, { ClutterGstVideoSinkPrivate *priv = sink->priv; GstCaps *intersection; - GstStructure *structure; - gboolean ret; - const GValue *fps; - const GValue *par; + GstVideoInfo vinfo; + gint fps_n, fps_d; + gint par_n, par_d; gint width, height; - guint32 fourcc; - int red_mask, blue_mask; ClutterGstVideoFormat format; gboolean bgr; ClutterGstRenderer *renderer; @@ -384,56 +366,49 @@ clutter_gst_parse_caps (GstCaps *caps, gst_caps_unref (intersection); - structure = gst_caps_get_structure (caps, 0); - - ret = gst_structure_get_int (structure, "width", &width); - ret &= gst_structure_get_int (structure, "height", &height); - fps = gst_structure_get_value (structure, "framerate"); - ret &= (fps != NULL); - - par = gst_structure_get_value (structure, "pixel-aspect-ratio"); - - if (!ret) - return FALSE; - - ret = gst_structure_get_fourcc (structure, "format", &fourcc); - if (ret && (fourcc == GST_MAKE_FOURCC ('Y', 'V', '1', '2'))) - { - format = CLUTTER_GST_YV12; - } - else if (ret && (fourcc == GST_MAKE_FOURCC ('I', '4', '2', '0'))) - { - format = CLUTTER_GST_I420; - } - else if (ret && (fourcc == GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'))) - { - format = CLUTTER_GST_AYUV; - bgr = FALSE; - } -#ifdef HAVE_HW_DECODER_SUPPORT - else if (gst_structure_has_name (structure, GST_VIDEO_CAPS_SURFACE)) - { - format = CLUTTER_GST_SURFACE; - } -#endif - else - { - guint32 mask; - gst_structure_get_int (structure, "red_mask", &red_mask); - gst_structure_get_int (structure, "blue_mask", &blue_mask); - - mask = red_mask | blue_mask; - if (mask < 0x1000000) - { - format = CLUTTER_GST_RGB24; - bgr = ((guint) red_mask == 0xff0000) ? FALSE : TRUE; - } - else - { - format = CLUTTER_GST_RGB32; - bgr = ((guint) red_mask == 0xff000000) ? FALSE : TRUE; - } - } + if (!gst_video_info_from_caps (&vinfo, caps)) + goto unknown_format; + + width = vinfo.width; + height = vinfo.height; + + /* We dont yet use fps or pixel aspect into but handy to have */ + fps_n = vinfo.fps_n; + fps_d = vinfo.fps_d; + + par_n = vinfo.par_n; + par_d = vinfo.par_d; + + switch (vinfo.finfo->format) { + case GST_VIDEO_FORMAT_YV12: + format = CLUTTER_GST_YV12; + break; + case GST_VIDEO_FORMAT_I420: + format = CLUTTER_GST_I420; + break; + case GST_VIDEO_FORMAT_AYUV: + format = CLUTTER_GST_AYUV; + bgr = FALSE; + break; + case GST_VIDEO_FORMAT_RGB: + format = CLUTTER_GST_RGB24; + bgr = FALSE; + break; + case GST_VIDEO_FORMAT_BGR: + format = CLUTTER_GST_RGB24; + bgr = TRUE; + break; + case GST_VIDEO_FORMAT_RGBA: + format = CLUTTER_GST_RGB32; + bgr = FALSE; + break; + case GST_VIDEO_FORMAT_BGRA: + format = CLUTTER_GST_RGB32; + bgr = TRUE; + break; + default: + break; + } /* find a renderer that can display our format */ renderer = clutter_gst_find_renderer_by_format (sink, format); @@ -443,27 +418,24 @@ clutter_gst_parse_caps (GstCaps *caps, return FALSE; } + GST_INFO_OBJECT (sink, "using the %s renderer", renderer->name); + if (save) { priv->width = width; priv->height = height; /* We dont yet use fps or pixel aspect into but handy to have */ - priv->fps_n = gst_value_get_fraction_numerator (fps); - priv->fps_d = gst_value_get_fraction_denominator (fps); + priv->fps_n = fps_n; + priv->fps_d = fps_d; - if (par) - { - priv->par_n = gst_value_get_fraction_numerator (par); - priv->par_d = gst_value_get_fraction_denominator (par); + priv->par_n = par_n; + priv->par_d = par_d; - /* If we happen to use a ClutterGstVideoTexture, now is to good time - * to instruct it about the pixel aspect ratio so we can have a - * correct natural width/height */ - ensure_texture_pixel_aspect_ratio (sink); - } - else - priv->par_n = priv->par_d = 1; + /* If we happen to use a ClutterGstVideoTexture, now is to good time + * to instruct it about the pixel aspect ratio so we can have a + * correct natural width/height */ + ensure_texture_pixel_aspect_ratio (sink); priv->format = format; priv->bgr = bgr; @@ -473,6 +445,12 @@ clutter_gst_parse_caps (GstCaps *caps, } return TRUE; + + unknown_format: + { + GST_WARNING_OBJECT (sink, "Could not figure format of input caps"); + return FALSE; + } } static gboolean @@ -534,7 +512,8 @@ clutter_gst_source_dispatch (GSource *source, if (G_UNLIKELY (gst_source->has_new_caps)) { - GstCaps *caps = GST_BUFFER_CAPS (gst_source->buffer); + GstCaps *caps = gst_pad_get_current_caps( + GST_BASE_SINK_PAD((GST_BASE_SINK(gst_source->sink)))); if (priv->renderer) priv->renderer->deinit (gst_source->sink); @@ -783,19 +762,24 @@ clutter_gst_rgb24_upload (ClutterGstVideoSink *sink, ClutterGstVideoSinkPrivate *priv = sink->priv; CoglPixelFormat format; CoglHandle tex; + GstMapInfo info; if (priv->bgr) format = COGL_PIXEL_FORMAT_BGR_888; else format = COGL_PIXEL_FORMAT_RGB_888; + gst_buffer_map (buffer, &info, GST_MAP_READ); + tex = cogl_texture_new_from_data (priv->width, priv->height, CLUTTER_GST_TEXTURE_FLAGS, format, format, GST_ROUND_UP_4 (3 * priv->width), - GST_BUFFER_DATA (buffer)); + info.data); + + gst_buffer_unmap (buffer, &info); _create_paint_material (sink, tex, @@ -808,7 +792,7 @@ static ClutterGstRenderer rgb24_renderer = "RGB 24", CLUTTER_GST_RGB24, 0, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR), + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE("{ RGB, BGR }")), clutter_gst_rgb_init, clutter_gst_dummy_deinit, clutter_gst_rgb24_upload, @@ -825,6 +809,9 @@ clutter_gst_rgb32_upload (ClutterGstVideoSink *sink, ClutterGstVideoSinkPrivate *priv = sink->priv; CoglPixelFormat format; CoglHandle tex; + GstMapInfo info; + + gst_buffer_map (buffer, &info, GST_MAP_READ); if (priv->bgr) format = COGL_PIXEL_FORMAT_BGRA_8888; @@ -837,7 +824,9 @@ clutter_gst_rgb32_upload (ClutterGstVideoSink *sink, format, format, GST_ROUND_UP_4 (4 * priv->width), - GST_BUFFER_DATA (buffer)); + info.data); + + gst_buffer_unmap (buffer, &info); _create_paint_material (sink, tex, @@ -850,7 +839,7 @@ static ClutterGstRenderer rgb32_renderer = "RGB 32", CLUTTER_GST_RGB32, 0, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA), + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE("{ RGBA, BGRA }")), clutter_gst_rgb_init, clutter_gst_dummy_deinit, clutter_gst_rgb32_upload, @@ -870,6 +859,9 @@ clutter_gst_yv12_upload (ClutterGstVideoSink *sink, gint y_row_stride = GST_ROUND_UP_4 (priv->width); gint uv_row_stride = GST_ROUND_UP_4 (priv->width / 2); CoglHandle y_tex, u_tex, v_tex; + GstMapInfo info; + + gst_buffer_map (buffer, &info, GST_MAP_READ); y_tex = cogl_texture_new_from_data (priv->width, priv->height, @@ -877,7 +869,7 @@ clutter_gst_yv12_upload (ClutterGstVideoSink *sink, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, y_row_stride, - GST_BUFFER_DATA (buffer)); + info.data); u_tex = cogl_texture_new_from_data (priv->width / 2, priv->height / 2, @@ -885,7 +877,7 @@ clutter_gst_yv12_upload (ClutterGstVideoSink *sink, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, uv_row_stride, - GST_BUFFER_DATA (buffer) + + info.data + (y_row_stride * priv->height)); v_tex = cogl_texture_new_from_data (priv->width / 2, @@ -894,10 +886,12 @@ clutter_gst_yv12_upload (ClutterGstVideoSink *sink, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, uv_row_stride, - GST_BUFFER_DATA (buffer) + info.data + (y_row_stride * priv->height) + (uv_row_stride * priv->height / 2)); + gst_buffer_unmap (buffer, &info); + _create_paint_material (sink, y_tex, u_tex, v_tex); } @@ -913,7 +907,7 @@ static ClutterGstRenderer yv12_glsl_renderer = "YV12 glsl", CLUTTER_GST_YV12, CLUTTER_GST_GLSL | CLUTTER_GST_MULTI_TEXTURE, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("YV12")), + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("YV12")), clutter_gst_yv12_glsl_init, clutter_gst_dummy_deinit, clutter_gst_yv12_upload, @@ -942,7 +936,7 @@ static ClutterGstRenderer yv12_fp_renderer = "YV12 fp", CLUTTER_GST_YV12, CLUTTER_GST_FP | CLUTTER_GST_MULTI_TEXTURE, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("YV12")), + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("YV12")), clutter_gst_yv12_fp_init, clutter_gst_dummy_deinit, clutter_gst_yv12_upload, @@ -967,7 +961,7 @@ static ClutterGstRenderer i420_glsl_renderer = "I420 glsl", CLUTTER_GST_I420, CLUTTER_GST_GLSL | CLUTTER_GST_MULTI_TEXTURE, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")), + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")), clutter_gst_i420_glsl_init, clutter_gst_dummy_deinit, clutter_gst_yv12_upload, @@ -997,7 +991,7 @@ static ClutterGstRenderer i420_fp_renderer = "I420 fp", CLUTTER_GST_I420, CLUTTER_GST_FP | CLUTTER_GST_MULTI_TEXTURE, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")), + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")), clutter_gst_i420_fp_init, clutter_gst_dummy_deinit, clutter_gst_yv12_upload, @@ -1023,14 +1017,21 @@ clutter_gst_ayuv_upload (ClutterGstVideoSink *sink, GstBuffer *buffer) { ClutterGstVideoSinkPrivate *priv = sink->priv; - CoglHandle tex = + CoglHandle tex; + GstMapInfo info; + + gst_buffer_map (buffer, &info, GST_MAP_READ); + + tex = cogl_texture_new_from_data (priv->width, priv->height, CLUTTER_GST_TEXTURE_FLAGS, COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_RGBA_8888, GST_ROUND_UP_4 (4 * priv->width), - GST_BUFFER_DATA (buffer)); + info.data); + + gst_buffer_unmap (buffer, &info); _create_paint_material (sink, tex, @@ -1043,7 +1044,7 @@ static ClutterGstRenderer ayuv_glsl_renderer = "AYUV glsl", CLUTTER_GST_AYUV, CLUTTER_GST_GLSL, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV")), + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("AYUV")), clutter_gst_ayuv_glsl_init, clutter_gst_dummy_deinit, clutter_gst_ayuv_upload, @@ -1089,10 +1090,9 @@ clutter_gst_hw_upload (ClutterGstVideoSink *sink, GstBuffer *buffer) { ClutterGstVideoSinkPrivate *priv = sink->priv; - GstSurfaceBuffer *surface; + GstSurfaceMeta *surface = gst_buffer_get_surface_meta (buffer); - g_return_if_fail (GST_IS_SURFACE_BUFFER (buffer)); - surface = GST_SURFACE_BUFFER (buffer); + g_return_if_fail (surface != NULL); if (G_UNLIKELY (priv->converter == NULL)) { CoglHandle tex; @@ -1107,11 +1107,11 @@ clutter_gst_hw_upload (ClutterGstVideoSink *sink, g_value_init (&value, G_TYPE_UINT); g_value_set_uint (&value, gl_texture); - priv->converter = gst_surface_buffer_create_converter (surface, "opengl", &value); + priv->converter = gst_surface_meta_create_converter (surface, "opengl", &value); g_return_if_fail (priv->converter); } - gst_surface_converter_upload (priv->converter, surface); + gst_surface_converter_upload (priv->converter, buffer); /* The texture is dirty, schedule a redraw */ clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->texture)); @@ -1122,7 +1122,7 @@ static ClutterGstRenderer hw_renderer = "HW surface", CLUTTER_GST_SURFACE, 0, - GST_STATIC_CAPS (GST_VIDEO_CAPS_SURFACE ", opengl=true"), + GST_STATIC_CAPS ("x-video/surface, opengl=true"), clutter_gst_hw_init, clutter_gst_hw_deinit, clutter_gst_hw_upload, @@ -1206,18 +1206,6 @@ clutter_gst_build_caps (GSList *renderers) return caps; } -static void -clutter_gst_video_sink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template - (element_class, - gst_static_pad_template_get (&sinktemplate_all)); - - gst_element_class_set_details (element_class, - &clutter_gst_video_sink_details); -} static gboolean navigation_event (ClutterActor *actor, @@ -1283,8 +1271,7 @@ navigation_event (ClutterActor *actor, } static void -clutter_gst_video_sink_init (ClutterGstVideoSink *sink, - ClutterGstVideoSinkClass *klass) +clutter_gst_video_sink_init (ClutterGstVideoSink *sink) { ClutterGstVideoSinkPrivate *priv; @@ -1335,7 +1322,7 @@ clutter_gst_video_sink_render (GstBaseSink *bsink, } static GstCaps * -clutter_gst_video_sink_get_caps (GstBaseSink *bsink) +clutter_gst_video_sink_get_caps (GstBaseSink *bsink, GstCaps *filter) { ClutterGstVideoSink *sink; @@ -1363,6 +1350,7 @@ clutter_gst_video_sink_set_caps (GstBaseSink *bsink, return TRUE; } + static void clutter_gst_video_sink_dispose (GObject *object) { @@ -1525,6 +1513,7 @@ static void clutter_gst_video_sink_class_init (ClutterGstVideoSinkClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); GstBaseSinkClass *gstbase_sink_class = GST_BASE_SINK_CLASS (klass); GParamSpec *pspec; @@ -1541,6 +1530,17 @@ clutter_gst_video_sink_class_init (ClutterGstVideoSinkClass *klass) gobject_class->dispose = clutter_gst_video_sink_dispose; gobject_class->finalize = clutter_gst_video_sink_finalize; + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&sinktemplate_all)); + + gst_element_class_set_details_simple (gstelement_class, + "Clutter video sink", + "Sink/Video", + "Sends video data from a GStreamer pipeline to a Clutter texture", + "Jonathan Matthew , " + "Matthew Allum "); + gstbase_sink_class->render = clutter_gst_video_sink_render; gstbase_sink_class->preroll = clutter_gst_video_sink_render; gstbase_sink_class->start = clutter_gst_video_sink_start; @@ -1624,16 +1624,24 @@ clutter_gst_navigation_send_event (GstNavigation *navigation, } } -static gboolean -clutter_gst_navigation_supported (ClutterGstVideoSink *object, GType type) -{ - g_assert (type == GST_TYPE_NAVIGATION); - return TRUE; -} - - static void clutter_gst_navigation_interface_init (GstNavigationInterface *iface) { iface->send_event = clutter_gst_navigation_send_event; } + +gboolean +_internal_plugin_init (GstPlugin *plugin) +{ + gboolean ret = gst_element_register (plugin, + "cluttersink", + GST_RANK_PRIMARY, + CLUTTER_GST_TYPE_VIDEO_SINK); + + GST_DEBUG_CATEGORY_INIT (clutter_gst_video_sink_debug, + "cluttersink", + 0, + "clutter video sink"); + + return ret; +} diff --git a/clutter-gst/clutter-gst-video-sink.h b/clutter-gst/clutter-gst-video-sink.h index e05fd4a..3a06804 100644 --- a/clutter-gst/clutter-gst-video-sink.h +++ b/clutter-gst/clutter-gst-video-sink.h @@ -37,6 +37,11 @@ #include #include +#if defined (CLUTTER_WINDOWING_X11) +#include +#endif + + G_BEGIN_DECLS #define CLUTTER_GST_TYPE_VIDEO_SINK clutter_gst_video_sink_get_type() diff --git a/clutter-gst/clutter-gst-video-texture.c b/clutter-gst/clutter-gst-video-texture.c index 7cd9114..11c55aa 100644 --- a/clutter-gst/clutter-gst-video-texture.c +++ b/clutter-gst/clutter-gst-video-texture.c @@ -554,17 +554,8 @@ setup_pipeline (ClutterGstVideoTexture *video_texture) return FALSE; } - video_sink = gst_element_factory_make ("autocluttersink", NULL); - if (!video_sink) - { - g_critical ("Unable to get autocluttersink"); - return FALSE; - } + video_sink = gst_element_factory_make ("cluttersink", NULL); - g_signal_connect (video_sink, - "element-added", - G_CALLBACK (on_autocluttersink_element_added), - video_texture); g_object_set (G_OBJECT (video_sink), "texture", CLUTTER_TEXTURE (video_texture), NULL); diff --git a/configure.ac b/configure.ac index b8b146e..209d7e8 100644 --- a/configure.ac +++ b/configure.ac @@ -80,8 +80,8 @@ AC_SUBST([CLUTTER_GST_RELEASE_STATUS], [clutter_gst_release_status]) # pkg-config requirements GLIB_REQ_VERSION=2.18.0 CLUTTER_REQ_VERSION=1.6.0 -GSTREAMER_REQ_VERSION=0.10.26 -GST_PLUGINS_BAD_REQ_VERSION=0.10.22.1 +GSTREAMER_REQ_VERSION=0.11.0 +GST_PLUGINS_BAD_REQ_VERSION=0.11.0 AC_SUBST(GLIB_REQ_VERSION) AC_SUBST(CLUTTER_REQ_VERSION) @@ -144,13 +144,12 @@ PKG_CHECK_MODULES(CLUTTER_GST, dnl ======================================================================== -GST_MAJORMINOR=0.10 +GST_MAJORMINOR=1.0 PKG_CHECK_MODULES(GST, [gstreamer-$GST_MAJORMINOR >= $GSTREAMER_REQ_VERSION gstreamer-plugins-base-$GST_MAJORMINOR gstreamer-base-$GST_MAJORMINOR - gstreamer-interfaces-$GST_MAJORMINOR gstreamer-video-$GST_MAJORMINOR gstreamer-audio-$GST_MAJORMINOR gstreamer-tag-$GST_MAJORMINOR]) @@ -160,7 +159,8 @@ PKG_CHECK_MODULES([PLUGIN], [clutter-1.0 >= $CLUTTER_REQ_VERSION gstreamer-$GST_MAJORMINOR >= $GSTREAMER_REQ_VERSION gstreamer-base-$GST_MAJORMINOR - gstreamer-interfaces-$GST_MAJORMINOR ]) + gstreamer-video-$GST_MAJORMINOR + gstreamer-audio-$GST_MAJORMINOR]) dnl define location of gstreamer plugin directory plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" @@ -285,6 +285,7 @@ GOBJECT_INTROSPECTION_CHECK([0.6.8]) dnl ======================================================================== AC_SUBST(GCC_FLAGS) +GST_CFLAGS="$GST_CFLAGS -DGST_USE_UNSTABLE_API" AC_SUBST(GST_CFLAGS) AC_SUBST(GST_LIBS) diff --git a/tests/test-alpha.c b/tests/test-alpha.c index 79786c9..238508e 100644 --- a/tests/test-alpha.c +++ b/tests/test-alpha.c @@ -171,9 +171,8 @@ main (int argc, char *argv[]) /* make videotestsrc spit the format we want */ if (g_strcmp0 (opt_fourcc, "RGB ") == 0) { - caps = gst_caps_new_simple ("video/x-raw-rgb", - "bpp", G_TYPE_INT, opt_bpp, - "depth", G_TYPE_INT, opt_depth, + caps = gst_caps_new_simple ("video/x-raw", + "format", G_TYPE_STRING, "RGB", "framerate", GST_TYPE_FRACTION, opt_framerate, 1, NULL); @@ -181,9 +180,9 @@ main (int argc, char *argv[]) } else { - caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, - parse_fourcc (opt_fourcc), + caps = gst_caps_new_simple ("video/x-raw", + "format", G_TYPE_STRING, + opt_fourcc, "framerate", GST_TYPE_FRACTION, opt_framerate, 1, NULL); diff --git a/tests/test-rgb-upload.c b/tests/test-rgb-upload.c index 57dde63..22f77c5 100644 --- a/tests/test-rgb-upload.c +++ b/tests/test-rgb-upload.c @@ -29,6 +29,7 @@ #include #include +#include #include static gint opt_framerate = 30; @@ -111,6 +112,7 @@ main (int argc, char *argv[]) GstElement *capsfilter; GstElement *sink; GstCaps *caps; + GstVideoFormat format; if (!g_thread_supported ()) g_thread_init (NULL); @@ -152,17 +154,16 @@ main (int argc, char *argv[]) sink = gst_element_factory_make ("cluttersink", NULL); g_object_set (sink, "texture", CLUTTER_TEXTURE (texture), NULL); - /* make videotestsrc spit the format we want */ - caps = gst_caps_new_simple ("video/x-raw-rgb", - "bpp", G_TYPE_INT, opt_bpp, - "depth", G_TYPE_INT, opt_depth, - "framerate", GST_TYPE_FRACTION, opt_framerate, 1, -#if 0 - "red_mask", G_TYPE_INT, 0xff000000, - "green_mask", G_TYPE_INT, 0x00ff0000, - "blue_mask", G_TYPE_INT, 0x0000ff00, -#endif - NULL); + format = gst_video_format_from_masks(opt_depth, opt_bpp, G_BIG_ENDIAN, + 0xff0000, + 0x00ff00, + 0x0000ff, + 0x00000000); + + caps = gst_caps_new_simple ("video/x-raw", + "format", G_TYPE_STRING, gst_video_format_to_string(format), + "framerate", GST_TYPE_FRACTION, opt_framerate, 1, + NULL); g_object_set (capsfilter, "caps", caps, NULL); g_printf ("%s: [caps] %s\n", __FILE__, gst_caps_to_string (caps)); diff --git a/tests/test-yuv-upload.c b/tests/test-yuv-upload.c index ca1ff18..a8ee1dd 100644 --- a/tests/test-yuv-upload.c +++ b/tests/test-yuv-upload.c @@ -52,15 +52,6 @@ static GOptionEntry options[] = { NULL } }; -static guint32 -parse_fourcc (const gchar *fourcc) -{ - if (strlen (fourcc) != 4) - return 0; - - return GST_STR_FOURCC (fourcc); -} - void size_change (ClutterTexture *texture, gint width, @@ -151,9 +142,8 @@ main (int argc, char *argv[]) g_object_set (sink, "texture", CLUTTER_TEXTURE (texture), NULL); /* make videotestsrc spit the format we want */ - caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, - parse_fourcc (opt_fourcc), + caps = gst_caps_new_simple ("video/x-raw", + "format", G_TYPE_STRING, opt_fourcc, "framerate", GST_TYPE_FRACTION, opt_framerate, 1, NULL); g_object_set (capsfilter, "caps", caps, NULL); -- cgit v1.2.3