gst/autodetect/gstautoaudiosink.*: Add property to filter sinks based on caps. Only...
authorTommi Myöhänen <ext-tommi.myohanen@nokia.com>
Wed, 5 Dec 2007 16:02:15 +0000 (16:02 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 5 Dec 2007 16:02:15 +0000 (16:02 +0000)
Original commit message from CVS:
Patch by: Tommi Myöhänen  <ext-tommi dot myohanen at nokia dot com>
* gst/autodetect/gstautoaudiosink.c:
(gst_auto_audio_sink_class_init), (gst_auto_audio_sink_dispose),
(gst_auto_audio_sink_init), (gst_auto_audio_sink_find_best),
(gst_auto_audio_sink_set_property),
(gst_auto_audio_sink_get_property):
* gst/autodetect/gstautoaudiosink.h:
Add property to filter sinks based on caps. Only select raw audio sinks
by default for backwards compat.  Fixes #417420.
API: GstAutoAudioSink::filter-caps

ChangeLog
gst/autodetect/gstautoaudiosink.c
gst/autodetect/gstautoaudiosink.h

index c39e34f..86c35fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2007-12-05  Wim Taymans  <wim.taymans@gmail.com>
+
+       Patch by: Tommi Myöhänen  <ext-tommi dot myohanen at nokia dot com>
+
+       * gst/autodetect/gstautoaudiosink.c:
+       (gst_auto_audio_sink_class_init), (gst_auto_audio_sink_dispose),
+       (gst_auto_audio_sink_init), (gst_auto_audio_sink_find_best),
+       (gst_auto_audio_sink_set_property),
+       (gst_auto_audio_sink_get_property):
+       * gst/autodetect/gstautoaudiosink.h:
+       Add property to filter sinks based on caps. Only select raw audio sinks
+       by default for backwards compat.  Fixes #417420.
+       API: GstAutoAudioSink::filter-caps
+
 2007-11-29  Michael Smith <msmith@fluendo.com>
 
        Patch by: Arek Korbik <arkadini@gmail.com>
index 8ab5f40..dc3b480 100644 (file)
 #include "gstautoaudiosink.h"
 #include "gstautodetect.h"
 
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_CAPS,
+};
+
 static GstStateChangeReturn
 gst_auto_audio_sink_change_state (GstElement * element,
     GstStateChange transition);
 static void gst_auto_audio_sink_dispose (GstAutoAudioSink * sink);
 static void gst_auto_audio_sink_clear_kid (GstAutoAudioSink * sink);
+static void gst_auto_audio_sink_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_auto_audio_sink_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
 
 GST_BOILERPLATE (GstAutoAudioSink, gst_auto_audio_sink, GstBin, GST_TYPE_BIN);
 
@@ -90,6 +101,26 @@ gst_auto_audio_sink_class_init (GstAutoAudioSinkClass * klass)
   gobject_class->dispose =
       (GObjectFinalizeFunc) GST_DEBUG_FUNCPTR (gst_auto_audio_sink_dispose);
   eklass->change_state = GST_DEBUG_FUNCPTR (gst_auto_audio_sink_change_state);
+  gobject_class->set_property =
+      GST_DEBUG_FUNCPTR (gst_auto_audio_sink_set_property);
+  gobject_class->get_property =
+      GST_DEBUG_FUNCPTR (gst_auto_audio_sink_get_property);
+
+  /**
+   * GstAutoAudioSink:filter-caps
+   *
+   * This property will filter out candidate sinks that can handle the specified
+   * caps. By default only audio sinks that support raw floating point and
+   * integer audio are selected.
+   *
+   * This property can only be set before the element goes to the READY state.
+   *
+   * Since: 0.10.7
+   **/
+  g_object_class_install_property (gobject_class, PROP_CAPS,
+      g_param_spec_boxed ("filter-caps", "Filter caps",
+          "Filter sink candidates using these caps.", GST_TYPE_CAPS,
+          G_PARAM_READWRITE));
 }
 
 static void
@@ -97,6 +128,10 @@ gst_auto_audio_sink_dispose (GstAutoAudioSink * sink)
 {
   gst_auto_audio_sink_clear_kid (sink);
 
+  if (sink->filter_caps)
+    gst_caps_unref (sink->filter_caps);
+  sink->filter_caps = NULL;
+
   G_OBJECT_CLASS (parent_class)->dispose ((GObject *) sink);
 }
 
