Policy element integration 79/2479/1 accepted/2.0alpha/20130116.195427 submit/2.0alpha/20121212.074539
authorAmarnath Valluri <amarnath.valluri@linux.intel.com>
Mon, 26 Nov 2012 09:08:17 +0000 (11:08 +0200)
committerAmarnath Valluri <amarnath.valluri@linux.intel.com>
Tue, 4 Dec 2012 08:00:13 +0000 (10:00 +0200)
21 files changed:
configure.ac
gst-libs/gst/Makefile.am
gst-libs/gst/policy/Makefile.am [new file with mode: 0644]
gst-libs/gst/policy/gstpolicy.c [new file with mode: 0644]
gst-libs/gst/policy/gstpolicy.h [new file with mode: 0644]
gst-plugins-base.spec.in
gst/playback/gstplaybin2.c
gst/playback/gstplaysink.c
gst/policy/Makefile.am [new file with mode: 0644]
gst/policy/gstautopolicy.c [new file with mode: 0644]
gst/policy/gstautopolicy.h [new file with mode: 0644]
gst/policy/gstdefaultpolicy.c [new file with mode: 0644]
gst/policy/gstdefaultpolicy.h [new file with mode: 0644]
gst/policy/gstpolicyplugin.c [new file with mode: 0644]
gst/policy/gstpolicyplugin.h [new file with mode: 0644]
packaging/gst-plugins-base.spec
pkgconfig/Makefile.am
pkgconfig/gstreamer-policy-uninstalled.pc.in [new file with mode: 0644]
pkgconfig/gstreamer-policy.pc.in [new file with mode: 0644]
tests/check/Makefile.am
tests/check/elements/policy.c [new file with mode: 0644]

index 1901bcf..a7bfabb 100644 (file)
@@ -423,6 +423,7 @@ AG_GST_CHECK_PLUGIN(encoding)
 AG_GST_CHECK_PLUGIN(ffmpegcolorspace)
 AG_GST_CHECK_PLUGIN(gdp)
 AG_GST_CHECK_PLUGIN(playback)
+AG_GST_CHECK_PLUGIN(policy)
 AG_GST_CHECK_PLUGIN(audioresample)
 AG_GST_CHECK_PLUGIN(subparse)
 AG_GST_CHECK_PLUGIN(tcp)
@@ -938,6 +939,7 @@ gst/encoding/Makefile
 gst/ffmpegcolorspace/Makefile
 gst/gdp/Makefile
 gst/playback/Makefile
+gst/policy/Makefile
 gst/audioresample/Makefile
 gst/subparse/Makefile
 gst/tcp/Makefile
@@ -969,6 +971,7 @@ gst-libs/gst/fft/Makefile
 gst-libs/gst/floatcast/Makefile
 gst-libs/gst/interfaces/Makefile
 gst-libs/gst/netbuffer/Makefile
+gst-libs/gst/policy/Makefile
 gst-libs/gst/riff/Makefile
 gst-libs/gst/rtp/Makefile
 gst-libs/gst/rtsp/Makefile
@@ -995,6 +998,8 @@ pkgconfig/gstreamer-netbuffer.pc
 pkgconfig/gstreamer-netbuffer-uninstalled.pc
 pkgconfig/gstreamer-pbutils.pc
 pkgconfig/gstreamer-pbutils-uninstalled.pc
+pkgconfig/gstreamer-policy.pc
+pkgconfig/gstreamer-policy-uninstalled.pc
 pkgconfig/gstreamer-riff.pc
 pkgconfig/gstreamer-riff-uninstalled.pc
 pkgconfig/gstreamer-rtp.pc
index 0984251..f300fa8 100644 (file)
@@ -16,7 +16,8 @@ SUBDIRS = \
        pbutils \
        audio \
        riff \
-       app
+       app \
+    policy
 
 noinst_HEADERS = gettext.h gst-i18n-plugin.h glib-compat-private.h
 
@@ -30,7 +31,7 @@ riff: tag audio
 rtsp: sdp
 
 INDEPENDENT_SUBDIRS = \
-       interfaces tag fft floatcast netbuffer pbutils rtp sdp video app
+       interfaces tag fft floatcast netbuffer pbutils rtp sdp video app policy
 
 .PHONY: independent-subdirs $(INDEPENDENT_SUBDIRS)
 
