SRC caps negotiation

Dr. Peter G. Baum peter at dr-baum.net
Sat Sep 27 05:17:25 PDT 2014


That looks good! Many thanks, Tim.

I was sure there was an easy way :-)

Peter


On 09/27/2014 11:37 AM, Tim Müller wrote:
> 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
>
> _______________________________________________
> 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