[gst-devel] element with one always sink pad and two request src pads

Mattias Barthel mattiasbarthel at gmail.com
Thu Mar 19 10:29:40 CET 2009


Hello,
I am trying to build an element that is a video transformer. It will
transform in a way that depends on downstream
elements (external dependencies). The sink pad has voxelVideo as caps
and the two src pads have video/x-raw-rgb and video/x-raw-short
respectively. The video/x-raw-short is just a 16bit/pixel 1 channel
video used for a disparity map.


When I try to get negotiated caps in the chain function, this fails.

Code:
-----
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",

GST_PAD_SINK,

GST_PAD_ALWAYS,
                   GST_STATIC_CAPS ("videoVoxel/x-raw-gray, "
                   "width = (int) [ 16, 4096 ], "
                                   "height = (int) [ 16, 4096 ], "
                                   "voxelDepth = (int) [ 1, 4096 ], "
                                   "framerate = (fraction) [ 0/1,
2147483647/1 ]"));


static GstStaticPadTemplate src_factory_rgb = GST_STATIC_PAD_TEMPLATE("src_rgb",
                                                                  GST_PAD_SRC,

GST_PAD_REQUEST,
                   GST_STATIC_CAPS ("video/x-raw-rgb, "
                   "width = (int) [ 16, 4096 ], "
                    "bpp = (int) 24, "
                                   "height = (int) [ 16, 4096 ], "
                                   "framerate = (fraction) [ 0/1,
2147483647/1 ]"));

static GstStaticPadTemplate src_factory_short =
GST_STATIC_PAD_TEMPLATE("src_short",
                                                                  GST_PAD_SRC,

GST_PAD_REQUEST,
                   GST_STATIC_CAPS ("video/x-raw-short, "
                   "width = (int) [ 16, 4096 ], "
                    "bpp = (int) 16, "
                                   "height = (int) [ 16, 4096 ], "
                                   "framerate = (fraction) [ 0/1,
2147483647/1 ]"));
-----

/* initialize the plugin's class */
static void
gst_tidvoxelrend_class_init (GsttidvoxelrendClass * klass) {
...
   gstelement_class->request_new_pad = gst_vrender_request_new_pad;
....
}
---------
static void gst_tidvoxelrend_base_init (gpointer gclass)
{
...

   gst_element_class_add_pad_template(element_class,
gst_static_pad_template_get (&sink_factory));
    gst_element_class_add_pad_template(element_class,
gst_static_pad_template_get (&src_factory_rgb));
    gst_element_class_add_pad_template(element_class,
gst_static_pad_template_get (&src_factory_short));
    gst_element_class_set_details(element_class, &element_details);
...

}
------------
static GstPad *
gst_vrender_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name)
{
    Gsttidvoxelrend *vrender = GST_TIDVOXELREND (element);
    GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
    GstPad *pad;

    GST_DEBUG("RENDER :::::::::: new pad");

    g_return_val_if_fail (templ != NULL, NULL);

    if (templ->direction != GST_PAD_SRC) {
    GST_WARNING_OBJECT (vrender, "request pad is not a SRC pad");
    return NULL;
    }



    if (templ == gst_element_class_get_pad_template (klass, "src_rgb")) {
    if (vrender->srcpad_rgb)
        return NULL;

    vrender->srcpad_rgb = gst_pad_new_from_template (templ, "src_rgb");

    gst_pad_set_setcaps_function (vrender->srcpad_rgb,
                      GST_DEBUG_FUNCPTR (gst_tidvoxelrend_set_caps_rgb));

    pad = vrender->srcpad_rgb;

    } else if (templ == gst_element_class_get_pad_template (klass,
"src_short")) {
    if (vrender->srcpad_short)
        return NULL;

    vrender->srcpad_short = gst_pad_new_from_template (templ, "src_short");

    gst_pad_set_setcaps_function (vrender->srcpad_short,
                      GST_DEBUG_FUNCPTR (gst_tidvoxelrend_set_caps_short));

    pad = vrender->srcpad_short;

    } else {
    g_return_val_if_reached (NULL);
    }

    gst_element_add_pad (element, pad);
    return pad;
}
-----
static void gst_tidvoxelrend_init(Gsttidvoxelrend * filter,
GsttidvoxelrendClass * gclass)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (filter);

  GST_DEBUG("In gst_tidvoxelrend_init");

  goodtimestamp                 = GOODTIMESTAMP;
  goodduration                  = GOODDURATION;
  gst_tidvoxelrend_pad_id      = GST_TIDVOXELREND_PAD_ID;


  /* Src pad config */
  filter->sinkpad = gst_pad_new_from_template
(gst_element_class_get_pad_template (klass, "sink"), "sink");

  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
  gst_pad_set_chain_function (filter->sinkpad, gst_tidvoxelrend_chain);
....
}
---------------
static GstFlowReturn gst_tidvoxelrend_chain (GstPad * pad, GstBuffer * buf)
{
  GstCaps *debugcaps = NULL;
  GstStructure *structure;
  GList *pads;
  GstBuffer *outbuf = NULL;
  size_t outsize = 0;
  int rgb = 0;
  Gsttidvoxelrend *vrender = (Gsttidvoxelrend *) gst_pad_get_parent (pad);



  pads = GST_ELEMENT_CAST (vrender)->srcpads;


  while (pads) {
      GstPad *pad;

    pad = GST_PAD_CAST (pads->data);

      GST_DEBUG("RENDER :::::::::: pad name = %s", GST_PAD_NAME(pad));

      /* We get the already negotiated caps to reapply them on the src pad */
      debugcaps = gst_pad_get_negotiated_caps(pad);

      GST_DEBUG("RENDER :::::::::: after get_negotiated_caps");

      /* Get output buffer size */

      structure = gst_caps_get_structure (debugcaps, 0);

      GST_DEBUG("RENDER :::::::::: after caps_get_structure");


      if (strstr (GST_PAD_NAME(pad), "src_rgb")) {
          outsize = vrender->out_width * vrender->out_height * 3;
          rgb = 1;
      }
      else {
          outsize = vrender->out_width * vrender->out_height * 2;
          rgb = 0;
      }

      if( gst_pad_alloc_buffer_and_set_caps (pad,
                                             GST_BUFFER_OFFSET_NONE,
                                             outsize,
                                             debugcaps,
                                             &outbuf) != GST_FLOW_OK )

................

}
----------------



When I try to run this element with one fakesink afterwards:

gstlaunch someplugins !  tidvoxelrend  name=rend rend. ! fakesink dump=true

I get:


0:00:01.427001861 25832 0x7fd6b0002f00 DEBUG         tidvoxelrend
voxelRenderer/gsttidvoxelrend.c:606:gst_tidvoxelrend_chain: RENDER
:::::::::: pad name = src_rgb
0:00:01.427033240 25832 0x7fd6b0002f00 DEBUG         tidvoxelrend
voxelRenderer/gsttidvoxelrend.c:611:gst_tidvoxelrend_chain: RENDER
:::::::::: after get_negotiated_caps

(gst-launch-0.10:25832): GStreamer-CRITICAL **:
gst_caps_get_structure: assertion `GST_IS_CAPS (caps)' failed
0:00:01.427112209 25832 0x7fd6b0002f00 DEBUG         tidvoxelrend
voxelRenderer/gsttidvoxelrend.c:617:gst_tidvoxelrend_chain: RENDER
:::::::::: after caps_get_structure



What could be wrong here, please?


Thanks in advance,


Mattias



-- 
Mattias Barthel




More information about the gstreamer-devel mailing list