When, where and how to set caps for a source plugin

Tim Müller tim at centricular.com
Thu Feb 12 13:15:24 PST 2015


On Wed, 2015-02-11 at 13:50 +0100, Peter Maersk-Moller wrote:

Hi Peter,

> I'm writing a couple of plugins for GStreamer for reading and writing
> raw video streams to and from a video mixer. It is largely based on
> the shm plugins.
> 
> 
> For the source plugin initially the its source pad is defined is
> initially defined as a static pad template as written in the plugin
> documentation:
> 
> static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE
> ("src",
>     GST_PAD_SRC,
>     GST_PAD_ALWAYS,
>     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE("video/x-raw ") \
>         ", format=(string)BGRA"
>         ", interlace-mode=(string)progressive"
>         ", height = " GST_VIDEO_SIZE_RANGE
>         ", width = " GST_VIDEO_SIZE_RANGE
>         ", framerate= " GST_VIDEO_FPS_RANGE)
>     );
> 
> 
> Should I use "src" or "mypluginsrc" in GST_STATIC_PAD_TEMPLATE(...)?

"src". It's the name of the pad. If there is only one src pad, it is
customarily called "src". You are free to call it whatever you want of
course, technically.

> Anyway this part works okay. Now the tricky part is that the plugin,
> when used in a pipeline will detect height, width and framerate and
> set its caps on the source pad according to this and forward the
> mandated caps settings downstream. My problem I need some help with is
> to identify when, where and how to set the caps for the source pad.
> Can you help?
> 
> 
> In my case the caps of the pad must be fixed, when the plugin is
> started whatever startet means. In the documentation I read that I
> should use gst_pad_use_fixed_caps() so in the init sections of the
> plugin, I have the following code:
> 
>     self->srcpad = gst_pad_new_from_static_template(&srctemplate,
> "src");
>     gst_pad_use_fixed_caps(self->srcpad);
> 
> 
> I also in the init section sets the query function
> 
>     gst_pad_set_query_function(self->srcpad, gst_myplugin_src_query);

If I may stop you right there: is there a good reason why you are not
deriving from GstBaseSrc or GstPushSrc ?

 Regards
  -Tim

> However the query functions does not seems to be called when using the
> plugin. Anyway the idea is now to set the fixed caps for the pad when
> the plugin/element changes state. In the documentation is says that
> the element should allocate non-stream specific data. I read this as I
> should not set fixed caps when the element changes state from NULL to
> READY. So I try to set the caps when the element changes state from
> READY to PAUSED:
> 
> gst_myplugin_src_change_state (GstElement * element, GstStateChange
> transition)
> {
>   ....
>   switch (transition) {
>     case GST_STATE_CHANGE_NULL_TO_READY:
>       break;
>     case GST_STATE_CHANGE_READY_TO_PAUSED:
>       caps = gst_caps_new_simple ("video/x-raw",
>         "format", G_TYPE_STRING, "BGRA",
>         "width", G_TYPE_INT, "1024",
>         "height", G_TYPE_INT, "576",
>         NULL);
>       g_message(">>> SNOWMIXSRC Pads setting\n");
>       if (!gst_pad_set_caps (self->srcpad, caps)) {
>       GST_ELEMENT_ERROR (element, CORE, NEGOTIATION, (NULL),
>           ("Failed to set caps on source"));
>       }
> 
> 
> In the final code, the width, height and framerate depends on external
> settings in another program of course. Now when I compile and install
> the plugin and use the following pipeline to test it, it fails to set
> the caps. So obviously I am not setting the caps correctly and quite
> likely not at the right place.
> 
> 
> Testing plugin:
> 
> 
>     gst-launch-1.0 -v mypluginsrc socket-path=something is-live=true !
> queue ! fakesink
> 
> 
> Result:
> 
>   Setting pipeline to PAUSED ...
> ** Message: >>> MYPLUGINSRC CHANGE STATE Null to Ready
> 
> ** Message: >>> MYPLUGINSRC CHANGE STATE Ready to Pause
> 
> ** Message: >>> MYPLUGINSRC Pads setting
> 
> ** Message: >>> MYPLUGINSRC Pads setting error
> 
> Pipeline is live and does not need PREROLL ...
> /GstPipeline:pipeline0/GstMypluginSrc:mypluginsrc0.GstPad:src: caps =
> "video/x-raw\,\ format\=\(string\)BGRA\,\ width\=\(int\)1\,\ height\=
> \(int\)1\,\ framerate\=\(fraction\)0/1\,\ interlace-mode\=\(string
> \)progressive"
> ERROR: from
> element /GstPipeline:pipeline0/GstMypluginSrc:mypluginsrc0: GStreamer
> error: negotiation problem.
> Additional debug info:
> gstmypluginsrc.c(596): gst_myplugin_src_change_state
> (): /GstPipeline:pipeline0/GstMypluginSrc:mypluginsrc0:
> Failed to set caps on source
> ERROR: pipeline doesn't want to preroll.
> Setting pipeline to PAUSED ...
> ** Message: >>> MYPLUGINSRC CHANGE STATE Other
> 
> /GstPipeline:pipeline0/GstQueue:queue0.GstPad:src: caps = "video/x-raw
> \,\ format\=\(string\)BGRA\,\ width\=\(int\)1\,\ height\=\(int\)1\,\
> framerate\=\(fraction\)0/1\,\ interlace-mode\=\(string\)progressive"
> Setting pipeline to READY ...
> 
> 
> The extra messages is generated with g_message(..) in the state change
> code.

> sktop.org/mailman/listinfo/gstreamer-devel

-- 
Tim Müller, Centricular Ltd - http://www.centricular.com



More information about the gstreamer-devel mailing list