diff --git a/gst-libs/gst/policy/Makefile.am b/gst-libs/gst/policy/Makefile.am
new file mode 100644 (file)
index 0000000..c1037e8
--- /dev/null
@@ -0,0 +1,72 @@
+libgstpolicyincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/policy
+
+libgstpolicyinclude_HEADERS = gstpolicy.h
+
+lib_LTLIBRARIES = libgstpolicy-@GST_MAJORMINOR@.la
+
+libgstpolicy_@GST_MAJORMINOR@_la_SOURCES = gstpolicy.c
+
+libgstpolicy_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GIO_CFLAGS)
+libgstpolicy_@GST_MAJORMINOR@_la_LIBADD = $(GST_LIBS) $(GIO_LIBS)
+libgstpolicy_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
+
+if HAVE_INTROSPECTION
+BUILT_GIRSOURCES = GstPolicy-@GST_MAJORMINOR@.gir
+
+gir_headers=$(patsubst %,$(srcdir)/%, $(libgstpolicyinclude_HEADERS))
+gir_sources=$(patsubst %,$(srcdir)/%, $(libgstpolicy_@GST_MAJORMINOR@_la_SOURCES))
+gir_cincludes=$(patsubst %,--c-include='gst/policy/%',$(libgstpolicyinclude_HEADERS))
+
+GstPolicy-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstpolicy-@GST_MAJORMINOR@.la
+       $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+               GST_PLUGIN_SYSTEM_PATH="" GST_PLUGIN_PATH="" GST_REGISTRY_UPDATE=no \
+               $(INTROSPECTION_SCANNER) -v --namespace GstPolicy \
+               --nsversion=@GST_MAJORMINOR@ \
+               --strip-prefix=Gst \
+               --warn-all \
+               $(gir_cincludes) \
+               -I$(top_srcdir)/gst-libs \
+               --add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-@GST_MAJORMINOR@` \
+               --library=libgstpolicy-@GST_MAJORMINOR@.la \
+               --include=Gst-@GST_MAJORMINOR@ \
+               --libtool="$(top_builddir)/libtool" \
+               --pkg gstreamer-@GST_MAJORMINOR@ \
+               --pkg-export gstreamer-policy-@GST_MAJORMINOR@ \
+        --add-init-section="gst_init(NULL,NULL);" \
+               --output $@ \
+               $(gir_headers) \
+               $(gir_sources)
+
+# INTROSPECTION_GIRDIR/INTROSPECTION_TYPELIBDIR aren't the right place to
+# install anything - we need to install inside our prefix.
+girdir = $(datadir)/gir-1.0
+gir_DATA = $(BUILT_GIRSOURCES)
+
+typelibsdir = $(libdir)/girepository-1.0/
+
+typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
+
+%.typelib: %.gir $(INTROSPECTION_COMPILER)
+       $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+               $(INTROSPECTION_COMPILER) \
+               --includedir=$(srcdir) \
+               --includedir=$(builddir) \
+               --includedir=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-@GST_MAJORMINOR@` \
+               $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
+
+CLEANFILES = $(BUILT_GIRSOURCES) $(typelibs_DATA)
+endif
+
+Android.mk: Makefile.am $(BUILT_SOURCES)
+       androgenizer -:PROJECT libgstpolicy -:SHARED libgstpolicy-@GST_MAJORMINOR@ \
+        -:TAGS eng debug \
+         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
+        -:SOURCES $(libgstpolicy_@GST_MAJORMINOR@_la_SOURCES) \
+        -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpolicy_@GST_MAJORMINOR@_la_CFLAGS) \
+        -:LDFLAGS $(libgstpolicy_@GST_MAJORMINOR@_la_LDFLAGS) \
+                  $(libgstpolicy_@GST_MAJORMINOR@_la_LIBADD) \
+                  -ldl \
+        -:HEADER_TARGET gstreamer-@GST_MAJORMINOR@/gst/policy \
+        -:HEADERS $(libgstpolicyinclude_HEADERS) \
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
+       > $@
diff --git a/gst-libs/gst/policy/gstpolicy.c b/gst-libs/gst/policy/gstpolicy.c
new file mode 100644 (file)
index 0000000..3b2d786
--- /dev/null
@@ -0,0 +1,284 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+/**
+ * SECTION:gstpolicy
+ * @short_description: Simple base class for platform-specific policy implementations
+ * @see_also: autopolicy
+ *
+ * Any platform-specific policy element should be implemented by subclassing
+ * #GstPolicy. Applications should be using #autopolicy element that finds and 
+ * and wraps an appropriate policy element, or just #playbin element which 
+ * encapsulates autopolicy element.
+ *
+ * #GstPolicy provides an unlimited number of request sink pads. You can obtain 
+ * the corresponding source pad by listening to a "pad-added" signal while 
+ * requesting the sink pad.
+ * </refsect2>
+ */
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gst/gst.h>
+
+#include "gstpolicy.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_policy_debug);
+#define GST_CAT_DEFAULT gst_policy_debug
+
+enum
+{
+  LAST_SIGNAL
+};
+
+enum
+{
+  PROP_0,
+  PROP_ROLE
+};
+
+static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS ("ANY")
+    );
+
+static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src_%d",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS ("ANY")
+    );
+
+GST_BOILERPLATE(GstPolicy, gst_policy, GstElement, GST_TYPE_ELEMENT);
+
+static void gst_policy_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_policy_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void gst_policy_finalize (GObject * object);
+
+static GstPad *gst_policy_request_new_pad (GstElement * element,
+    GstPadTemplate * templ, const gchar * name);
+static void gst_policy_release_pad (GstElement * element, GstPad * pad);
+
+static gboolean gst_policy_sink_event (GstPad * pad, GstEvent * event);
+static gboolean gst_policy_src_event (GstPad * pad, GstEvent * event);
+static GstFlowReturn gst_policy_chain (GstPad * pad, GstBuffer * buf);
+
+static GstIterator *gst_policy_iterate_internal_links (GstPad *
+    pad, GstObject * parent);
+
+static void
+gst_policy_class_init (GstPolicyClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  GST_DEBUG_CATEGORY_INIT (gst_policy_debug, "policy", 0, "Policy debugging");
+
+  gobject_class->set_property = gst_policy_set_property;
+  gobject_class->get_property = gst_policy_get_property;
+  gobject_class->finalize = gst_policy_finalize;
+
+  /**
+   * GstPolicy:role
+   *
+   * Set the role of the stream. This property can be used by the platform policy subsystem
+   * to make policy decisions that affect the stream (for example routing and enforced 
+   * pause/playback).
+   */
+  g_object_class_install_property (gobject_class, PROP_ROLE,
+      g_param_spec_string ("role", "Stream role",
+          "Stream role for the platform policy sybsystem", NULL,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  // element class methods
+  gstelement_class->request_new_pad = gst_policy_request_new_pad;
+  gstelement_class->release_pad = gst_policy_release_pad;
+}
+
+static void
+gst_policy_init (GstPolicy * policy, GstPolicyClass *klass)
+{
+  GST_DEBUG_CATEGORY_INIT (gst_policy_debug, "policy", 0, "Policy");
+
+  policy->role = NULL;
+}
+
+static void
+gst_policy_base_init (gpointer klass) 
+{
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_factory));
+
+}
+
+static void
+gst_policy_finalize (GObject * object)
+{
+  GstPolicy *policy;
+
+  policy = GST_POLICY (object);
+
+  g_free (policy->role);
+  policy->role = NULL;
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_policy_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstPolicy *policy = GST_POLICY (object);
+
+  switch (prop_id) {
+    case PROP_ROLE:
+      g_free (policy->role);
+      policy->role = g_strdup (g_value_get_string (value));
+      GST_DEBUG_OBJECT (policy, "Setting stream role to %s", policy->role);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_policy_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstPolicy *policy = GST_POLICY (object);
+
+  switch (prop_id) {
+    case PROP_ROLE:
+      GST_DEBUG_OBJECT (policy, "Getting stream role: %s", policy->role);
+      g_value_set_string (value, policy->role);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+static void
+gst_policy_release_pad (GstElement * element, GstPad * pad)
+{
+  GstPolicy *self = GST_POLICY (element);
+  GstPad *srcpad = gst_pad_get_element_private (pad);
+
+  gst_pad_set_element_private (pad, NULL);
+  gst_pad_set_element_private (srcpad, NULL);
+
+  gst_element_remove_pad (GST_ELEMENT_CAST (self), srcpad);
+  gst_element_remove_pad (GST_ELEMENT_CAST (self), pad);
+}
+
+static GstIterator *
+gst_policy_iterate_internal_links (GstPad * pad, GstObject * parent)
+{
+  GstIterator *it = NULL;
+  GstPad *opad;
+
+  opad = gst_pad_get_element_private (pad);
+  if (opad) {
+    it = gst_iterator_new_single (GST_TYPE_PAD, (gpointer)opad, 
+             (GstCopyFunction)gst_object_ref, 
+             (GFreeFunc)gst_object_unref);
+  }
+
+  return it;
+}
+
+static gboolean
+gst_policy_sink_event (GstPad * pad, GstEvent * event)
+{
+  gboolean ret;
+
+  switch (GST_EVENT_TYPE (event)) {
+    default:
+      ret = gst_pad_event_default (pad, event);
+      break;
+  }
+  return ret;
+}
+
+static gboolean
+gst_policy_src_event (GstPad * pad, GstEvent * event)
+{
+  gboolean ret;
+
+  switch (GST_EVENT_TYPE (event)) {
+    default:
+      ret = gst_pad_event_default (pad, event);
+      break;
+  }
+  return ret;
+}
+
+static GstFlowReturn
+gst_policy_chain (GstPad * pad, GstBuffer * buf)
+{
+  /* just push out the incoming buffer without touching it */
+  return gst_pad_push (gst_pad_get_element_private (pad), buf);
+}
+
+static GstPad *
+gst_policy_request_new_pad (GstElement * element,
+    GstPadTemplate * templ, const gchar * name)
+{
+  GstPad *srcpad;
+  GstPad *sinkpad;
+  GstPolicy *self = GST_POLICY (element);
+
+  sinkpad = gst_pad_new_from_template (templ, name);
+  srcpad = gst_pad_new_from_static_template (&src_factory, NULL);
+
+  gst_pad_set_element_private (sinkpad, srcpad);
+  gst_pad_set_element_private (srcpad, sinkpad);
+
+  gst_pad_set_chain_function (sinkpad, 
+      GST_DEBUG_FUNCPTR (gst_policy_chain));
+  gst_pad_set_iterate_internal_links_function (sinkpad,
+      (GstPadIterIntLinkFunction)gst_policy_iterate_internal_links);
+  gst_pad_set_event_function (sinkpad, 
+      GST_DEBUG_FUNCPTR (gst_policy_sink_event));
+
+  gst_pad_set_iterate_internal_links_function (srcpad,
+      (GstPadIterIntLinkFunction)gst_policy_iterate_internal_links);
+  gst_pad_set_event_function (srcpad, 
+      GST_DEBUG_FUNCPTR (gst_policy_src_event));
+
+  gst_pad_set_active (srcpad, TRUE);
+  gst_pad_set_active (sinkpad, TRUE);
+
+  gst_element_add_pad (GST_ELEMENT (self), sinkpad);
+  gst_element_add_pad (GST_ELEMENT (self), srcpad);
+
+  return sinkpad;
+}
+
diff --git a/gst-libs/gst/policy/gstpolicy.h b/gst-libs/gst/policy/gstpolicy.h
new file mode 100644 (file)
index 0000000..fd9defc
--- /dev/null
@@ -0,0 +1,70 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_POLICY_H__
+#define __GST_POLICY_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+/* #defines don't like whitespacey bits */
+#define GST_TYPE_POLICY \
+  (gst_policy_get_type())
+#define GST_POLICY(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_POLICY,GstPolicy))
+#define GST_POLICY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_POLICY,GstPolicyClass))
+#define GST_IS_POLICY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_POLICY))
+#define GST_IS_POLICY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_POLICY))
+
+typedef struct _GstPolicy      GstPolicy;
+typedef struct _GstPolicyClass GstPolicyClass;
+
+/**
+ * GstPolicy:
+ *
+ * Opaque #GstPolicy.
+ */
+struct _GstPolicy
+{
+  GstElement element;
+
+  gchar* role;
+};
+
+/**
+ * GstPolicyClass:
+ * @parent_class: the parent class structure.
+ *
+ * #GstPolicy class.
+ */
+struct _GstPolicyClass 
+{
+  GstElementClass parent_class;
+};
+
+GType gst_policy_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_POLICY_H__ */
index 5f741ac..994e485 100644 (file)
@@ -98,6 +98,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/libgstrtsp-%{majorminor}.so.*
 %{_libdir}/libgstsdp-%{majorminor}.so.*
 %{_libdir}/libgstapp-%{majorminor}.so.*
+%{_libdir}/libgstpolicy-%{majorminor}.so.*
 
 # base plugins without external dependencies
 %{_libdir}/gstreamer-%{majorminor}/libgstadder.so
@@ -106,6 +107,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/gstreamer-%{majorminor}/libgstdecodebin.so
 %{_libdir}/gstreamer-%{majorminor}/libgstdecodebin2.so
 %{_libdir}/gstreamer-%{majorminor}/libgstplaybin.so
+%{_libdir}/gstreamer-%{majorminor}/libgstpolicy.so
 %{_libdir}/gstreamer-%{majorminor}/libgsttypefindfunctions.so
 %{_libdir}/gstreamer-%{majorminor}/libgstvideotestsrc.so
 %{_libdir}/gstreamer-%{majorminor}/libgstaudiorate.so
index e01ff6c..5956544 100644 (file)
@@ -504,6 +504,7 @@ enum
   PROP_BUFFER_DURATION,
   PROP_AV_OFFSET,
   PROP_RING_BUFFER_MAX_SIZE,
+  PROP_ROLE,
   PROP_LAST
 };
 
@@ -824,6 +825,17 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
           "Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled)",
           0, G_MAXUINT, DEFAULT_RING_BUFFER_MAX_SIZE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+  * GstPlayBin:role
+  *
+  * Set the role of the stream. This property is used by the platform policy subsystem
+  * to make policy decisions that affect the stream (for example routing and enforced 
+  * pause/playback).
+  */
+  g_object_class_install_property (gobject_klass, PROP_ROLE,
+      g_param_spec_string ("role", "Stream role",
+          "Stream role for the platform policy sybsystem", NULL,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   /**
    * GstPlayBin2::about-to-finish
@@ -1959,6 +1971,10 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
     case PROP_RING_BUFFER_MAX_SIZE:
       playbin->ring_buffer_max_size = g_value_get_uint64 (value);
       break;
+    case PROP_ROLE:
+      gst_child_proxy_set_property (GST_OBJECT_CAST(playbin->playsink),
+          "policy::actual-policy::role", value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2134,6 +2150,10 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_RING_BUFFER_MAX_SIZE:
       g_value_set_uint64 (value, playbin->ring_buffer_max_size);
       break;
+    case PROP_ROLE:
+      gst_child_proxy_get_property (GST_OBJECT_CAST (playbin->playsink),
+          "policy::actual-policy::role", value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index d02ec60..011d5cd 100644 (file)
@@ -156,6 +156,7 @@ struct _GstPlaySink
   GstPlayFlags flags;
 
   GstStreamSynchronizer *stream_synchronizer;
+  GstElement *policy;
 
   /* chains */
   GstPlayAudioChain *audiochain;
@@ -170,6 +171,8 @@ struct _GstPlaySink
   gboolean audio_pad_blocked;
   GstPad *audio_srcpad_stream_synchronizer;
   GstPad *audio_sinkpad_stream_synchronizer;
+  GstPad *audio_srcpad_policy;
+  GstPad *audio_sinkpad_policy;
   /* audio tee */
   GstElement *audio_tee;
   GstPad *audio_tee_sink;
@@ -181,11 +184,15 @@ struct _GstPlaySink
   gboolean video_pad_blocked;
   GstPad *video_srcpad_stream_synchronizer;
   GstPad *video_sinkpad_stream_synchronizer;
+  GstPad *video_srcpad_policy;
+  GstPad *video_sinkpad_policy;
   /* text */
   GstPad *text_pad;
   gboolean text_pad_blocked;
   GstPad *text_srcpad_stream_synchronizer;
   GstPad *text_sinkpad_stream_synchronizer;
+  GstPad *text_srcpad_policy;
+  GstPad *text_sinkpad_policy;
 
   guint32 pending_blocked_pads;
 
@@ -525,6 +532,10 @@ gst_play_sink_init (GstPlaySink * playsink)
   gst_bin_add (GST_BIN_CAST (playsink),
       GST_ELEMENT_CAST (playsink->stream_synchronizer));
 
+  playsink->policy = 
+      gst_element_factory_make ("autopolicy", "policy");
+  gst_bin_add (GST_BIN_CAST (playsink), playsink->policy);
+
   g_static_rec_mutex_init (&playsink->lock);
   GST_OBJECT_FLAG_SET (playsink, GST_ELEMENT_IS_SINK);
 }
@@ -617,6 +628,7 @@ gst_play_sink_dispose (GObject * object)
   playsink->subtitle_encoding = NULL;
 
   playsink->stream_synchronizer = NULL;
+  playsink->policy = NULL;
 
   G_OBJECT_CLASS (gst_play_sink_parent_class)->dispose (object);
 }
@@ -2146,6 +2158,85 @@ link_failed:
   }
 }
 
