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

Peter Maersk-Moller pmaersk at gmail.com
Wed Feb 11 04:50:54 PST 2015


Hi.

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(...)?

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);

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.

Thanks in advance for any hints and suggestions.

Peter MM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20150211/7286f2e3/attachment.html>


More information about the gstreamer-devel mailing list