SRC caps negotiation
Tim Müller
tim at centricular.com
Sat Sep 27 02:37:06 PDT 2014
Hi Peter,
you don't need a query or event function on the src pad, it's much simpler: before you output your header buffers you do a gst_pad_get_allowed_caps(), and if the result is not fixed you truncate the caps to the first caps structure, and there you have your output caps.
Cheers
-Tim
----- Original message -----
> 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;
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
More information about the gstreamer-devel
mailing list