+static void
+policy_pad_added_cb (GstElement * gstelement,
+    GstPad * new_pad, gpointer user_data)
+{
+  GstPad **ppad;
+  ppad = user_data;
+  if (gst_pad_get_direction (new_pad) == GST_PAD_SRC) {
+    gst_object_ref (new_pad);
+    *ppad = new_pad;
+  }
+}
+
+static void
+_add_policy_and_synchronizer_pads (GstPlaySink * playsink,
+    GstPad ** sinkpad_stream_synchronizer,
+    GstPad ** srcpad_stream_synchronizer,
+    GstPad ** sinkpad_policy,
+    GstPad ** srcpad_policy)
+{
+  if (!*sinkpad_stream_synchronizer) {
+    GstIterator *it;
+
+    /* request stream synchronizer pads */
+    *sinkpad_stream_synchronizer = 
+        gst_element_get_request_pad (GST_ELEMENT_CAST
+        (playsink->stream_synchronizer), "sink_%d");
+    it = gst_pad_iterate_internal_links (*sinkpad_stream_synchronizer);
+    g_assert (it);
+    gst_iterator_next (it, (gpointer *)srcpad_stream_synchronizer);
+    gst_iterator_free (it);
+
+    /* request policy pads */
+    g_signal_connect (G_OBJECT (playsink->policy), "pad-added",
+        G_CALLBACK (policy_pad_added_cb), srcpad_policy);
+    *sinkpad_policy = gst_element_get_request_pad (playsink->policy, "sink_%d");
+    g_assert (*sinkpad_policy);
+    g_signal_handlers_disconnect_by_func (playsink->policy,
+        G_CALLBACK (policy_pad_added_cb), srcpad_policy);
+
+    /* link pads */
+    if (gst_pad_link (*srcpad_stream_synchronizer,
+            *sinkpad_policy) != GST_PAD_LINK_OK) {
+      GST_WARNING_OBJECT (playsink, "pad linking failed : (%s, %s)", 
+          GST_DEBUG_PAD_NAME (*srcpad_stream_synchronizer), 
+          GST_DEBUG_PAD_NAME (*sinkpad_policy));
+    }
+  }
+}
+
+static void
+_remove_policy_and_synchronizer_pads (GstPlaySink * playsink,
+    GstPad ** sinkpad_stream_synchronizer,
+    GstPad ** srcpad_stream_synchronizer,
+    GstPad ** sinkpad_policy,
+    GstPad ** srcpad_policy)
+{
+  if (*sinkpad_stream_synchronizer) {
+    gst_pad_unlink (*srcpad_stream_synchronizer, *sinkpad_policy);
+
+    gst_element_release_request_pad (GST_ELEMENT_CAST
+        (playsink->stream_synchronizer), 
+        *sinkpad_stream_synchronizer);
+
+    gst_object_unref (*sinkpad_stream_synchronizer);
+    *sinkpad_stream_synchronizer = NULL;
+
+    gst_object_unref (*srcpad_stream_synchronizer);
+    *srcpad_stream_synchronizer = NULL;
+    
+    gst_element_release_request_pad (playsink->policy, *sinkpad_policy);
+    
+    gst_object_unref (*sinkpad_policy);
+    *sinkpad_policy = NULL;
+    
+    gst_object_unref (*srcpad_policy);
+    *srcpad_policy = NULL;
+  }
+}
+
 /* this function is called when all the request pads are requested and when we
  * have to construct the final pipeline. Based on the flags we construct the
  * final output pipelines.
@@ -2238,13 +2329,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       /* try to reactivate the chain */
       if (!setup_video_chain (playsink, raw, async)) {
         if (playsink->video_sinkpad_stream_synchronizer) {
-          gst_element_release_request_pad (GST_ELEMENT_CAST
-              (playsink->stream_synchronizer),
-              playsink->video_sinkpad_stream_synchronizer);
-          gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
-          playsink->video_sinkpad_stream_synchronizer = NULL;
-          gst_object_unref (playsink->video_srcpad_stream_synchronizer);
-          playsink->video_srcpad_stream_synchronizer = NULL;
+          _remove_policy_and_synchronizer_pads (playsink,
+              &playsink->video_sinkpad_stream_synchronizer,
+              &playsink->video_srcpad_stream_synchronizer,
+              &playsink->video_sinkpad_policy,
+              &playsink->video_srcpad_policy);
         }
 
         add_chain (GST_PLAY_CHAIN (playsink->videochain), FALSE);
@@ -2267,18 +2356,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       goto no_chain;
 
     if (!playsink->video_sinkpad_stream_synchronizer) {
-      GstIterator *it;
-
-      playsink->video_sinkpad_stream_synchronizer =
-          gst_element_get_request_pad (GST_ELEMENT_CAST
-          (playsink->stream_synchronizer), "sink_%d");
-      it = gst_pad_iterate_internal_links
-          (playsink->video_sinkpad_stream_synchronizer);
-      g_assert (it);
-      gst_iterator_next (it,
-          (gpointer *) & playsink->video_srcpad_stream_synchronizer);
-      g_assert (playsink->video_srcpad_stream_synchronizer);
-      gst_iterator_free (it);
+      _add_policy_and_synchronizer_pads (playsink,
+          &playsink->video_sinkpad_stream_synchronizer,
+          &playsink->video_srcpad_stream_synchronizer,
+          &playsink->video_sinkpad_policy,
+          &playsink->video_srcpad_policy);
     }
 
     if (playsink->video_pad)
@@ -2299,7 +2381,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       add_chain (GST_PLAY_CHAIN (playsink->videodeinterlacechain), TRUE);
       activate_chain (GST_PLAY_CHAIN (playsink->videodeinterlacechain), TRUE);
 
-      gst_pad_link_full (playsink->video_srcpad_stream_synchronizer,
+      gst_pad_link_full (playsink->video_srcpad_policy,
           playsink->videodeinterlacechain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
     } else {
       if (playsink->videodeinterlacechain) {
@@ -2320,7 +2402,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
         gst_pad_link_full (playsink->videodeinterlacechain->srcpad,
             playsink->videochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
       else
-        gst_pad_link_full (playsink->video_srcpad_stream_synchronizer,
+        gst_pad_link_full (playsink->video_srcpad_policy,
             playsink->videochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
     }
   } else {
@@ -2346,13 +2428,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       }
 
       if (playsink->video_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->video_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
-        playsink->video_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->video_srcpad_stream_synchronizer);
-        playsink->video_srcpad_stream_synchronizer = NULL;
+        _remove_policy_and_synchronizer_pads (playsink,
+            &playsink->video_sinkpad_stream_synchronizer,
+            &playsink->video_srcpad_stream_synchronizer,
+            &playsink->video_sinkpad_policy,
+            &playsink->video_srcpad_policy);
       }
 
       add_chain (GST_PLAY_CHAIN (playsink->videochain), FALSE);
@@ -2391,13 +2471,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
         }
 
         if (playsink->audio_sinkpad_stream_synchronizer) {
-          gst_element_release_request_pad (GST_ELEMENT_CAST
-              (playsink->stream_synchronizer),
-              playsink->audio_sinkpad_stream_synchronizer);
-          gst_object_unref (playsink->audio_sinkpad_stream_synchronizer);
-          playsink->audio_sinkpad_stream_synchronizer = NULL;
-          gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
-          playsink->audio_srcpad_stream_synchronizer = NULL;
+          _remove_policy_and_synchronizer_pads (playsink,
+              &playsink->audio_sinkpad_stream_synchronizer,
+              &playsink->audio_srcpad_stream_synchronizer,
+              &playsink->audio_sinkpad_policy,
+              &playsink->audio_srcpad_policy);
         }
 
         add_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
@@ -2427,18 +2505,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
     }
 
     if (!playsink->audio_sinkpad_stream_synchronizer) {
-      GstIterator *it;
-
-      playsink->audio_sinkpad_stream_synchronizer =
-          gst_element_get_request_pad (GST_ELEMENT_CAST
-          (playsink->stream_synchronizer), "sink_%d");
-      it = gst_pad_iterate_internal_links
-          (playsink->audio_sinkpad_stream_synchronizer);
-      g_assert (it);
-      gst_iterator_next (it,
-          (gpointer *) & playsink->audio_srcpad_stream_synchronizer);
-      g_assert (playsink->audio_srcpad_stream_synchronizer);
-      gst_iterator_free (it);
+      _add_policy_and_synchronizer_pads (playsink,
+          &playsink->audio_sinkpad_stream_synchronizer,
+          &playsink->audio_srcpad_stream_synchronizer,
+          &playsink->audio_sinkpad_policy,
+          &playsink->audio_srcpad_policy);
     }
 
     if (playsink->audiochain) {
@@ -2452,7 +2523,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       gst_pad_link_full (playsink->audio_tee_asrc,
           playsink->audio_sinkpad_stream_synchronizer,
           GST_PAD_LINK_CHECK_NOTHING);
-      gst_pad_link_full (playsink->audio_srcpad_stream_synchronizer,
+      gst_pad_link_full (playsink->audio_srcpad_policy,
           playsink->audiochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
     }
   } else {
@@ -2469,13 +2540,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       }
 
       if (playsink->audio_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->audio_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->audio_sinkpad_stream_synchronizer);
-        playsink->audio_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
-        playsink->audio_srcpad_stream_synchronizer = NULL;
+        _remove_policy_and_synchronizer_pads (playsink,
+            &playsink->audio_sinkpad_stream_synchronizer,
+            &playsink->audio_srcpad_stream_synchronizer,
+            &playsink->audio_sinkpad_policy,
+            &playsink->audio_srcpad_policy);
       }
 
       if (playsink->audiochain->sink_volume) {
@@ -2513,7 +2582,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
           playsink->vischain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
       gst_pad_link_full (srcpad, playsink->video_sinkpad_stream_synchronizer,
           GST_PAD_LINK_CHECK_NOTHING);
-      gst_pad_link_full (playsink->video_srcpad_stream_synchronizer,
+      gst_pad_link_full (playsink->video_srcpad_policy,
           playsink->videochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
       gst_object_unref (srcpad);
     }
@@ -2539,7 +2608,6 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       playsink->textchain = gen_text_chain (playsink);
     }
     if (playsink->textchain) {
-      GstIterator *it;
 
       GST_DEBUG_OBJECT (playsink, "adding text chain");
       if (playsink->textchain->overlay)
@@ -2548,20 +2616,15 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       add_chain (GST_PLAY_CHAIN (playsink->textchain), TRUE);
 
       if (!playsink->text_sinkpad_stream_synchronizer) {
-        playsink->text_sinkpad_stream_synchronizer =
-            gst_element_get_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer), "sink_%d");
-        it = gst_pad_iterate_internal_links
-            (playsink->text_sinkpad_stream_synchronizer);
-        g_assert (it);
-        gst_iterator_next (it,
-            (gpointer *) & playsink->text_srcpad_stream_synchronizer);
-        g_assert (playsink->text_srcpad_stream_synchronizer);
-        gst_iterator_free (it);
+        _add_policy_and_synchronizer_pads (playsink,
+            &playsink->text_sinkpad_stream_synchronizer,
+            &playsink->text_srcpad_stream_synchronizer,
+            &playsink->text_sinkpad_policy,
+            &playsink->text_srcpad_policy);
 
         gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->text_pad),
             playsink->text_sinkpad_stream_synchronizer);
-        gst_pad_link_full (playsink->text_srcpad_stream_synchronizer,
+        gst_pad_link_full (playsink->text_srcpad_policy,
             playsink->textchain->textsinkpad, GST_PAD_LINK_CHECK_NOTHING);
       }
 
@@ -2579,7 +2642,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
           gst_pad_link_full (playsink->videodeinterlacechain->srcpad,
               playsink->textchain->videosinkpad, GST_PAD_LINK_CHECK_NOTHING);
         else
-          gst_pad_link_full (playsink->video_srcpad_stream_synchronizer,
+          gst_pad_link_full (playsink->video_srcpad_policy,
               playsink->textchain->videosinkpad, GST_PAD_LINK_CHECK_NOTHING);
       }
       gst_pad_link_full (playsink->textchain->srcpad,
@@ -2592,13 +2655,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
     /* we have no subtitles/text or we are requested to not show them */
 
     if (playsink->text_sinkpad_stream_synchronizer) {
-      gst_element_release_request_pad (GST_ELEMENT_CAST
-          (playsink->stream_synchronizer),
-          playsink->text_sinkpad_stream_synchronizer);
-      gst_object_unref (playsink->text_sinkpad_stream_synchronizer);
-      playsink->text_sinkpad_stream_synchronizer = NULL;
-      gst_object_unref (playsink->text_srcpad_stream_synchronizer);
-      playsink->text_srcpad_stream_synchronizer = NULL;
+      _remove_policy_and_synchronizer_pads (playsink,
+          &playsink->text_sinkpad_stream_synchronizer,
+          &playsink->text_srcpad_stream_synchronizer,
+          &playsink->text_sinkpad_policy,
+          &playsink->text_srcpad_policy);
     }
 
     if (playsink->textchain) {
@@ -2617,13 +2678,11 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
     }
     if (!need_video && playsink->video_pad) {
       if (playsink->video_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->video_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
-        playsink->video_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->video_srcpad_stream_synchronizer);
-        playsink->video_srcpad_stream_synchronizer = NULL;
+        _remove_policy_and_synchronizer_pads (playsink,
+            &playsink->video_sinkpad_stream_synchronizer,
+            &playsink->video_srcpad_stream_synchronizer,
+            &playsink->video_sinkpad_policy,
+            &playsink->video_srcpad_policy);
       }
 
       gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad), NULL);