@@ -114,7 +149,6 @@ gst_auto_audio_sink_clear_kid (GstAutoAudioSink * sink)
  * Hack to make initial linking work; ideally, this'd work even when
  * no target has been assigned to the ghostpad yet.
  */
-
 static void
 gst_auto_audio_sink_reset (GstAutoAudioSink * sink)
 {
@@ -132,6 +166,9 @@ gst_auto_audio_sink_reset (GstAutoAudioSink * sink)
   gst_object_unref (targetpad);
 }
 
+static GstStaticCaps raw_caps =
+    GST_STATIC_CAPS ("audio/x-raw-int; audio/x-raw-float");
+
 static void
 gst_auto_audio_sink_init (GstAutoAudioSink * sink,
     GstAutoAudioSinkClass * g_class)
@@ -141,6 +178,10 @@ gst_auto_audio_sink_init (GstAutoAudioSink * sink,
 
   gst_auto_audio_sink_reset (sink);
 
+  /* set the default raw audio caps */
+  sink->filter_caps = gst_static_caps_get (&raw_caps);
+
+  /* mark as sink */
   GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_IS_SINK);
 }
 
@@ -208,6 +249,9 @@ gst_auto_audio_sink_find_best (GstAutoAudioSink * sink)
   GstMessage *message = NULL;
   GSList *errors = NULL;
   GstBus *bus = gst_bus_new ();
+  GstPad *el_pad = NULL;
+  GstCaps *el_caps = NULL, *intersect = NULL;
+  gboolean no_match = TRUE;
 
   list = gst_registry_feature_filter (gst_registry_get_default (),
       (GstPluginFeatureFilter) gst_auto_audio_sink_factory_filter, FALSE, sink);
@@ -226,6 +270,30 @@ gst_auto_audio_sink_find_best (GstAutoAudioSink * sink)
       GstStateChangeReturn ret;
 
       GST_DEBUG_OBJECT (sink, "Testing %s", GST_PLUGIN_FEATURE (f)->name);
+
+      /* If autoaudiosink has been provided with filter caps,
+       * accept only sinks that match with the filter caps */
+      if (sink->filter_caps) {
+        el_pad = gst_element_get_static_pad (GST_ELEMENT (el), "sink");
+        el_caps = gst_pad_get_caps (el_pad);
+        gst_object_unref (el_pad);
+        GST_DEBUG_OBJECT (sink,
+            "Checking caps: %" GST_PTR_FORMAT " vs. %" GST_PTR_FORMAT,
+            sink->filter_caps, el_caps);
+        intersect = gst_caps_intersect (sink->filter_caps, el_caps);
+        no_match = gst_caps_is_empty (intersect);
+        gst_caps_unref (el_caps);
+        gst_caps_unref (intersect);
+
+        if (no_match) {
+          GST_DEBUG_OBJECT (sink, "Incompatible caps");
+          gst_object_unref (el);
+          continue;
+        } else {
+          GST_DEBUG_OBJECT (sink, "Found compatible caps");
+        }
+      }
+
       gst_element_set_bus (el, bus);
       ret = gst_element_set_state (el, GST_STATE_READY);
       if (ret == GST_STATE_CHANGE_SUCCESS) {
@@ -334,3 +402,38 @@ gst_auto_audio_sink_change_state (GstElement * element,
 
   return ret;
 }
+
+static void
+gst_auto_audio_sink_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (object);
+
+  switch (prop_id) {
+    case PROP_CAPS:
+      if (sink->filter_caps)
+        gst_caps_unref (sink->filter_caps);
+      sink->filter_caps = gst_caps_copy (gst_value_get_caps (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_auto_audio_sink_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (object);
+
+  switch (prop_id) {
+    case PROP_CAPS:{
+      gst_value_set_caps (value, sink->filter_caps);
+      break;
+    }
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
index 36defb8..2e5085f 100644 (file)
@@ -43,6 +43,7 @@ typedef struct _GstAutoAudioSink {
   /* explicit pointers to stuff used */
   GstPad *pad;
   GstElement *kid;
+  GstCaps *filter_caps;
 } GstAutoAudioSink;
 
 typedef struct _GstAutoAudioSinkClass {