From 16378a7de34f10cf6dc4c0431e011a133e0e2765 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 5 Nov 2014 09:40:43 +0200 Subject: [PATCH] playback: Add gstplaybackutils.{h,c} to deploy the common subroutines Bring some of the helper functions in gstplaybin2.c to new files gstplaybackutils.{h,c} which can be utilized by other files in gst/playback too. https://bugzilla.gnome.org/show_bug.cgi?id=687182 --- gst/playback/Makefile.am | 6 +- gst/playback/gstplaybackutils.c | 129 ++++++++++++++++++++++++++++++++++++++++ gst/playback/gstplaybackutils.h | 37 ++++++++++++ gst/playback/gstplaybin2.c | 102 +------------------------------ 4 files changed, 173 insertions(+), 101 deletions(-) create mode 100644 gst/playback/gstplaybackutils.c create mode 100644 gst/playback/gstplaybackutils.h diff --git a/gst/playback/Makefile.am b/gst/playback/Makefile.am index cc2c5ce..081b224 100644 --- a/gst/playback/Makefile.am +++ b/gst/playback/Makefile.am @@ -13,7 +13,8 @@ libgstplayback_la_SOURCES = \ gstplaysinkvideoconvert.c \ gstplaysinkaudioconvert.c \ gstplaysinkconvertbin.c \ - gststreamsynchronizer.c + gststreamsynchronizer.c \ + gstplaybackutils.c nodist_libgstplayback_la_SOURCES = $(built_sources) libgstplayback_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(csp_cflags) @@ -34,7 +35,8 @@ noinst_HEADERS = \ gstplaysinkvideoconvert.h \ gstplaysinkaudioconvert.h \ gstplaysinkconvertbin.h \ - gststreamsynchronizer.h + gststreamsynchronizer.h \ + gstplaybackutils.h BUILT_SOURCES = $(built_headers) $(built_sources) diff --git a/gst/playback/gstplaybackutils.c b/gst/playback/gstplaybackutils.c new file mode 100644 index 0000000..bd6ad7b --- /dev/null +++ b/gst/playback/gstplaybackutils.c @@ -0,0 +1,129 @@ +/* Copyright (C) <2014> Intel Corporation + * Copyright (C) <2014> Sreerenj Balachandran + * + * Author: Sreerenj Balachandran + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gstplaybackutils.h" + +static GstStaticCaps raw_audio_caps = GST_STATIC_CAPS ("audio/x-raw(ANY)"); +static GstStaticCaps raw_video_caps = GST_STATIC_CAPS ("video/x-raw(ANY)"); + +/* unref the caps after usage */ +static GstCaps * +get_template_caps (GstElementFactory * factory, GstPadDirection direction) +{ + const GList *templates; + GstStaticPadTemplate *templ = NULL; + GList *walk; + + templates = gst_element_factory_get_static_pad_templates (factory); + for (walk = (GList *) templates; walk; walk = g_list_next (walk)) { + templ = walk->data; + if (templ->direction == direction) + break; + } + if (templ) + return gst_static_caps_get (&templ->static_caps); + else + return NULL; +} + +static gboolean +is_included (GList * list, GstCapsFeatures * cf) +{ + for (; list; list = list->next) { + if (gst_caps_features_is_equal ((GstCapsFeatures *) list->data, cf)) + return TRUE; + } + return FALSE; +} + +/* compute the number of common caps features */ +guint +gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1, + GstElementFactory * fact2, GstPlayFlags flags, gboolean isaudioelement) +{ + GstCaps *fact1_tmpl_caps, *fact2_tmpl_caps; + GstCapsFeatures *fact1_features, *fact2_features; + GstStructure *fact1_struct, *fact2_struct; + GList *cf_list = NULL; + guint fact1_caps_size, fact2_caps_size; + guint i, j, n_common_cf = 0; + GstCaps *raw_caps = + (isaudioelement) ? gst_static_caps_get (&raw_audio_caps) : + gst_static_caps_get (&raw_video_caps); + GstStructure *raw_struct = gst_caps_get_structure (raw_caps, 0); + gboolean native_raw = + (isaudioelement ? ! !(flags & GST_PLAY_FLAG_NATIVE_AUDIO) : ! !(flags & + GST_PLAY_FLAG_NATIVE_VIDEO)); + + fact1_tmpl_caps = get_template_caps (fact1, GST_PAD_SRC); + fact2_tmpl_caps = get_template_caps (fact2, GST_PAD_SINK); + if (!fact1_tmpl_caps || !fact2_tmpl_caps) { + GST_ERROR ("Failed to get template caps from decoder or sink"); + return 0; + } + + fact1_caps_size = gst_caps_get_size (fact1_tmpl_caps); + fact2_caps_size = gst_caps_get_size (fact2_tmpl_caps); + + for (i = 0; i < fact1_caps_size; i++) { + fact1_features = + gst_caps_get_features ((const GstCaps *) fact1_tmpl_caps, i); + fact1_struct = + gst_caps_get_structure ((const GstCaps *) fact1_tmpl_caps, i); + for (j = 0; j < fact2_caps_size; j++) { + + fact2_features = + gst_caps_get_features ((const GstCaps *) fact2_tmpl_caps, j); + fact2_struct = + gst_caps_get_structure ((const GstCaps *) fact2_tmpl_caps, j); + + /* A common caps feature is given if the caps features are equal + * and the structures can intersect. If the NATIVE_AUDIO/NATIVE_VIDEO + * flags are not set we also allow if both structures are raw caps with + * system memory caps features, because in that case we have converters in + * place. + */ + if (gst_caps_features_is_equal (fact1_features, fact2_features) && + (gst_structure_can_intersect (fact1_struct, fact2_struct) || + (!native_raw + && gst_caps_features_is_equal (fact1_features, + GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) + && gst_structure_can_intersect (raw_struct, fact1_struct) + && gst_structure_can_intersect (raw_struct, fact2_struct))) + && !is_included (cf_list, fact2_features)) { + cf_list = g_list_prepend (cf_list, fact2_features); + n_common_cf++; + } + } + } + if (cf_list) + g_list_free (cf_list); + + gst_caps_unref (fact1_tmpl_caps); + gst_caps_unref (fact2_tmpl_caps); + + return n_common_cf; +} diff --git a/gst/playback/gstplaybackutils.h b/gst/playback/gstplaybackutils.h new file mode 100644 index 0000000..c9f895e --- /dev/null +++ b/gst/playback/gstplaybackutils.h @@ -0,0 +1,37 @@ +/* Copyright (C) <2014> Intel Corporation + * Copyright (C) <2014> Sreerenj Balachandran + * + * Author: Sreerenj Balachandran + * + * 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. + */ + +#ifndef __GST_PLAYBACK_UTILS_H__ +#define __GST_PLAYBACK_UTILS_H__ + +G_BEGIN_DECLS + +#include +#include "gstplay-enum.h" + +guint +gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1, + GstElementFactory * fact2, + GstPlayFlags flags, + gboolean isaudioelement); +G_END_DECLS + +#endif /* __GST_PLAYBACK_UTILS_H__ */ diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 3c19754..0929026 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -237,6 +237,7 @@ #include "gstplayback.h" #include "gstplaysink.h" #include "gstsubtitleoverlay.h" +#include "gstplaybackutils.h" GST_DEBUG_CATEGORY_STATIC (gst_play_bin_debug); #define GST_CAT_DEFAULT gst_play_bin_debug @@ -3811,103 +3812,6 @@ avelement_compare (gconstpointer p1, gconstpointer p2) return strcmp (GST_OBJECT_NAME (fd1), GST_OBJECT_NAME (fd2)); } -/* unref the caps after usage */ -static GstCaps * -get_template_caps (GstElementFactory * factory, GstPadDirection direction) -{ - const GList *templates; - GstStaticPadTemplate *templ = NULL; - GList *walk; - - templates = gst_element_factory_get_static_pad_templates (factory); - for (walk = (GList *) templates; walk; walk = g_list_next (walk)) { - templ = walk->data; - if (templ->direction == direction) - break; - } - if (templ) - return gst_static_caps_get (&templ->static_caps); - else - return NULL; -} - -static gboolean -is_included (GList * list, GstCapsFeatures * cf) -{ - for (; list; list = list->next) { - if (gst_caps_features_is_equal ((GstCapsFeatures *) list->data, cf)) - return TRUE; - } - return FALSE; -} - -/* compute the number of common caps features */ -static guint -get_n_common_capsfeatures (GstPlayBin * playbin, GstElementFactory * dec, - GstElementFactory * sink, gboolean isaudioelement) -{ - GstCaps *d_tmpl_caps, *s_tmpl_caps; - GstCapsFeatures *d_features, *s_features; - GstStructure *d_struct, *s_struct; - GList *cf_list = NULL; - guint d_caps_size, s_caps_size; - guint i, j, n_common_cf = 0; - GstCaps *raw_caps = - (isaudioelement) ? gst_static_caps_get (&raw_audio_caps) : - gst_static_caps_get (&raw_video_caps); - GstStructure *raw_struct = gst_caps_get_structure (raw_caps, 0); - GstPlayFlags flags = gst_play_bin_get_flags (playbin); - gboolean native_raw = - (isaudioelement ? ! !(flags & GST_PLAY_FLAG_NATIVE_AUDIO) : ! !(flags & - GST_PLAY_FLAG_NATIVE_VIDEO)); - - d_tmpl_caps = get_template_caps (dec, GST_PAD_SRC); - s_tmpl_caps = get_template_caps (sink, GST_PAD_SINK); - - if (!d_tmpl_caps || !s_tmpl_caps) { - GST_ERROR ("Failed to get template caps from decoder or sink"); - return 0; - } - - d_caps_size = gst_caps_get_size (d_tmpl_caps); - s_caps_size = gst_caps_get_size (s_tmpl_caps); - - for (i = 0; i < d_caps_size; i++) { - d_features = gst_caps_get_features ((const GstCaps *) d_tmpl_caps, i); - d_struct = gst_caps_get_structure ((const GstCaps *) d_tmpl_caps, i); - for (j = 0; j < s_caps_size; j++) { - - s_features = gst_caps_get_features ((const GstCaps *) s_tmpl_caps, j); - s_struct = gst_caps_get_structure ((const GstCaps *) s_tmpl_caps, j); - - /* A common caps feature is given if the caps features are equal - * and the structures can intersect. If the NATIVE_AUDIO/NATIVE_VIDEO - * flags are not set we also allow if both structures are raw caps with - * system memory caps features, because in that case we have converters in - * place. - */ - if (gst_caps_features_is_equal (d_features, s_features) && - (gst_structure_can_intersect (d_struct, s_struct) || - (!native_raw - && gst_caps_features_is_equal (d_features, - GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) - && gst_structure_can_intersect (raw_struct, d_struct) - && gst_structure_can_intersect (raw_struct, s_struct))) - && !is_included (cf_list, s_features)) { - cf_list = g_list_prepend (cf_list, s_features); - n_common_cf++; - } - } - } - if (cf_list) - g_list_free (cf_list); - - gst_caps_unref (d_tmpl_caps); - gst_caps_unref (s_tmpl_caps); - - return n_common_cf; -} - static GSequence * avelements_create (GstPlayBin * playbin, gboolean isaudioelement) { @@ -3951,8 +3855,8 @@ avelements_create (GstPlayBin * playbin, gboolean isaudioelement) s_factory = (GstElementFactory *) sl->data; n_common_cf = - get_n_common_capsfeatures (playbin, d_factory, s_factory, - isaudioelement); + gst_playback_utils_get_n_common_capsfeatures (d_factory, s_factory, + gst_play_bin_get_flags (playbin), isaudioelement); if (n_common_cf < 1) continue; -- 2.7.4