@@ -3544,31 +3603,25 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:{
       if (playsink->video_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->video_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
-        playsink->video_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->video_srcpad_stream_synchronizer);
-        playsink->video_srcpad_stream_synchronizer = NULL;
+        _remove_policy_and_synchronizer_pads (playsink,
+            &playsink->video_sinkpad_stream_synchronizer,
+            &playsink->video_srcpad_stream_synchronizer,
+            &playsink->video_sinkpad_policy,
+            &playsink->video_srcpad_policy);
       }
       if (playsink->audio_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->audio_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->audio_sinkpad_stream_synchronizer);
-        playsink->audio_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
-        playsink->audio_srcpad_stream_synchronizer = NULL;
+        _remove_policy_and_synchronizer_pads (playsink,
+            &playsink->audio_sinkpad_stream_synchronizer,
+            &playsink->audio_srcpad_stream_synchronizer,
+            &playsink->audio_sinkpad_policy,
+            &playsink->audio_srcpad_policy);
       }
       if (playsink->text_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->text_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->text_sinkpad_stream_synchronizer);
-        playsink->text_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->text_srcpad_stream_synchronizer);
-        playsink->text_srcpad_stream_synchronizer = NULL;
+        _remove_policy_and_synchronizer_pads (playsink,
+            &playsink->text_sinkpad_stream_synchronizer,
+            &playsink->text_srcpad_stream_synchronizer,
+            &playsink->text_sinkpad_policy,
+            &playsink->text_srcpad_policy);
       }
     }
       /* fall through */
diff --git a/gst/policy/Makefile.am b/gst/policy/Makefile.am
new file mode 100644 (file)
index 0000000..56b377e
--- /dev/null
@@ -0,0 +1,37 @@
+plugin_LTLIBRARIES = libgstpolicy.la
+
+libgstpolicy_la_SOURCES = \
+    gstpolicyplugin.c \
+       gstautopolicy.c \
+       gstdefaultpolicy.c
+
+nodist_libgstpolicy_la_SOURCES = $(built_sources)
+libgstpolicy_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+libgstpolicy_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstpolicy_la_LIBADD = \
+    $(top_builddir)/gst-libs/gst/policy/libgstpolicy-$(GST_MAJORMINOR).la \
+       $(GST_LIBS)
+libgstpolicy_la_LIBTOOLFLAGS = --tag=disable-static
+
+noinst_HEADERS = \
+       gstautopolicy.h \
+       gstdefaultpolicy.h
+
+BUILT_SOURCES = $(built_headers) $(built_sources)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+Android.mk: Makefile.am $(BUILT_SOURCES)
+       androgenizer \
+       -:PROJECT libgstpolicy -:SHARED libgstpolicy \
+        -:TAGS eng debug \
+         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
+        -:SOURCES $(libgstpolicy_la_SOURCES) \
+                  $(nodist_libgstpolicy_la_SOURCES) \
+        -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpolicy_la_CFLAGS) $(csp_cflags) \
+        -:LDFLAGS $(libgstpolicy_la_LDFLAGS) \
+                  $(libgstpolicy_la_LIBADD) \
+                  -ldl \
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
+                      LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
+       > $@
diff --git a/gst/policy/gstautopolicy.c b/gst/policy/gstautopolicy.c
new file mode 100644 (file)
index 0000000..c46062f
--- /dev/null
@@ -0,0 +1,237 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+/**
+ * SECTION:element-autopolicy
+ * @see_also: defaultpolicy
+ *
+ * Autopolicy is a wrapper element for platform-specific policy elements.
+ * It automatically detects an appropriate policy element to use by scanning 
+ * the registry for all elements that have <quote>Policy</quote> in the class 
+ * field of their element information. The list is sorted by rank and only 
+ * elements with a non-zero autoplugging rank are included.
+ *
+ * <refsect2>
+ * <title>Example launch line (with policy-specific debugging)</title>
+ * |[
+ * gst-launch -v -m --gst-debug=policy:5 fakesrc ! autopolicy actual-policy::role=testrole ! fakesink silent=TRUE
+ * ]|
+ * </refsect2>
+ * <refsect2>
+ * <title>Usage</title>
+ * Autopolicy provides an unlimited number of request sink pads. You can obtain 
+ * the corresponding source pad by listening to a "pad-added" signal while 
+ * requesting the sink pad.
+ * 
+ * You can also get and set the stream role property #GstPolicy:role by using 
+ * #GstChildProxy interface that autopolicy implements. The name of the role 
+ * property is "actual-policy::role".
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gst/gst.h>
+#include <string.h>
+
+#include "gstautopolicy.h"
+#include "gstpolicyplugin.h"
+
+GST_DEBUG_CATEGORY_EXTERN (gst_policy_debug);
+#define GST_CAT_DEFAULT gst_policy_debug
+
+enum
+{
+  LAST_SIGNAL
+};
+
+enum
+{
+  PROP_0
+};
+
+static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS ("ANY")
+    );
+
+static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src_%d",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS ("ANY")
+    );
+
+#define gst_auto_policy_parent_class parent_class
+G_DEFINE_TYPE (GstAutoPolicy, gst_auto_policy, GST_TYPE_BIN);
+
+static GstPad *
+gst_auto_policy_request_new_pad (GstElement * element,
+    GstPadTemplate * templ, const gchar * name/*, const GstCaps * caps*/)
+{
+  GstPad *srcpad = NULL;
+  GstPad *sinkpad = NULL;
+  GstPad *kid_sink_pad = NULL;
+  GstPad *kid_src_pad = NULL;
+  GstIterator *it = NULL;
+  GstAutoPolicy *self = GST_AUTO_POLICY (element);
+
+  kid_sink_pad = gst_element_get_request_pad (self->kid, "sink_%d");
+  it = gst_pad_iterate_internal_links (kid_sink_pad);
+  if (!it) {
+      gst_object_unref(kid_sink_pad);
+      return NULL;
+  }
+  gst_iterator_next (it, (gpointer *)&kid_src_pad);
+  gst_iterator_free (it);
+
+  sinkpad = gst_ghost_pad_new (name, kid_sink_pad);
+  srcpad = gst_ghost_pad_new (NULL, kid_src_pad);
+
+  gst_pad_set_element_private (sinkpad, srcpad);
+  gst_pad_set_element_private (srcpad, sinkpad);
+
+  gst_pad_set_active (srcpad, TRUE);
+  gst_pad_set_active (sinkpad, TRUE);
+
+  gst_element_add_pad (GST_ELEMENT (self), sinkpad);
+  gst_element_add_pad (GST_ELEMENT (self), srcpad);
+
+  gst_object_unref (kid_sink_pad);
+  gst_object_unref (kid_src_pad);
+
+  return sinkpad;
+}
+
+static void
+gst_auto_policy_release_pad (GstElement * element, GstPad * pad)
+{
+  GstAutoPolicy *self = GST_AUTO_POLICY (element);
+  GstPad *srcpad = gst_pad_get_element_private (pad);
+
+  gst_pad_set_element_private (pad, NULL);
+  gst_pad_set_element_private (srcpad, NULL);
+
+  gst_element_remove_pad (GST_ELEMENT_CAST (self), srcpad);
+  gst_element_remove_pad (GST_ELEMENT_CAST (self), pad);
+}
+
+static void
+gst_auto_policy_dispose (GstAutoPolicy * auto_policy)
+{
+  gst_element_set_state (auto_policy->kid, GST_STATE_NULL);
+  gst_bin_remove (GST_BIN (auto_policy), auto_policy->kid);
+  auto_policy->kid = NULL;
+
+  G_OBJECT_CLASS (parent_class)->dispose ((GObject *) auto_policy);
+}
+
+/* initialize the policy's class */
+static void
+gst_auto_policy_class_init (GstAutoPolicyClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+  const GstElementDetails details = { 
+      (gchar *)"Auto policy", (gchar *)"Policy",
+      (gchar *)"Wrapper element for automatically detected policy element",
+      (gchar *)"Alexander Kanavin <alexander.kanavin@intel.com>" 
+  };
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  gobject_class->dispose = (GObjectFinalizeFunc) gst_auto_policy_dispose;
+
+  gst_element_class_set_details(gstelement_class, &details);
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_factory));
+
+  gstelement_class->request_new_pad = gst_auto_policy_request_new_pad;
+  gstelement_class->release_pad = gst_auto_policy_release_pad;
+}
+
+static gboolean
+gst_auto_policy_factory_filter (GstPluginFeature * feature, gpointer data)
+{
+  guint rank;
+  const gchar *klass;
+
+  /* we only care about element factories */
+  if (!GST_IS_ELEMENT_FACTORY (feature))
+    return FALSE;
+
+  /* policy elements */
+  klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
+  if (strstr (klass, "Policy") == NULL)
+    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
+gst_auto_policy_compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
+{
+  return gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
+}
+
+static GstElement *
+gst_auto_policy_discover_actual_policy (GstAutoPolicy * auto_policy)
+{
+  GList *list, *item;
+  GstElement *choice = NULL;
+
+  list = gst_registry_feature_filter (gst_registry_get_default (),
+      (GstPluginFeatureFilter) gst_auto_policy_factory_filter, FALSE,
+      auto_policy);
+  list = g_list_sort (list, (GCompareFunc) gst_auto_policy_compare_ranks);
+
+  for (item = list; item != NULL; item = item->next) {
+    GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
+    GST_DEBUG_OBJECT (auto_policy, "Testing %s", GST_OBJECT_NAME (f));
+    choice = gst_element_factory_create (f, "actual-policy");
+    if (choice) {
+      GST_DEBUG_OBJECT (auto_policy, "Selected %s", GST_OBJECT_NAME (f));
+      break;
+    }
+  }
+  gst_plugin_feature_list_free (list);
+  return choice;
+}
+
+static void
+gst_auto_policy_init (GstAutoPolicy * auto_policy)
+{
+  auto_policy->kid = gst_auto_policy_discover_actual_policy (auto_policy);
+  //At least default policy should always be available
+  g_assert (auto_policy->kid);
+  gst_bin_add (GST_BIN (auto_policy), auto_policy->kid);
+
+}
diff --git a/gst/policy/gstautopolicy.h b/gst/policy/gstautopolicy.h
new file mode 100644 (file)
index 0000000..216b153
--- /dev/null
@@ -0,0 +1,59 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+
+#ifndef __GST_AUTO_POLICY_H__
+#define __GST_AUTO_POLICY_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_AUTO_POLICY \
+  (gst_auto_policy_get_type())
+#define GST_AUTO_POLICY(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUTO_POLICY,GstAutoPolicy))
+#define GST_AUTO_POLICY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUTO_POLICY,GstAutoPolicyClass))
+#define GST_IS_AUTO_POLICY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUTO_POLICY))
+#define GST_IS_AUTO_POLICY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUTO_POLICY))
+
+typedef struct _GstAutoPolicy      GstAutoPolicy;
+typedef struct _GstAutoPolicyClass GstAutoPolicyClass;
+
+struct _GstAutoPolicy
+{
+  GstBin parent;
+  
+  GstElement *kid;
+};
+
+struct _GstAutoPolicyClass 
+{
+  GstBinClass parent_class;
+};
+
+GType gst_auto_policy_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_POLICY_H__ */
diff --git a/gst/policy/gstdefaultpolicy.c b/gst/policy/gstdefaultpolicy.c
new file mode 100644 (file)
index 0000000..4f1a13a
--- /dev/null
@@ -0,0 +1,69 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+/**
+ * SECTION:element-defaultpolicy
+ * @see_also: autopolicy
+ *
+ * Defaultpolicy implements a default policy, which does nothing at all with the
+ * stream. It's the element that autopolicy element selects in the absence of any
+ * other policy element.
+ *
+ * <refsect2>
+ * <title>Example launch line (with policy-specific debugging)</title>
+ * |[
+ * gst-launch -v -m --gst-debug=policy:5 fakesrc ! defaultpolicy role=testrole ! fakesink silent=TRUE
+ * ]|
+ * </refsect2>
+ * <refsect2>
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gst/gst.h>
+
+#include "gstdefaultpolicy.h"
+
+#define gst_default_policy_parent_class parent_class
+G_DEFINE_TYPE (GstDefaultPolicy, gst_default_policy, GST_TYPE_POLICY);
+
+static void
+gst_default_policy_class_init (GstDefaultPolicyClass * klass)
+{
+  GstElementClass *gstelement_class;
+  const GstElementDetails details = {
+      (gchar *)"Default policy", 
+      (gchar *)"Policy",
+      (gchar *)"Default policy element that does nothing",
+      (gchar *)"Alexander Kanavin <alexander.kanavin@intel.com>"
+  };
+
+  gstelement_class = (GstElementClass *) klass;
+
+  gst_element_class_set_details (gstelement_class, &details);
+}
+
+static void
+gst_default_policy_init (GstDefaultPolicy * policy)
+{
+}
diff --git a/gst/policy/gstdefaultpolicy.h b/gst/policy/gstdefaultpolicy.h
new file mode 100644 (file)
index 0000000..fa6f7cb
--- /dev/null
@@ -0,0 +1,58 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_DEFAULT_POLICY_H__
+#define __GST_DEFAULT_POLICY_H__
+
+#include <gst/gst.h>
+#include "gst/policy/gstpolicy.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_DEFAULT_POLICY \
+  (gst_default_policy_get_type())
+#define GST_DEFAULT_POLICY(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DEFAULT_POLICY,GstDefaultPolicy))
+#define GST_DEFAULT_POLICY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DEFAULT_POLICY,GstDefaultPolicyClass))
+#define GST_IS_DEFAULT_POLICY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DEFAULT_POLICY))
+#define GST_IS_DEFAULT_POLICY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DEFAULT_POLICY))
+
+typedef struct _GstDefaultPolicy      GstDefaultPolicy;
+typedef struct _GstDefaultPolicyClass GstDefaultPolicyClass;
+
+struct _GstDefaultPolicy
+{
+  GstPolicy policy;
+
+};
+
+struct _GstDefaultPolicyClass 
+{
+  GstPolicyClass parent_class;
+};
+
+GType gst_default_policy_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_DEFAULT_POLICY_H__ */
diff --git a/gst/policy/gstpolicyplugin.c b/gst/policy/gstpolicyplugin.c
new file mode 100644 (file)
index 0000000..fe10554
--- /dev/null
@@ -0,0 +1,48 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include "gstdefaultpolicy.h"
+#include "gstautopolicy.h"
+#include "gstpolicyplugin.h"
+
+GST_DEBUG_CATEGORY (gst_policy_debug);
+#define GST_CAT_DEFAULT gst_policy_debug
+
+static gboolean
+policy_init (GstPlugin * policy)
+{
+  GST_DEBUG_CATEGORY_INIT (gst_policy_debug, "policy", 0, "Policy debugging");
+
+  return gst_element_register (policy, "defaultpolicy", GST_RANK_MARGINAL,
+      GST_TYPE_DEFAULT_POLICY) &&
+      gst_element_register (policy, "autopolicy", GST_RANK_NONE,
+      GST_TYPE_AUTO_POLICY);
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    "policy",
+    "various policy elements", policy_init, VERSION, GST_LICENSE,
+    GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/gst/policy/gstpolicyplugin.h b/gst/policy/gstpolicyplugin.h
new file mode 100644 (file)
index 0000000..cc2ae6d
--- /dev/null
@@ -0,0 +1,24 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_POLICYPLUGIN_H__
+#define __GST_POLICYPLUGIN_H__
+
+
+#endif /* __GST_POLICYPLUGIN_H__ */
index 588b782..867eec8 100644 (file)
@@ -102,6 +102,7 @@ rm -rf %{buildroot}/tmp/dump
 %{_libdir}/libgstrtsp-0.10.so.*
 %{_libdir}/libgstsdp-0.10.so.*
 %{_libdir}/libgstapp-0.10.so.*
+%{_libdir}/libgstpolicy-0.10.so.*
 # base plugins without external dependencies
 %{_libdir}/gstreamer-0.10/libgstadder.so
 %{_libdir}/gstreamer-0.10/libgstaudioconvert.so
@@ -109,6 +110,7 @@ rm -rf %{buildroot}/tmp/dump
 %{_libdir}/gstreamer-0.10/libgstffmpegcolorspace.so
 %{_libdir}/gstreamer-0.10/libgstdecodebin.so
 %{_libdir}/gstreamer-0.10/libgstdecodebin2.so
+%{_libdir}/gstreamer-0.10/libgstpolicy.so
 %{_libdir}/gstreamer-0.10/libgstplaybin.so
 %{_libdir}/gstreamer-0.10/libgsttypefindfunctions.so
 %{_libdir}/gstreamer-0.10/libgstvideotestsrc.so
@@ -224,6 +226,8 @@ rm -rf %{buildroot}/tmp/dump
 %{_includedir}/gstreamer-0.10/gst/video/video.h
 %{_includedir}/gstreamer-0.10/gst/video/video-enumtypes.h
 %{_includedir}/gstreamer-0.10/gst/video/video-overlay-composition.h
+%dir %{_includedir}/gstreamer-0.10/gst/policy/
+%{_includedir}/gstreamer-0.10/gst/policy/gstpolicy.h
 %{_libdir}/libgstaudio-0.10.so
 %{_libdir}/libgstinterfaces-0.10.so
 %{_libdir}/libgstnetbuffer-0.10.so
@@ -237,6 +241,7 @@ rm -rf %{buildroot}/tmp/dump
 %{_libdir}/libgstsdp-0.10.so
 %{_libdir}/libgstfft-0.10.so
 %{_libdir}/libgstapp-0.10.so
+%{_libdir}/libgstpolicy-0.10.so
 # pkg-config files
 %{_libdir}/pkgconfig/*.pc
 # documentation
index 8fb2529..86b2b12 100644 (file)
@@ -8,6 +8,7 @@ pcverfiles =  \
        gstreamer-interfaces-@GST_MAJORMINOR@.pc \
        gstreamer-netbuffer-@GST_MAJORMINOR@.pc \
        gstreamer-pbutils-@GST_MAJORMINOR@.pc \
+    gstreamer-policy-@GST_MAJORMINOR@.pc \
        gstreamer-riff-@GST_MAJORMINOR@.pc \
        gstreamer-rtp-@GST_MAJORMINOR@.pc \
        gstreamer-rtsp-@GST_MAJORMINOR@.pc \
@@ -24,6 +25,7 @@ pcverfiles_uninstalled = \
        gstreamer-interfaces-@GST_MAJORMINOR@-uninstalled.pc \
        gstreamer-netbuffer-@GST_MAJORMINOR@-uninstalled.pc \
        gstreamer-pbutils-@GST_MAJORMINOR@-uninstalled.pc \
+    gstreamer-policy-@GST_MAJORMINOR@-uninstalled.pc \
        gstreamer-riff-@GST_MAJORMINOR@-uninstalled.pc \
        gstreamer-rtp-@GST_MAJORMINOR@-uninstalled.pc \
        gstreamer-rtsp-@GST_MAJORMINOR@-uninstalled.pc \
@@ -57,6 +59,7 @@ pcinfiles = \
            gstreamer-interfaces.pc.in gstreamer-interfaces-uninstalled.pc.in \
            gstreamer-netbuffer.pc.in gstreamer-netbuffer-uninstalled.pc.in \
            gstreamer-pbutils.pc.in gstreamer-pbutils-uninstalled.pc.in \
+           gstreamer-policy.pc.in gstreamer-policy-uninstalled.pc.in \
            gstreamer-riff.pc.in gstreamer-riff-uninstalled.pc.in \
            gstreamer-rtp.pc.in gstreamer-rtp-uninstalled.pc.in \
            gstreamer-rtsp.pc.in gstreamer-rtsp-uninstalled.pc.in \
diff --git a/pkgconfig/gstreamer-policy-uninstalled.pc.in b/pkgconfig/gstreamer-policy-uninstalled.pc.in
new file mode 100644 (file)
index 0000000..ef07ea2
--- /dev/null
@@ -0,0 +1,16 @@
+# the standard variables don't make sense for an uninstalled copy
+prefix=
+exec_prefix=
+libdir=
+# includedir is builddir because it is used to find gstconfig.h in places
+includedir=@abs_top_builddir@/gst-libs
+girdir=@abs_top_builddir@/gst-libs/gst/policy
+typelibdir=@abs_top_builddir@/gst-libs/gst/policy
+
+Name: GStreamer Policy Library, Uninstalled
+Description: Helper functions and base classes for policy integration, uninstalled
+Version: @VERSION@
+Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@
+Libs: @abs_top_builddir@/gst-libs/gst/policy/libgstpolicy-@GST_MAJORMINOR@.la
+Cflags: -I@abs_top_srcdir@/gst-libs -I@abs_top_builddir@/gst-libs
+
diff --git a/pkgconfig/gstreamer-policy.pc.in b/pkgconfig/gstreamer-policy.pc.in
new file mode 100644 (file)
index 0000000..9ede774
--- /dev/null
@@ -0,0 +1,16 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/gstreamer-@GST_MAJORMINOR@
+datarootdir=${prefix}/share
+datadir=${datarootdir}
+girdir=${datadir}/gir-1.0
+typelibdir=${libdir}/girepository-1.0
+
+Name: GStreamer Policy Library
+Description: Helper functions and base classes for policy integration
+Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@
+Version: @VERSION@
+Libs: -L${libdir} -lgstpolicy-@GST_MAJORMINOR@
+Cflags: -I${includedir}
+
index 3280ba3..f3d9bb9 100644 (file)
@@ -131,6 +131,7 @@ check_PROGRAMS = \
        elements/playbin \
        elements/playbin2 \
        elements/playbin2-compressed \
+    elements/policy \
        $(check_subparse) \
        elements/videorate \
        elements/videoscale \
@@ -376,6 +377,9 @@ elements_gdppay_LDADD = $(GST_GDP_LIBS) $(LDADD)
 elements_playbin_LDADD = $(GST_BASE_LIBS) $(LDADD)
 elements_playbin_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
 
+elements_policy_LDADD = $(GST_BASE_LIBS) $(LDADD)
+elements_policy_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
+
 elements_playbin2_LDADD = $(GST_BASE_LIBS) $(LDADD)
 elements_playbin2_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
 
diff --git a/tests/check/elements/policy.c b/tests/check/elements/policy.c
new file mode 100644 (file)
index 0000000..f444b79
--- /dev/null
@@ -0,0 +1,113 @@
+/* GStreamer
+ * Copyright (C) <2012> 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gst/check/gstcheck.h>
+#include <gst/policy/gstpolicy.h>
+
+
+static void
+test_pads (GstElement * policy)
+{
+  GstPad *sinkpad1;
+  GstPad *sinkpad2;
+
+  sinkpad1 = gst_element_get_request_pad (policy, "sink_%d");
+  assert_equals_int (policy->numpads, 2);
+  assert_equals_int (policy->numsinkpads, 1);
+  assert_equals_int (policy->numsrcpads, 1);
+
+  sinkpad2 = gst_element_get_request_pad (policy, "sink_%d");
+
+  assert_equals_int (policy->numpads, 4);
+  assert_equals_int (policy->numsinkpads, 2);
+  assert_equals_int (policy->numsrcpads, 2);
+
+  gst_element_release_request_pad (policy, sinkpad2);
+  g_object_unref (sinkpad2);
+  assert_equals_int (policy->numpads, 2);
+  assert_equals_int (policy->numsinkpads, 1);
+  assert_equals_int (policy->numsrcpads, 1);
+
+  gst_element_release_request_pad (policy, sinkpad1);
+  g_object_unref (sinkpad1);
+  assert_equals_int (policy->numpads, 0);
+  assert_equals_int (policy->numsinkpads, 0);
+  assert_equals_int (policy->numsrcpads, 0);
+}
+
+GST_START_TEST (test_autopolicy)
+{
+  GstElement *policy;
+  const gchar *role1;
+  gchar *role2;
+
+  policy = gst_check_setup_element ("autopolicy");
+
+  test_pads (policy);
+
+  role1 = "megarole";
+  gst_child_proxy_set (GST_OBJECT (policy), "actual-policy::role", role1,
+      NULL);
+  gst_child_proxy_get (GST_OBJECT (policy), "actual-policy::role", &role2,
+      NULL);
+  assert_equals_string (role1, role2);
+  g_free (role2);
+
+  gst_check_teardown_element (policy);
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_defaultpolicy)
+{
+  GstElement *policy;
+  const gchar *role1;
+  gchar *role2;
+
+  policy = gst_check_setup_element ("defaultpolicy");
+
+  test_pads (policy);
+
+  role1 = "megarole";
+  g_object_set (policy, "role", role1, NULL);
+  g_object_get (policy, "role", &role2, NULL);
+  assert_equals_string (role1, role2);
+  g_free (role2);
+
+  gst_check_teardown_element (policy);
+}
+
+GST_END_TEST;
+
+static Suite *
+policy_suite (void)
+{
+  Suite *s = suite_create ("policy");
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_defaultpolicy);
+  tcase_add_test (tc_chain, test_autopolicy);
+
+  return s;
+}
+
+GST_CHECK_MAIN (policy);