summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>2014-11-05 09:40:43 +0200
committerSebastian Dröge <sebastian@centricular.com>2015-06-09 10:13:08 +0200
commit16378a7de34f10cf6dc4c0431e011a133e0e2765 (patch)
tree5f2ec65117cec0a55956a6b07099bda1dc8f8382
parent51c3ef05cd5ce6eed001bd6c16ea00f173fc1b08 (diff)
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
-rw-r--r--gst/playback/Makefile.am6
-rw-r--r--gst/playback/gstplaybackutils.c129
-rw-r--r--gst/playback/gstplaybackutils.h37
-rw-r--r--gst/playback/gstplaybin2.c102
4 files changed, 173 insertions, 101 deletions
diff --git a/gst/playback/Makefile.am b/gst/playback/Makefile.am
index cc2c5ce2b..081b22425 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 000000000..bd6ad7bae
--- /dev/null
+++ b/gst/playback/gstplaybackutils.c
@@ -0,0 +1,129 @@
+/* Copyright (C) <2014> Intel Corporation
+ * Copyright (C) <2014> Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+ *
+ * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#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 000000000..c9f895eb6
--- /dev/null
+++ b/gst/playback/gstplaybackutils.h
@@ -0,0 +1,37 @@
+/* Copyright (C) <2014> Intel Corporation
+ * Copyright (C) <2014> Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+ *
+ * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_PLAYBACK_UTILS_H__
+#define __GST_PLAYBACK_UTILS_H__
+
+G_BEGIN_DECLS
+
+#include <gst/gst.h>
+#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 3c19754f5..0929026e9 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;