Hello, I need to implement the following pipeline (successfully tested with gst-launch-1.0 -e) using C API: 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 The C code used for GstElements declaration and pipeline initialization is the following: { GstElement *pipeline; GstElement *v4l2src; GstElement *tee; // connect this pad to v4lserc GstPadTemplate *teepadtmplate; // tee src pads GstPad *teeSrcVPad; GstPad *teeSrcIPad; // queues sink pads GstPad *vQueueSinkPad; GstPad *iQueueSinkPad; GstElement *vQueue; GstElement *iQueue; GstElement *decodebin; GstElement *pngenc; GstElement *vVideoconvert; GstElement *iVideoconvert; GstElement *capsfilter; GstCaps *caps; GstElement *v4l2h264enc; GstElement *h264parse; GstElement *mp4mux; GstElement *filesink; GstElement *multifilesink; GstBuffer *buffer; } GstData; gboolean buildPipeline(GstData *gstData, const char *filename) { gstData->pipeline = gst_pipeline_new ("pipeline"); if (! gstData->pipeline) { printf("Error creating pipeline.\n"); return false; } gstData->v4l2src = gst_element_factory_make("v4l2src", NULL); if (! gstData->v4l2src) { printf("Error creating v4l2src.\n"); return false; } gstData->tee = gst_element_factory_make("tee", "tee"); if (! gstData->tee) { printf("Error creating tee.\n"); return false; } gstData->vQueue = gst_element_factory_make("queue", NULL); if (! gstData->vQueue) { printf("Error creating video queue.\n"); return false; } gstData->iQueue = gst_element_factory_make("queue", NULL); if (! gstData->iQueue) { printf("Error creating image queue.\n"); return false; } gstData->decodebin = gst_element_factory_make("decodebin", NULL); if (! gstData->decodebin) { printf("Error creating decodebin.\n"); return false; } gstData->pngenc = gst_element_factory_make("pngenc", NULL); if (! gstData->pngenc) { printf("Error creating pngenc.\n"); return false; } gstData->iVideoconvert = gst_element_factory_make("videoconvert", NULL); if (! gstData->iVideoconvert) { printf("Error creating iVideoconvert.\n"); return false; } gstData->vVideoconvert = gst_element_factory_make("videoconvert", NULL); if (! gstData->vVideoconvert) { printf("Error creating vVideoconvert.\n"); return false; } gstData->capsfilter = gst_element_factory_make("capsfilter", NULL); if (! gstData->capsfilter) { printf("Error creating capsfilter.\n"); return false; } gstData->v4l2h264enc = gst_element_factory_make("v4l2h264enc", NULL); if (! gstData->v4l2h264enc) { printf("Error creating v4l2h264enc.\n"); return false; } gstData->h264parse = gst_element_factory_make("h264parse", NULL); if (! gstData->h264parse) { printf("Error creating h264parse.\n"); return false; } gstData->mp4mux = gst_element_factory_make("mp4mux", NULL); if (! gstData->mp4mux) { printf("Error creating mp4mux.\n"); return false; } gstData->filesink = gst_element_factory_make("filesink", NULL); if (! gstData->filesink) { printf("Error creating filesink.\n"); return false; } gstData->multifilesink = gst_element_factory_make("multifilesink", NULL); if (! gstData->multifilesink) { printf("Error creating multifilesink.\n"); return false; } g_object_set(G_OBJECT(gstData->v4l2src), "device", filename, NULL); g_object_set(G_OBJECT(gstData->filesink), "location", "video.mp4", NULL); g_object_set(G_OBJECT(gstData->multifilesink), "location", "file%6u.png", NULL); gstData->caps = gst_caps_from_string(CAPS_STR); g_object_set(G_OBJECT(gstData->capsfilter), "caps", gstData->caps, NULL); 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); if(gst_element_link_many(gstData->v4l2src, gstData->vVideoconvert, gstData->capsfilter, gstData->tee, NULL) != true) { g_print("Error linking pipeline: v4l2src ! videoconvert ! capsfilter ! tee ...\n"); return false; } if(gst_element_link_many(gstData->vQueue, gstData->v4l2h264enc, gstData->h264parse, gstData->mp4mux, gstData->filesink, NULL) != true) { g_print("Error linking pipeline: queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink ...\n"); return false; } // Program fails here if(gst_element_link_many(gstData->iQueue, gstData->decodebin, gstData->iVideoconvert, gstData->pngenc, gstData->multifilesink, NULL) != true) { g_print("Error linking pipeline: queue ! decodebin ! videoconvert ! pngenc ! multifilesink ...\n"); return false; } // manually link pads gstData->teepadtmplate = gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS (gstData->tee), "src_%u"); if (! gstData->teepadtmplate) { g_print("Error setting tee pad template...\n"); return false; } gstData->teeSrcVPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL); if(! gstData->teeSrcVPad) { g_print("Error setting tee video src pad...\n"); return false; } gstData->vQueueSinkPad = gst_element_get_static_pad(gstData->vQueue, "sink"); if(! gstData->vQueueSinkPad) { g_print("Error setting tee video sink pad...\n"); return false; } gstData->teeSrcIPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL); if(! gstData->teeSrcIPad) { g_print("Error setting tee image src pad...\n"); return false; } gstData->iQueueSinkPad = gst_element_get_static_pad (gstData->iQueue, "sink"); if(! gstData->iQueueSinkPad) { g_print("Error setting queue image sink pad...\n"); return false; } if (gst_pad_link(gstData->teeSrcVPad, gstData->vQueueSinkPad) != GST_PAD_LINK_OK) { g_print("Error: cannot connect tee to video queue...\n"); return false; } if (gst_pad_link(gstData->teeSrcIPad, gstData->iQueueSinkPad) != GST_PAD_LINK_OK) { g_print("Error: cannot connect tee to appsink queue...\n"); return false; } return 0; } This code is inspired from the tutorial But I cannot understand why it fails. What's wrong with it ? Thank you in advance for your help. Simon _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Solved ! This is the correct pipeline: 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 ! videoconvert ! pngenc ! multifilesink location=file%6d.png Simon El Jueves 31 de agosto de 2017 18:23, simo zz <[hidden email]> escribió: There is an error in the return of the function buildPipeline. Should return true and of course not 0. gboolean buildPipeline(GstData *gstData, const char *filename) { gstData->pipeline = gst_pipeline_new ("pipeline"); if (! gstData->pipeline) { printf("Error creating pipeline.\n"); return false; } gstData->v4l2src = gst_element_factory_make("v4l2src", NULL); if (! gstData->v4l2src) { printf("Error creating v4l2src.\n"); return false; } gstData->tee = gst_element_factory_make("tee", "tee"); if (! gstData->tee) { printf("Error creating tee.\n"); return false; } gstData->vQueue = gst_element_factory_make("queue", NULL); if (! gstData->vQueue) { printf("Error creating video queue.\n"); return false; } gstData->iQueue = gst_element_factory_make("queue", NULL); if (! gstData->iQueue) { printf("Error creating image queue.\n"); return false; } gstData->decodebin = gst_element_factory_make("decodebin", NULL); if (! gstData->decodebin) { printf("Error creating decodebin.\n"); return false; } gstData->pngenc = gst_element_factory_make("pngenc", NULL); if (! gstData->pngenc) { printf("Error creating pngenc.\n"); return false; } gstData->iVideoconvert = gst_element_factory_make("videoconvert", NULL); if (! gstData->iVideoconvert) { printf("Error creating iVideoconvert.\n"); return false; } gstData->vVideoconvert = gst_element_factory_make("videoconvert", NULL); if (! gstData->vVideoconvert) { printf("Error creating vVideoconvert.\n"); return false; } gstData->capsfilter = gst_element_factory_make("capsfilter", NULL); if (! gstData->capsfilter) { printf("Error creating capsfilter.\n"); return false; } gstData->v4l2h264enc = gst_element_factory_make("v4l2h264enc", NULL); if (! gstData->v4l2h264enc) { printf("Error creating v4l2h264enc.\n"); return false; } gstData->h264parse = gst_element_factory_make("h264parse", NULL); if (! gstData->h264parse) { printf("Error creating h264parse.\n"); return false; } gstData->mp4mux = gst_element_factory_make("mp4mux", NULL); if (! gstData->mp4mux) { printf("Error creating mp4mux.\n"); return false; } gstData->filesink = gst_element_factory_make("filesink", NULL); if (! gstData->filesink) { printf("Error creating filesink.\n"); return false; } gstData->multifilesink = gst_element_factory_make("multifilesink", NULL); if (! gstData->multifilesink) { printf("Error creating multifilesink.\n"); return false; } g_object_set(G_OBJECT(gstData->v4l2src), "device", filename, NULL); g_object_set(G_OBJECT(gstData->filesink), "location", "video.mp4", NULL); g_object_set(G_OBJECT(gstData->multifilesink), "location", "file%6u.png", NULL); gstData->caps = gst_caps_from_string(CAPS_STR); g_object_set(G_OBJECT(gstData->capsfilter), "caps", gstData->caps, NULL); 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); if(gst_element_link_many(gstData->v4l2src, gstData->vVideoconvert, gstData->capsfilter, gstData->tee, NULL) != true) { g_print("Error linking pipeline: v4l2src ! videoconvert ! capsfilter ! tee ...\n"); return false; } if(gst_element_link_many(gstData->vQueue, gstData->v4l2h264enc, gstData->h264parse, gstData->mp4mux, gstData->filesink, NULL) != true) { g_print("Error linking pipeline: queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink ...\n"); return false; } // Program fails here if(gst_element_link_many(gstData->iQueue, gstData->decodebin, gstData->iVideoconvert, gstData->pngenc, gstData->multifilesink, NULL) != true) { g_print("Error linking pipeline: queue ! decodebin ! videoconvert ! pngenc ! multifilesink ...\n"); return false; } // manually link pads gstData->teepadtmplate = gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS (gstData->tee), "src_%u"); if (! gstData->teepadtmplate) { g_print("Error setting tee pad template...\n"); return false; } gstData->teeSrcVPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL); if(! gstData->teeSrcVPad) { g_print("Error setting tee video src pad...\n"); return false; } gstData->vQueueSinkPad = gst_element_get_static_pad(gstData->vQueue, "sink"); if(! gstData->vQueueSinkPad) { g_print("Error setting tee video sink pad...\n"); return false; } gstData->teeSrcIPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL); if(! gstData->teeSrcIPad) { g_print("Error setting tee image src pad...\n"); return false; } gstData->iQueueSinkPad = gst_element_get_static_pad (gstData->iQueue, "sink"); if(! gstData->iQueueSinkPad) { g_print("Error setting queue image sink pad...\n"); return false; } if (gst_pad_link(gstData->teeSrcVPad, gstData->vQueueSinkPad) != GST_PAD_LINK_OK) { g_print("Error: cannot connect tee to video queue...\n"); return false; } if (gst_pad_link(gstData->teeSrcIPad, gstData->iQueueSinkPad) != GST_PAD_LINK_OK) { g_print("Error: cannot connect tee to appsink queue...\n"); return false; } return true; } Simon El Jueves 31 de agosto de 2017 17:30, simo zz <[hidden email]> escribió: Hello, I need to implement the following pipeline (successfully tested with gst-launch-1.0 -e) using C API: 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 The C code used for GstElements declaration and pipeline initialization is the following: { GstElement *pipeline; GstElement *v4l2src; GstElement *tee; // connect this pad to v4lserc GstPadTemplate *teepadtmplate; // tee src pads GstPad *teeSrcVPad; GstPad *teeSrcIPad; // queues sink pads GstPad *vQueueSinkPad; GstPad *iQueueSinkPad; GstElement *vQueue; GstElement *iQueue; GstElement *decodebin; GstElement *pngenc; GstElement *vVideoconvert; GstElement *iVideoconvert; GstElement *capsfilter; GstCaps *caps; GstElement *v4l2h264enc; GstElement *h264parse; GstElement *mp4mux; GstElement *filesink; GstElement *multifilesink; GstBuffer *buffer; } GstData; gboolean buildPipeline(GstData *gstData, const char *filename) { gstData->pipeline = gst_pipeline_new ("pipeline"); if (! gstData->pipeline) { printf("Error creating pipeline.\n"); return false; } gstData->v4l2src = gst_element_factory_make("v4l2src", NULL); if (! gstData->v4l2src) { printf("Error creating v4l2src.\n"); return false; } gstData->tee = gst_element_factory_make("tee", "tee"); if (! gstData->tee) { printf("Error creating tee.\n"); return false; } gstData->vQueue = gst_element_factory_make("queue", NULL); if (! gstData->vQueue) { printf("Error creating video queue.\n"); return false; } gstData->iQueue = gst_element_factory_make("queue", NULL); if (! gstData->iQueue) { printf("Error creating image queue.\n"); return false; } gstData->decodebin = gst_element_factory_make("decodebin", NULL); if (! gstData->decodebin) { printf("Error creating decodebin.\n"); return false; } gstData->pngenc = gst_element_factory_make("pngenc", NULL); if (! gstData->pngenc) { printf("Error creating pngenc.\n"); return false; } gstData->iVideoconvert = gst_element_factory_make("videoconvert", NULL); if (! gstData->iVideoconvert) { printf("Error creating iVideoconvert.\n"); return false; } gstData->vVideoconvert = gst_element_factory_make("videoconvert", NULL); if (! gstData->vVideoconvert) { printf("Error creating vVideoconvert.\n"); return false; } gstData->capsfilter = gst_element_factory_make("capsfilter", NULL); if (! gstData->capsfilter) { printf("Error creating capsfilter.\n"); return false; } gstData->v4l2h264enc = gst_element_factory_make("v4l2h264enc", NULL); if (! gstData->v4l2h264enc) { printf("Error creating v4l2h264enc.\n"); return false; } gstData->h264parse = gst_element_factory_make("h264parse", NULL); if (! gstData->h264parse) { printf("Error creating h264parse.\n"); return false; } gstData->mp4mux = gst_element_factory_make("mp4mux", NULL); if (! gstData->mp4mux) { printf("Error creating mp4mux.\n"); return false; } gstData->filesink = gst_element_factory_make("filesink", NULL); if (! gstData->filesink) { printf("Error creating filesink.\n"); return false; } gstData->multifilesink = gst_element_factory_make("multifilesink", NULL); if (! gstData->multifilesink) { printf("Error creating multifilesink.\n"); return false; } g_object_set(G_OBJECT(gstData->v4l2src), "device", filename, NULL); g_object_set(G_OBJECT(gstData->filesink), "location", "video.mp4", NULL); g_object_set(G_OBJECT(gstData->multifilesink), "location", "file%6u.png", NULL); gstData->caps = gst_caps_from_string(CAPS_STR); g_object_set(G_OBJECT(gstData->capsfilter), "caps", gstData->caps, NULL); 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); if(gst_element_link_many(gstData->v4l2src, gstData->vVideoconvert, gstData->capsfilter, gstData->tee, NULL) != true) { g_print("Error linking pipeline: v4l2src ! videoconvert ! capsfilter ! tee ...\n"); return false; } if(gst_element_link_many(gstData->vQueue, gstData->v4l2h264enc, gstData->h264parse, gstData->mp4mux, gstData->filesink, NULL) != true) { g_print("Error linking pipeline: queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink ...\n"); return false; } // Program fails here if(gst_element_link_many(gstData->iQueue, gstData->decodebin, gstData->iVideoconvert, gstData->pngenc, gstData->multifilesink, NULL) != true) { g_print("Error linking pipeline: queue ! decodebin ! videoconvert ! pngenc ! multifilesink ...\n"); return false; } // manually link pads gstData->teepadtmplate = gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS (gstData->tee), "src_%u"); if (! gstData->teepadtmplate) { g_print("Error setting tee pad template...\n"); return false; } gstData->teeSrcVPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL); if(! gstData->teeSrcVPad) { g_print("Error setting tee video src pad...\n"); return false; } gstData->vQueueSinkPad = gst_element_get_static_pad(gstData->vQueue, "sink"); if(! gstData->vQueueSinkPad) { g_print("Error setting tee video sink pad...\n"); return false; } gstData->teeSrcIPad = gst_element_request_pad(gstData->tee, gstData->teepadtmplate, NULL, NULL); if(! gstData->teeSrcIPad) { g_print("Error setting tee image src pad...\n"); return false; } gstData->iQueueSinkPad = gst_element_get_static_pad (gstData->iQueue, "sink"); if(! gstData->iQueueSinkPad) { g_print("Error setting queue image sink pad...\n"); return false; } if (gst_pad_link(gstData->teeSrcVPad, gstData->vQueueSinkPad) != GST_PAD_LINK_OK) { g_print("Error: cannot connect tee to video queue...\n"); return false; } if (gst_pad_link(gstData->teeSrcIPad, gstData->iQueueSinkPad) != GST_PAD_LINK_OK) { g_print("Error: cannot connect tee to appsink queue...\n"); return false; } return 0; } This code is inspired from the tutorial But I cannot understand why it fails. What's wrong with it ? Thank you in advance for your help. Simon _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |