<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yiv4107434724"><!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]--><div id="yui_3_16_0_1_1504192874455_2486"><div id="yui_3_16_0_1_1504192874455_2485" style="color:#000;background-color:#fff;font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px;"><div id="yiv4107434724"><!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]--><div id="yiv4107434724yui_3_16_0_1_1504184226553_4882"><div id="yiv4107434724yui_3_16_0_1_1504184226553_4881" style="color:#000;background-color:#fff;font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px;"><div id="yiv4107434724"><div id="yiv4107434724yui_3_16_0_1_1504184226553_2567"><div id="yiv4107434724yui_3_16_0_1_1504184226553_2566" style="color:#000;background-color:#fff;font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px;"><div id="yiv4107434724yui_3_16_0_1_1504175479485_6908">Hello,</div><div id="yiv4107434724yui_3_16_0_1_1504175479485_6914"><br></div><div dir="ltr" id="yiv4107434724yui_3_16_0_1_1504175479485_6988"><div id="yui_3_16_0_1_1504192874455_2620" dir="ltr">I need to implement the following pipeline (successfully tested with <b>gst-launch-1.0 -e</b>) using C API:<br></div></div><div id="yiv4107434724yui_3_16_0_1_1504175479485_7190" dir="ltr"><br></div><div id="yiv4107434724yui_3_16_0_1_1504175479485_7191" dir="ltr"><div id="yui_3_16_0_1_1504192874455_2565" dir="ltr"><b id="yiv4107434724yui_3_16_0_1_1504175479485_7194">v4l2src device=/dev/webcam ! videoconvert ! video/x-raw,width=544,height=288,framerate=10/1 ! tee name=t ! queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=video.mp4 t. ! queue ! decodebin ! videoconvert ! pngenc ! multifilesink location=file%6d.png</b></div></div><div id="yiv4107434724yui_3_16_0_1_1504175479485_8542" dir="ltr"><div id="yiv4107434724yui_3_16_0_1_1504184226553_5412"><div id="yui_3_16_0_1_1504192874455_2737"><br></div><div dir="ltr" id="yui_3_16_0_1_1504192874455_2640">The C code used for GstElements declaration and pipeline initialization is the following:</div><div id="yui_3_16_0_1_1504192874455_2656" dir="ltr"><br></div><b id="yui_3_16_0_1_1504192874455_3475">typedef struct _CustomData<br id="yui_3_16_0_1_1504192874455_4284">{<br id="yui_3_16_0_1_1504192874455_4285"> GstElement *pipeline;<br id="yui_3_16_0_1_1504192874455_4286"> GstElement *v4l2src;<br id="yui_3_16_0_1_1504192874455_4287"> <br id="yui_3_16_0_1_1504192874455_4288"> GstElement *tee;<br id="yui_3_16_0_1_1504192874455_4289"> // connect this pad to v4lserc<br id="yui_3_16_0_1_1504192874455_4290"> GstPadTemplate *teepadtmplate;<br id="yui_3_16_0_1_1504192874455_4291"> <br id="yui_3_16_0_1_1504192874455_4292"> // tee src pads<br id="yui_3_16_0_1_1504192874455_4293"> GstPad *teeSrcVPad;<br id="yui_3_16_0_1_1504192874455_4294"> GstPad *teeSrcIPad;<br id="yui_3_16_0_1_1504192874455_4295"><br id="yui_3_16_0_1_1504192874455_4296"> // queues sink pads<br id="yui_3_16_0_1_1504192874455_4297"> GstPad *vQueueSinkPad;<br id="yui_3_16_0_1_1504192874455_4298"> GstPad *iQueueSinkPad;<br id="yui_3_16_0_1_1504192874455_4299"><br id="yui_3_16_0_1_1504192874455_4300"> GstElement *vQueue;<br id="yui_3_16_0_1_1504192874455_4301"> GstElement *iQueue;<br id="yui_3_16_0_1_1504192874455_4302"><br id="yui_3_16_0_1_1504192874455_4303"> GstElement *decodebin;<br id="yui_3_16_0_1_1504192874455_4304"> GstElement *pngenc;<br id="yui_3_16_0_1_1504192874455_4305"><br id="yui_3_16_0_1_1504192874455_4306"> GstElement *vVideoconvert;<br id="yui_3_16_0_1_1504192874455_4307"> GstElement *iVideoconvert;<br id="yui_3_16_0_1_1504192874455_4308"><br id="yui_3_16_0_1_1504192874455_4309"> GstElement *capsfilter;<br id="yui_3_16_0_1_1504192874455_4310"> GstCaps *caps;<br id="yui_3_16_0_1_1504192874455_4311"> GstElement *v4l2h264enc;<br id="yui_3_16_0_1_1504192874455_4312"> GstElement *h264parse;<br id="yui_3_16_0_1_1504192874455_4313"> GstElement *mp4mux;<br id="yui_3_16_0_1_1504192874455_4314"> GstElement *filesink;<br id="yui_3_16_0_1_1504192874455_4315"> GstElement *multifilesink;<br id="yui_3_16_0_1_1504192874455_4316"> GstBuffer *buffer;<br id="yui_3_16_0_1_1504192874455_4317"><br id="yui_3_16_0_1_1504192874455_4318">} GstData;<br id="yui_3_16_0_1_1504192874455_4319"><br id="yui_3_16_0_1_1504192874455_4320"><br id="yui_3_16_0_1_1504192874455_4321">gboolean buildPipeline(GstData *gstData, const char *filename)<br id="yui_3_16_0_1_1504192874455_4322">{<br id="yui_3_16_0_1_1504192874455_4323"> gstData->pipeline = gst_pipeline_new ("pipeline");<br id="yui_3_16_0_1_1504192874455_4324"> if (! gstData->pipeline)<br id="yui_3_16_0_1_1504192874455_4325"> {<br id="yui_3_16_0_1_1504192874455_4326"> printf("Error creating pipeline.\n");<br id="yui_3_16_0_1_1504192874455_4327"> return false;<br id="yui_3_16_0_1_1504192874455_4328"> }<br id="yui_3_16_0_1_1504192874455_4329"> <br id="yui_3_16_0_1_1504192874455_4330"> gstData->v4l2src = gst_element_factory_make("v4l2src", NULL);<br id="yui_3_16_0_1_1504192874455_4331"> if (! gstData->v4l2src)<br id="yui_3_16_0_1_1504192874455_4332"> {<br id="yui_3_16_0_1_1504192874455_4333"> printf("Error creating v4l2src.\n");<br id="yui_3_16_0_1_1504192874455_4334"> return false;<br id="yui_3_16_0_1_1504192874455_4335"> }<br id="yui_3_16_0_1_1504192874455_4336"><br id="yui_3_16_0_1_1504192874455_4337"> gstData->tee = gst_element_factory_make("tee", "tee");<br id="yui_3_16_0_1_1504192874455_4338"> if (! gstData->tee)<br id="yui_3_16_0_1_1504192874455_4339"> {<br id="yui_3_16_0_1_1504192874455_4340"> printf("Error creating tee.\n");<br id="yui_3_16_0_1_1504192874455_4341"> return false;<br id="yui_3_16_0_1_1504192874455_4342"> }<br id="yui_3_16_0_1_1504192874455_4343"><br id="yui_3_16_0_1_1504192874455_4344"> gstData->vQueue = gst_element_factory_make("queue", NULL);<br id="yui_3_16_0_1_1504192874455_4345"> if (! gstData->vQueue)<br id="yui_3_16_0_1_1504192874455_4346"> {<br id="yui_3_16_0_1_1504192874455_4347"> printf("Error creating video queue.\n");<br id="yui_3_16_0_1_1504192874455_4348"> return false;<br id="yui_3_16_0_1_1504192874455_4349"> }<br id="yui_3_16_0_1_1504192874455_4350"><br id="yui_3_16_0_1_1504192874455_4351"> gstData->iQueue = gst_element_factory_make("queue", NULL);<br id="yui_3_16_0_1_1504192874455_4352"> if (! gstData->iQueue)<br id="yui_3_16_0_1_1504192874455_4353"> {<br id="yui_3_16_0_1_1504192874455_4354"> printf("Error creating image queue.\n");<br id="yui_3_16_0_1_1504192874455_4355"> return false;<br id="yui_3_16_0_1_1504192874455_4356"> }<br id="yui_3_16_0_1_1504192874455_4357"><br id="yui_3_16_0_1_1504192874455_4358"> gstData->decodebin = gst_element_factory_make("decodebin", NULL);<br id="yui_3_16_0_1_1504192874455_4359"> if (! gstData->decodebin)<br id="yui_3_16_0_1_1504192874455_4360"> {<br id="yui_3_16_0_1_1504192874455_4361"> printf("Error creating decodebin.\n");<br id="yui_3_16_0_1_1504192874455_4362"> return false;<br id="yui_3_16_0_1_1504192874455_4363"> }<br id="yui_3_16_0_1_1504192874455_4364"><br id="yui_3_16_0_1_1504192874455_4365"> gstData->pngenc = gst_element_factory_make("pngenc", NULL);<br id="yui_3_16_0_1_1504192874455_4366"> if (! gstData->pngenc)<br id="yui_3_16_0_1_1504192874455_4367"> {<br id="yui_3_16_0_1_1504192874455_4368"> printf("Error creating pngenc.\n");<br id="yui_3_16_0_1_1504192874455_4369"> return false;<br id="yui_3_16_0_1_1504192874455_4370"> }<br id="yui_3_16_0_1_1504192874455_4371"><br id="yui_3_16_0_1_1504192874455_4372"> gstData->iVideoconvert = gst_element_factory_make("videoconvert", NULL);<br id="yui_3_16_0_1_1504192874455_4373"> if (! gstData->iVideoconvert)<br id="yui_3_16_0_1_1504192874455_4374"> {<br id="yui_3_16_0_1_1504192874455_4375"> printf("Error creating iVideoconvert.\n");<br id="yui_3_16_0_1_1504192874455_4376"> return false;<br id="yui_3_16_0_1_1504192874455_4377"> }<br id="yui_3_16_0_1_1504192874455_4378"><br id="yui_3_16_0_1_1504192874455_4379"> gstData->vVideoconvert = gst_element_factory_make("videoconvert", NULL);<br id="yui_3_16_0_1_1504192874455_4380"> if (! gstData->vVideoconvert)<br id="yui_3_16_0_1_1504192874455_4381"> {<br id="yui_3_16_0_1_1504192874455_4382"> printf("Error creating vVideoconvert.\n");<br id="yui_3_16_0_1_1504192874455_4383"> return false;<br id="yui_3_16_0_1_1504192874455_4384"> }<br id="yui_3_16_0_1_1504192874455_4385"><br id="yui_3_16_0_1_1504192874455_4386"> gstData->capsfilter = gst_element_factory_make("capsfilter", NULL);<br id="yui_3_16_0_1_1504192874455_4387"> if (! gstData->capsfilter)<br id="yui_3_16_0_1_1504192874455_4388"> {<br id="yui_3_16_0_1_1504192874455_4389"> printf("Error creating capsfilter.\n");<br id="yui_3_16_0_1_1504192874455_4390"> return false;<br id="yui_3_16_0_1_1504192874455_4391"> }<br id="yui_3_16_0_1_1504192874455_4392"><br id="yui_3_16_0_1_1504192874455_4393"> gstData->v4l2h264enc = gst_element_factory_make("v4l2h264enc", NULL);<br id="yui_3_16_0_1_1504192874455_4394"> if (! gstData->v4l2h264enc)<br id="yui_3_16_0_1_1504192874455_4395"> {<br id="yui_3_16_0_1_1504192874455_4396"> printf("Error creating v4l2h264enc.\n");<br id="yui_3_16_0_1_1504192874455_4397"> return false;<br id="yui_3_16_0_1_1504192874455_4398"> }<br id="yui_3_16_0_1_1504192874455_4399"><br id="yui_3_16_0_1_1504192874455_4400"> gstData->h264parse = gst_element_factory_make("h264parse", NULL);<br id="yui_3_16_0_1_1504192874455_4401"> if (! gstData->h264parse)<br id="yui_3_16_0_1_1504192874455_4402"> {<br id="yui_3_16_0_1_1504192874455_4403"> printf("Error creating h264parse.\n");<br id="yui_3_16_0_1_1504192874455_4404"> return false;<br id="yui_3_16_0_1_1504192874455_4405"> }<br id="yui_3_16_0_1_1504192874455_4406"><br id="yui_3_16_0_1_1504192874455_4407"> gstData->mp4mux = gst_element_factory_make("mp4mux", NULL);<br id="yui_3_16_0_1_1504192874455_4408"> if (! gstData->mp4mux)<br id="yui_3_16_0_1_1504192874455_4409"> {<br id="yui_3_16_0_1_1504192874455_4410"> printf("Error creating mp4mux.\n");<br id="yui_3_16_0_1_1504192874455_4411"> return false;<br id="yui_3_16_0_1_1504192874455_4412"> }<br id="yui_3_16_0_1_1504192874455_4413"><br id="yui_3_16_0_1_1504192874455_4414"> gstData->filesink = gst_element_factory_make("filesink", NULL);<br id="yui_3_16_0_1_1504192874455_4415"> if (! gstData->filesink)<br id="yui_3_16_0_1_1504192874455_4416"> {<br id="yui_3_16_0_1_1504192874455_4417"> printf("Error creating filesink.\n");<br id="yui_3_16_0_1_1504192874455_4418"> return false;<br id="yui_3_16_0_1_1504192874455_4419"> }<br id="yui_3_16_0_1_1504192874455_4420"><br id="yui_3_16_0_1_1504192874455_4421"> gstData->multifilesink = gst_element_factory_make("multifilesink", NULL);<br id="yui_3_16_0_1_1504192874455_4422"> if (! gstData->multifilesink)<br id="yui_3_16_0_1_1504192874455_4423"> {<br id="yui_3_16_0_1_1504192874455_4424"> printf("Error creating multifilesink.\n");<br id="yui_3_16_0_1_1504192874455_4425"> return false;<br id="yui_3_16_0_1_1504192874455_4426"> }<br id="yui_3_16_0_1_1504192874455_4427"><br id="yui_3_16_0_1_1504192874455_4428"> g_object_set(G_OBJECT(gstData->v4l2src), "device", filename, NULL);<br id="yui_3_16_0_1_1504192874455_4429"> g_object_set(G_OBJECT(gstData->filesink), "location", "video.mp4", NULL);<br id="yui_3_16_0_1_1504192874455_4430"> g_object_set(G_OBJECT(gstData->multifilesink), "location", "file%6u.png", NULL);<br id="yui_3_16_0_1_1504192874455_4431"><br id="yui_3_16_0_1_1504192874455_4432"> gstData->caps = gst_caps_from_string(CAPS_STR);<br id="yui_3_16_0_1_1504192874455_4433"> g_object_set(G_OBJECT(gstData->capsfilter), "caps", gstData->caps, NULL);<br id="yui_3_16_0_1_1504192874455_4434"><br id="yui_3_16_0_1_1504192874455_4435"> gst_bin_add_many(GST_BIN(gstData->pipeline), gstData->v4l2src, gstData->tee, gstData->vQueue, gstData->iQueue, gstData->iVideoconvert, gstData->vVideoconvert, gstData->decodebin, gstData->pngenc, gstData->capsfilter, gstData->v4l2h264enc, gstData->h264parse, gstData->mp4mux, gstData->filesink, gstData->multifilesink, NULL);<br id="yui_3_16_0_1_1504192874455_4436"><br id="yui_3_16_0_1_1504192874455_4437"> if(gst_element_link_many(gstData->v4l2src, gstData->vVideoconvert, gstData->capsfilter, gstData->tee, NULL) != true)<br id="yui_3_16_0_1_1504192874455_4438"> {<br id="yui_3_16_0_1_1504192874455_4439"> g_print("Error linking pipeline: v4l2src ! videoconvert ! capsfilter ! tee ...\n");<br id="yui_3_16_0_1_1504192874455_4440"> return false;<br id="yui_3_16_0_1_1504192874455_4441"> }<br id="yui_3_16_0_1_1504192874455_4442"><br id="yui_3_16_0_1_1504192874455_4443"> if(gst_element_link_many(gstData->vQueue, gstData->v4l2h264enc, gstData->h264parse, gstData->mp4mux, gstData->filesink, NULL) != true)<br id="yui_3_16_0_1_1504192874455_4444"> {<br id="yui_3_16_0_1_1504192874455_4445"> g_print("Error linking pipeline: queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink ...\n");<br id="yui_3_16_0_1_1504192874455_4446"> return false;<br id="yui_3_16_0_1_1504192874455_4447"> }<br id="yui_3_16_0_1_1504192874455_4448"><br id="yui_3_16_0_1_1504192874455_4449"> // Program fails here<br id="yui_3_16_0_1_1504192874455_4450"> if(gst_element_link_many(gstData->iQueue, gstData->decodebin, gstData->iVideoconvert, gstData->pngenc, gstData->multifilesink, NULL) != true)<br id="yui_3_16_0_1_1504192874455_4451"> {<br id="yui_3_16_0_1_1504192874455_4452"> g_print("Error linking pipeline: queue ! decodebin ! videoconvert ! pngenc ! multifilesink ...\n");<br id="yui_3_16_0_1_1504192874455_4453"> return false;<br id="yui_3_16_0_1_1504192874455_4454"> }<br id="yui_3_16_0_1_1504192874455_4455"><br id="yui_3_16_0_1_1504192874455_4456"> // manually link pads<br id="yui_3_16_0_1_1504192874455_4457"> gstData->teepadtmplate = gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS (gstData->tee), "src_%u");<br id="yui_3_16_0_1_1504192874455_4458"> if (! gstData->teepadtmplate)<br id="yui_3_16_0_1_1504192874455_4459"> {<br id="yui_3_16_0_1_1504192874455_4460"> g_print("Error setting tee pad template...\n");<br id="yui_3_16_0_1_1504192874455_4461"> return false;<br id="yui_3_16_0_1_1504192874455_4462"> }<br id="yui_3_16_0_1_1504192874455_4463"> <br id="yui_3_16_0_1_1504192874455_4464"> gstData->teeSrcVPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL);<br id="yui_3_16_0_1_1504192874455_4465"> if(! gstData->teeSrcVPad)<br id="yui_3_16_0_1_1504192874455_4466"> {<br id="yui_3_16_0_1_1504192874455_4467"> g_print("Error setting tee video src pad...\n");<br id="yui_3_16_0_1_1504192874455_4468"> return false;<br id="yui_3_16_0_1_1504192874455_4469"> }<br id="yui_3_16_0_1_1504192874455_4470"><br id="yui_3_16_0_1_1504192874455_4471"> gstData->vQueueSinkPad = gst_element_get_static_pad(gstData->vQueue, "sink");<br id="yui_3_16_0_1_1504192874455_4472"> if(! gstData->vQueueSinkPad)<br id="yui_3_16_0_1_1504192874455_4473"> {<br id="yui_3_16_0_1_1504192874455_4474"> g_print("Error setting tee video sink pad...\n");<br id="yui_3_16_0_1_1504192874455_4475"> return false;<br id="yui_3_16_0_1_1504192874455_4476"> }<br id="yui_3_16_0_1_1504192874455_4477"><br id="yui_3_16_0_1_1504192874455_4478"> gstData->teeSrcIPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL);<br id="yui_3_16_0_1_1504192874455_4479"> if(! gstData->teeSrcIPad)<br id="yui_3_16_0_1_1504192874455_4480"> {<br id="yui_3_16_0_1_1504192874455_4481"> g_print("Error setting tee image src pad...\n");<br id="yui_3_16_0_1_1504192874455_4482"> return false;<br id="yui_3_16_0_1_1504192874455_4483"> }<br id="yui_3_16_0_1_1504192874455_4484"> gstData->iQueueSinkPad = gst_element_get_static_pad (gstData->iQueue, "sink");<br id="yui_3_16_0_1_1504192874455_4485"> if(! gstData->iQueueSinkPad)<br id="yui_3_16_0_1_1504192874455_4486"> {<br id="yui_3_16_0_1_1504192874455_4487"> g_print("Error setting queue image sink pad...\n");<br id="yui_3_16_0_1_1504192874455_4488"> return false;<br id="yui_3_16_0_1_1504192874455_4489"> }<br id="yui_3_16_0_1_1504192874455_4490"><br id="yui_3_16_0_1_1504192874455_4491"> if (gst_pad_link(gstData->teeSrcVPad, gstData->vQueueSinkPad) != GST_PAD_LINK_OK)<br id="yui_3_16_0_1_1504192874455_4492"> {<br id="yui_3_16_0_1_1504192874455_4493"> g_print("Error: cannot connect tee to video queue...\n");<br id="yui_3_16_0_1_1504192874455_4494"> return false;<br id="yui_3_16_0_1_1504192874455_4495"> }<br id="yui_3_16_0_1_1504192874455_4496"><br id="yui_3_16_0_1_1504192874455_4497"> if (gst_pad_link(gstData->teeSrcIPad, gstData->iQueueSinkPad) != GST_PAD_LINK_OK)<br id="yui_3_16_0_1_1504192874455_4498"> {<br id="yui_3_16_0_1_1504192874455_4499"> g_print("Error: cannot connect tee to appsink queue...\n");<br id="yui_3_16_0_1_1504192874455_4500"> return false;<br id="yui_3_16_0_1_1504192874455_4501"> }<br id="yui_3_16_0_1_1504192874455_4502"> <br id="yui_3_16_0_1_1504192874455_4503"> return 0;<br id="yui_3_16_0_1_1504192874455_4504"></b><div id="yui_3_16_0_1_1504192874455_4505" dir="ltr"><b id="yui_3_16_0_1_1504192874455_3475">}</b></div><div id="yiv4107434724yui_3_16_0_1_1504184226553_6562" dir="ltr"><div id="yui_3_16_0_1_1504192874455_3660"><br></div><div dir="ltr" id="yui_3_16_0_1_1504192874455_3693">This code is inspired from the tutorial</div><div id="yui_3_16_0_1_1504192874455_3768" dir="ltr"><br></div><div id="yui_3_16_0_1_1504192874455_3769" dir="ltr"> <a id="yui_3_16_0_1_1504192874455_3698" class="" href="https://gstreamer.freedesktop.org/documentation/tutorials/basic/short-cutting-the-pipeline.html">https://gstreamer.freedesktop.org/documentation/tutorials/basic/short-cutting-the-pipeline.html</a><br></div><div id="yui_3_16_0_1_1504192874455_3770"><br></div><div id="yui_3_16_0_1_1504192874455_3690">But I cannot understand why it fails. What's wrong with it ?<br></div></div><div id="yiv4107434724yui_3_16_0_1_1504184226553_10076" dir="ltr">Thank you in advance for your help.</div><div id="yiv4107434724yui_3_16_0_1_1504184226553_10078" dir="ltr">Simon<br></div></div></div></div></div></div></div></div></div></div></div></div></div></body></html>