This post was updated on .
Thank you in advance!
This is the working gst-launch-1.0 pipeline. gst-launch-1.0 rtspsrc port-range=5000-5100 location=rtsp://192.168.1.10:8555/right latency=0 ! decodebin ! videoconvert ! video/x-raw,width=640,height=480,format=YUY2 ! autovideosink The following is the NOT working C function. int startPipeline(const char *vs_location) { GstElement *pipeline; GstBus *bus; guint bus_watch_id; gst_init(NULL, NULL); pipeline = gst_pipeline_new("my_pipeline"); bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); bus_watch_id = gst_bus_add_watch(bus, bus_callback, NULL); gst_object_unref(bus); GstElement *source, *dec_bin, *v_conv, *sink; source = gst_element_factory_make("rtspsrc", "source"); dec_bin = gst_element_factory_make("decodebin", "dec_bin"); v_conv = gst_element_factory_make("videoconvert", "v_con"); sink = gst_element_factory_make("autovideosink", "sink"); gst_bin_add_many(GST_BIN(pipeline), source, dec_bin, v_conv, sink, NULL); // Set element properties. g_object_set(G_OBJECT(source), "port-range", "5000-5100", NULL); g_object_set(G_OBJECT(source), "location", vs_location, NULL); g_object_set(G_OBJECT(source), "latency", 0, NULL); gst_element_link_many(source, dec_bin, v_conv, NULL); GstCaps *caps; caps = gst_caps_new_simple( "video/x-raw", "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 480, "format", G_TYPE_STRING, "YUY2", NULL); gst_element_link_filtered(v_conv, sink, caps); gst_caps_unref(caps); gst_element_set_state(pipeline, GST_STATE_PLAYING); loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); // Clean up. gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); g_source_remove(bus_watch_id); g_main_loop_unref(loop); return 0; } Then the Errors are here. 0:00:00.442295071 16407 0x7f007c01e940 FIXME default gstutils.c:3825:gst_pad_create_stream_id_internal:<fakesrc0:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id 0:00:00.455584401 16407 0x7f006c0025e0 FIXME rtpjitterbuffer gstrtpjitterbuffer.c:1395:gst_jitter_buffer_sink_parse_caps:<rtpjitterbuffer0> Unsupported timestamp reference clock 0:00:00.455616947 16407 0x7f006c0025e0 FIXME rtpjitterbuffer gstrtpjitterbuffer.c:1403:gst_jitter_buffer_sink_parse_caps:<rtpjitterbuffer0> Unsupported media clock 0:00:00.457236636 16407 0x7f006c0025e0 WARN basesrc gstbasesrc.c:2947:gst_base_src_loop:<udpsrc0> error: Internal data flow error. 0:00:00.457268553 16407 0x7f006c0025e0 WARN basesrc gstbasesrc.c:2947:gst_base_src_loop:<udpsrc0> error: streaming task paused, reason not-linked (-1) Error: Internal data flow error. Debug: gstbasesrc.c(2947): gst_base_src_loop (): /GstPipeline:my_pipeline/GstRTSPSrc:source/GstUDPSrc:udpsrc0: streaming task paused, reason not-linked (-1) 0:00:00.458046376 16407 0x10af5e0 WARN rtspsrc gstrtspsrc.c:5520:gst_rtspsrc_try_send:<source> receive interrupted 0:00:00.458083322 16407 0x10af5e0 WARN rtspsrc gstrtspsrc.c:7546:gst_rtspsrc_pause:<source> PAUSE interrupted |
Hi Zheng
Whenever possible, I use gst_parse_launch to avoid these types of complications. This is what gst-launch uses underneath, so if it works on one it should work on the other. Specifically in your example: int startPipeline(const char *vs_location) { GstElement *pipeline; GstBus *bus; guint bus_watch_id; gchar *pipe_desc; GError *error = NULL; gst_init(NULL, NULL); pipe_desc = g_strdup_printf("rtspsrc port-range=5000-5100 location=%s latency=0 ! decodebin ! videoconvert ! video/x-raw,width=640,height=480,format=YUY2 ! autovideosink”, vs_location); pipeline = gst_parse_launch (pipe_desc, &error); //Handle errors here g_free (pipe_desc); bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); bus_watch_id = gst_bus_add_watch(bus, bus_callback, NULL); gst_object_unref(bus); gst_element_set_state(pipeline, GST_STATE_PLAYING); loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); // Clean up. gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); g_source_remove(bus_watch_id); g_main_loop_unref(loop); return 0; } — Michael Gruner <[hidden email]> Embedded Linux and GStreamer solutions RidgeRun Engineering Contact Us - http://www.ridgerun.com/#!contact/c3vn
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by Zheng
On Do, 2016-06-16 at 18:45 -0700, Zheng wrote:
> *Thang you in advance!* > > *This is the working gst-launch-1.0 pipeline.* > > gst-launch-1.0 rtspsrc port-range=5000-5100 > location=rtsp://192.168.1.10:8555/right latency=0 ! decodebin ! > videoconvert > ! video/x-raw,width=640,height=480,format=YUY2 ! autovideosink > > *The following is the NOT working C function.* > [...] that one or more of the links are actually failing, which seems to be the underlying problem here. The pipeline fails because a pad is producing data but it is not linked downstream. -- Sebastian Dröge, Centricular Ltd · http://www.centricular.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel signature.asc (968 bytes) Download Attachment |
Thanks! @Sebastian Dröge-3 and @Michael Gruner
The problem is exactly the one Sebastian said. The rtspsrc's sink pad is not a static one. So a on_pad_added callback function is needed. The following is the working C functions. static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) { gchar *name; name = gst_pad_get_name(pad); g_print("A new pad %s was created.\n", name); g_free(name); GstPad *sinkpad; GstElement *downstream = (GstElement *) data; sinkpad = gst_element_get_static_pad(downstream, "sink"); gst_pad_link (pad, sinkpad); gst_object_unref(sinkpad); } int startPipeline(const char *vs_location, const char *socket_path) { puts(vs_location); puts(socket_path); GstElement *pipeline; GstBus *bus; guint bus_watch_id; gst_init(NULL, NULL); pipeline = gst_pipeline_new("my_pipeline"); bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); bus_watch_id = gst_bus_add_watch(bus, bus_callback, NULL); gst_object_unref(bus); GstElement *source, *dec_bin, *v_conv, *sink; source = gst_element_factory_make("rtspsrc", "source"); dec_bin = gst_element_factory_make("decodebin", "dec_bin"); v_conv = gst_element_factory_make("videoconvert", "v_con"); sink = gst_element_factory_make("autovideosink", "sink"); gst_bin_add_many(GST_BIN(pipeline), source, dec_bin, v_conv, sink, NULL); // Set element properties. g_object_set(G_OBJECT(source), "port-range", "5000-5100", NULL); g_object_set(G_OBJECT(source), "location", vs_location, NULL); g_object_set(G_OBJECT(source), "latency", 0, NULL); g_signal_connect(source, "pad-added", G_CALLBACK(on_pad_added), dec_bin); g_signal_connect(dec_bin, "pad-added", G_CALLBACK(on_pad_added), v_conv); GstCaps *caps; caps = gst_caps_new_simple( "video/x-raw", "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 480, "format", G_TYPE_STRING, "YUY2", NULL); if(gst_element_link_filtered(v_conv, sink, caps) == FALSE) { g_printerr("Error: gst_element_link_filtered() failed.\n"); gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); g_source_remove(bus_watch_id); return -1; } gst_caps_unref(caps); gst_element_set_state(pipeline, GST_STATE_PLAYING); loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); // Clean up. gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); g_source_remove(bus_watch_id); g_main_loop_unref(loop); return 0; } |
Free forum by Nabble | Edit this page |