[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