SRC caps negotiation

Dr. Peter G. Baum peter at dr-baum.net
Sat Sep 27 00:23:52 PDT 2014


Hi,

despite having read
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-nego-usecases.html
I still don't get the details of the caps negotiation right.

I want to fix bug https://bugzilla.gnome.org/show_bug.cgi?id=735627, 
that means implement two different wav formats depending on the 
negotiated output format of the wavenc plug-in with a preference to the 
current "audio/x-wav".

I thought, that in the code below I could get the proposed format and 
set the preferred one in "gst_wavenc_src_setcaps". But the if clause in 
this function is never entered.

Any pointer welcome,

Peter



diff --git a/gst/wavenc/gstwavenc.c b/gst/wavenc/gstwavenc.c
index 4bcccf2..a2fd310 100644
--- a/gst/wavenc/gstwavenc.c
+++ b/gst/wavenc/gstwavenc.c
@@ -96,6 +96,9 @@ typedef struct
      "rate = (int) [ 8000, 192000 ], "    \
      "channels = (int) [ 1, 2 ]"

+#define SRC_CAPS \
+    "audio/x-wav; " \
+    "audio/x-rf64"

  static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE 
("sink",
      GST_PAD_SINK,
@@ -106,7 +109,7 @@ static GstStaticPadTemplate sink_factory = 
GST_STATIC_PAD_TEMPLATE ("sink",
  static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
      GST_PAD_SRC,
      GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-wav")
+    GST_STATIC_CAPS (SRC_CAPS)
      );

  #define gst_wavenc_parent_class parent_class
@@ -122,6 +125,7 @@ static gboolean gst_wavenc_event (GstPad * pad, 
GstObject * parent,
  static GstStateChangeReturn gst_wavenc_change_state (GstElement * element,
      GstStateChange transition);
  static gboolean gst_wavenc_sink_setcaps (GstPad * pad, GstCaps * caps);
+static gboolean gst_wavenc_src_setcaps (GstPad *pad,  GstObject 
*parent, GstEvent *event );

  static void
  gst_wavenc_class_init (GstWavEncClass * klass)
@@ -144,6 +148,46 @@ gst_wavenc_class_init (GstWavEncClass * klass)
    GST_DEBUG_CATEGORY_INIT (wavenc_debug, "wavenc", 0, "WAV encoder 
element");
  }

+static gboolean
+gst_wavenc_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+  GstWavEnc *wavenc;
+  gboolean ret = FALSE;
+
+  wavenc = GST_WAVENC (parent);
+
+  GST_DEBUG_OBJECT (wavenc, "Got %s query on pad %s: %s",
+      GST_QUERY_TYPE_NAME (query), GST_DEBUG_PAD_NAME (pad));
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_CAPS:
+    {
+      GstCaps *caps, *filter;
+      GstStaticCaps staticCaps = GST_STATIC_CAPS (SRC_CAPS);
+
+      /* caps = gst_pad_get_allowed_caps (wavenc->srcpad); */
+      caps = gst_static_caps_get (&staticCaps);
+      GST_DEBUG_OBJECT (wavenc, "allowed %" GST_PTR_FORMAT, caps);
+      gst_query_parse_caps (query, &filter);
+      if (filter) {
+        GstCaps *temp = gst_caps_intersect (caps, filter);
+        gst_caps_unref (caps);
+        caps = temp;
+        GST_DEBUG_OBJECT (wavenc, "filtered %" GST_PTR_FORMAT, caps);
+      }
+      gst_query_set_caps_result (query, caps);
+      gst_caps_unref (caps);
+      ret = TRUE;
+    }
+    default:
+      ret = gst_pad_query_default (pad, parent, query);
+      break;
+  }
+
+  return ret;
+
+}
+
  static void
  gst_wavenc_init (GstWavEnc * wavenc)
  {
@@ -157,8 +201,15 @@ gst_wavenc_init (GstWavEnc * wavenc)

    wavenc->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
    gst_pad_use_fixed_caps (wavenc->srcpad);
+  gst_pad_set_query_function (wavenc->srcpad,
+      GST_DEBUG_FUNCPTR (gst_wavenc_src_query));
+  gst_pad_set_event_function (wavenc->srcpad,
+      GST_DEBUG_FUNCPTR (gst_wavenc_src_setcaps));
+
+  /*
    gst_pad_set_caps (wavenc->srcpad,
        gst_static_pad_template_get_caps (&src_factory));
+  */
    gst_element_add_pad (GST_ELEMENT (wavenc), wavenc->srcpad);
  }

@@ -377,6 +428,19 @@ gst_wavenc_push_header (GstWavEnc * wavenc)
  }

  static gboolean
+gst_wavenc_src_setcaps (GstPad *pad,  GstObject *parent, GstEvent *event )
+{
+  GstCaps *caps;
+  GstWavEnc * wavenc = GST_WAVENC (parent);
+
+  if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS) {
+     gst_event_parse_caps (event, &caps);
+     GST_DEBUG_OBJECT (wavenc, "src caps are %" GST_PTR_FORMAT, caps);
+  }
+  return gst_pad_event_default (pad, parent, event);
+}
+
+static gboolean
  gst_wavenc_sink_setcaps (GstPad * pad, GstCaps * caps)
  {
    GstWavEnc *wavenc;


More information about the gstreamer-devel mailing list