diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-12-16 09:56:00 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-12-16 09:59:42 +0100 |
commit | 2561bb8fa7d6dfd143024a81198cd047b1345d83 (patch) | |
tree | ee6d278428d3ffd1c19d20c50942f5f28862de7b /gst/autoconvert/gstautovideoconvert.c | |
parent | 7ae4aaaee6831b9c8bad3c25e99d735435a2a1e0 (diff) | |
download | gstreamer-plugins-bad-2561bb8fa7d6dfd143024a81198cd047b1345d83.tar.gz |
autoconvert: Rename autocolorspace to autovideoconvert
This doesn't just convert between color spaces.
Diffstat (limited to 'gst/autoconvert/gstautovideoconvert.c')
-rw-r--r-- | gst/autoconvert/gstautovideoconvert.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/gst/autoconvert/gstautovideoconvert.c b/gst/autoconvert/gstautovideoconvert.c new file mode 100644 index 000000000..4dba911d3 --- /dev/null +++ b/gst/autoconvert/gstautovideoconvert.c @@ -0,0 +1,248 @@ +/* GStreamer + * Copyright 2010 ST-Ericsson SA + * @author: Benjamin Gaignard <benjamin.gaignard@stericsson.com> + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + * test autovideoconvert: + * if rgb2bayer is present + * gst-launch videotestsrc num-buffers=2 ! "video/x-raw-rgb,width=100,height=100,framerate=10/1" ! autovideoconvert ! "video/x-raw-bayer,width=100,height=100,format=bggr,framerate=10/1" ! fakesink -v + * if bayer2rgb is present + * gst-launch videotestsrc num-buffers=2 ! "video/x-raw-bayer,width=100,height=100,format=bggr,framerate=10/1" ! autovideoconvert ! "video/x-raw-rgb,width=100,height=100,framerate=10/1" ! fakesink -v + * test with ffmpegvideoconvert + * gst-launch videotestsrc num-buffers=2 ! "video/x-raw-rgb,bpp=32,width=100,height=100,framerate=10/1" ! autovideoconvert ! "video/x-raw-rgb,bpp=16,width=100,height=100,framerate=10/1" ! fakesink -v + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include "gstautovideoconvert.h" + +GST_DEBUG_CATEGORY (autovideoconvert_debug); +#define GST_CAT_DEFAULT (autovideoconvert_debug) + +GStaticMutex factories_mutex = G_STATIC_MUTEX_INIT; +guint32 factories_cookie = 0; /* Cookie from last time when factories was updated */ +GList *factories = NULL; /* factories we can use for selecting elements */ + +/* element factory information */ +static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + + +static GstStateChangeReturn gst_auto_video_convert_change_state (GstElement * + element, GstStateChange transition); + +void gst_auto_video_convert_update_factory_list (GstAutoVideoConvert * + autovideoconvert); + +static gboolean +gst_auto_video_convert_element_filter (GstPluginFeature * feature, + GstAutoVideoConvert * autovideoconvert) +{ + const gchar *klass; + + /* we only care about element factories */ + if (G_UNLIKELY (!GST_IS_ELEMENT_FACTORY (feature))) + return FALSE; + + klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY_CAST (feature)); + /* only select color space converter */ + if (strstr (klass, "Filter") && + strstr (klass, "Converter") && strstr (klass, "Video")) { + GST_DEBUG_OBJECT (autovideoconvert, + "gst_auto_video_convert_element_filter found %s\n", + gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (feature))); + return TRUE; + } + return FALSE; +} + + +static GList * +gst_auto_video_convert_create_factory_list (GstAutoVideoConvert * + autovideoconvert) +{ + GList *result = NULL; + + /* get the feature list using the filter */ + result = gst_default_registry_feature_filter ((GstPluginFeatureFilter) + gst_auto_video_convert_element_filter, FALSE, autovideoconvert); + + /* sort on rank and name */ + result = g_list_sort (result, gst_plugin_feature_rank_compare_func); + + return result; +} + +void +gst_auto_video_convert_update_factory_list (GstAutoVideoConvert * + autovideoconvert) +{ + /* use a static mutex to protect factories list and factories cookie */ + g_static_mutex_lock (&factories_mutex); + + /* test if a factories list already exist or not */ + if (!factories) { + /* no factories list create it */ + factories_cookie = gst_default_registry_get_feature_list_cookie (); + factories = gst_auto_video_convert_create_factory_list (autovideoconvert); + } else { + /* a factories list exist but is it up to date? */ + if (factories_cookie != gst_default_registry_get_feature_list_cookie ()) { + /* we need to update the factories list */ + /* first free the old one */ + gst_plugin_feature_list_free (factories); + /* then create an updated one */ + factories_cookie = gst_default_registry_get_feature_list_cookie (); + factories = gst_auto_video_convert_create_factory_list (autovideoconvert); + } + } + + g_static_mutex_unlock (&factories_mutex); +} + +GST_BOILERPLATE (GstAutoVideoConvert, gst_auto_video_convert, GstBin, + GST_TYPE_BIN); + +static void +gst_auto_video_convert_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&srctemplate)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sinktemplate)); + + gst_element_class_set_details_simple (element_class, + "Select color space convertor based on caps", "Generic/Bin", + "Selects the right color space convertor based on the caps", + "Benjamin Gaignard <benjamin.gaignard@stericsson.com>"); +} + +static void +gst_auto_video_convert_dispose (GObject * object) +{ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_auto_video_convert_class_init (GstAutoVideoConvertClass * klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + GstElementClass *gstelement_class = (GstElementClass *) klass; + + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_auto_video_convert_dispose); + + GST_DEBUG_CATEGORY_INIT (autovideoconvert_debug, "autovideoconvert", 0, + "Auto color space converter"); + + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_auto_video_convert_change_state); + +} + +static void +gst_auto_video_convert_add_autoconvert (GstAutoVideoConvert * autovideoconvert) +{ + GstPad *pad; + + autovideoconvert->autoconvert = + gst_element_factory_make ("autoconvert", "autoconvertchild"); + + /* first add autoconvert in bin */ + gst_bin_add (GST_BIN (autovideoconvert), autovideoconvert->autoconvert); + + /* get sinkpad and link it to ghost sink pad */ + pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "sink"); + gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->sinkpad), + pad); + gst_object_unref (pad); + + /* get srcpad and link it to ghost src pad */ + pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "src"); + gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->srcpad), pad); + gst_object_unref (pad); +} + +static void +gst_auto_video_convert_init (GstAutoVideoConvert * autovideoconvert, + GstAutoVideoConvertClass * klass) +{ + GstPadTemplate *pad_tmpl; + + /* get sink pad template */ + pad_tmpl = gst_static_pad_template_get (&sinktemplate); + autovideoconvert->sinkpad = + gst_ghost_pad_new_no_target_from_template ("sink", pad_tmpl); + /* add sink ghost pad */ + gst_element_add_pad (GST_ELEMENT (autovideoconvert), + autovideoconvert->sinkpad); + + /* get src pad template */ + pad_tmpl = gst_static_pad_template_get (&srctemplate); + autovideoconvert->srcpad = + gst_ghost_pad_new_no_target_from_template ("src", pad_tmpl); + /* add src ghost pad */ + gst_element_add_pad (GST_ELEMENT (autovideoconvert), + autovideoconvert->srcpad); + + return; +} + +static GstStateChangeReturn +gst_auto_video_convert_change_state (GstElement * element, + GstStateChange transition) +{ + GstAutoVideoConvert *autovideoconvert = GST_AUTO_VIDEO_CONVERT (element); + GstStateChangeReturn ret; + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + { + /* create and add autoconvert in bin */ + gst_auto_video_convert_add_autoconvert (autovideoconvert); + /* get an updated list of factories */ + gst_auto_video_convert_update_factory_list (autovideoconvert); + GST_DEBUG_OBJECT (autovideoconvert, "set factories list"); + /* give factory list to autoconvert */ + g_object_set (GST_ELEMENT (autovideoconvert->autoconvert), "factories", + factories, NULL); + /* synchronize autoconvert state with parent state */ + gst_element_sync_state_with_parent (autovideoconvert->autoconvert); + break; + } + default: + break; + } + + return ret; +} |