Hi,
I'm having a problem with dynamically linked elements. My pipeline is gst-launch-1.0 rtspsrc location=rtsp://root:root@10.128.1.88/axis-media/media.amp?videocodec=h264 latency=0 ! rtph264depay ! h264parse ! queue ! vaapidecode ! glimagesink When closing the pipeline I get the following debug messages (GST_DEBUG=3): Execution ended after 0:00:02.282472788 Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... 0:00:02.913797906 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:5477:gst_rtspsrc_try_send:<rtspsrc0> receive interrupted 0:00:02.913841639 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:7500:gst_rtspsrc_pause:<rtspsrc0> PAUSE interrupted 0:00:02.922788913 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:5477:gst_rtspsrc_try_send:<rtspsrc0> receive interrupted 0:00:02.922838980 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:6971:gst_rtspsrc_close:<rtspsrc0> TEARDOWN interrupted Freeing pipeline ... Otherwise this wouldn't bother me, but I'm making an application that changes the camera source quite frequently. This behavior causes the application to crash (actually the whole machine crashes) after a while it has been changing the rtsp streams. The dynamic pad linking happens in the following way: static void onPadAdded(GstElement *element, GstPad *pad, gpointer data) { gchar *name; name = gst_pad_get_name(pad); g_print("A new pad %s was created\n", name); // here, you would setup a new pad link for the newly created pad // sooo, now find that rtph264depay is needed and link them? GstCaps * p_caps = gst_pad_get_pad_template_caps (pad); gchar * description = gst_caps_to_string(p_caps); g_print("Caps, %s .\n", description); // std::cout << p_caps << ", " << description << std::endl; g_free(description); GstElement *depay = GST_ELEMENT(data); // try to link the pads then ... if(gst_element_link_pads(element, name, depay, "sink") == 0) { g_print("cb_new_rtspsrc_pad : failed to link elements \n"); } g_free(name); } Never mind the comments, it's copied and modified from some forum. My question is that am I doing the linking correctly? The same debug messages can be seen using just the gst-launch pipeline. Thanks, Joona PS. I'll post a runnable example as a reply. |
Okay, here's an example:
#include <gst/gst.h> static void onPadAdded(GstElement *element, GstPad *pad, gpointer data) { gchar *name; name = gst_pad_get_name(pad); g_print("A new pad %s was created\n", name); // here, you would setup a new pad link for the newly created pad // sooo, now find that rtph264depay is needed and link them? GstCaps * p_caps = gst_pad_get_pad_template_caps (pad); gchar * description = gst_caps_to_string(p_caps); // std::cout << p_caps << ", " << description << std::endl; g_free(description); GstElement *depay = GST_ELEMENT(data); // try to link the pads then ... if(gst_element_link_pads(element, name, depay, "sink") == 0) { g_print("cb_new_rtspsrc_pad : failed to link elements \n"); } g_free(name); } static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: g_print ("End-of-stream\n"); g_main_loop_quit (loop); break; case GST_MESSAGE_ERROR: { gchar *debug = NULL; GError *err = NULL; gst_message_parse_error (msg, &err, &debug); g_print ("Error: %s\n", err->message); g_error_free (err); if (debug) { g_print ("Debug details: %s\n", debug); g_free (debug); } g_main_loop_quit (loop); break; } default: break; } return TRUE; } gint main (gint argc, gchar *argv[]) { GstStateChangeReturn ret; GstElement *pipeline, *rtspsrc, *depayer, *parser, *queue, *decoder, *filter, *sink; GMainLoop *loop; GstBus *bus; guint watch_id; char *uri1 = "rtsp://root:root@10.128.1.88/axis-media/media.amp"; // char *uri2 = "rtsp://root:root@10.128.1.82/axis-media/media.amp"; /* initialization */ gst_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); /* create elements */ pipeline = gst_pipeline_new ("my_pipeline"); /* watch for messages on the pipeline's bus (note that this will only * work like this when a GLib main loop is running) */ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); watch_id = gst_bus_add_watch (bus, bus_call, loop); gst_object_unref (bus); rtspsrc = gst_element_factory_make ("rtspsrc", "my_source"); depayer = gst_element_factory_make ("rtph264depay", "my_depayer"); parser = gst_element_factory_make ("h264parse", "my_parser"); queue = gst_element_factory_make ("queue", "my_queue"); decoder = gst_element_factory_make ("vaapidecode", "my_decoder"); filter = gst_element_factory_make ("videoconvert", "my_filter"); sink = gst_element_factory_make ("glimagesink", "my_sink"); if (!sink || !decoder) { g_print ("Decoder or output could not be found - check your install\n"); return -1; } else if (!depayer || !parser || !queue) { g_print ("Could not create audioconvert or audioresample element, " "check your installation\n"); return -1; } else if (!filter) { g_print ("Your self-written filter could not be found. Make sure it " "is installed correctly in $(libdir)/gstreamer-1.0/ or " "~/.gstreamer-1.0/plugins/ and that gst-inspect-1.0 lists it. " "If it doesn't, check with 'GST_DEBUG=*:2 gst-inspect-1.0' for " "the reason why it is not being loaded."); return -1; } g_object_set (G_OBJECT (rtspsrc), "location", uri1, NULL); g_object_set (G_OBJECT (rtspsrc), "latency", 0, NULL); g_signal_connect(G_OBJECT(rtspsrc), "pad-added", G_CALLBACK(onPadAdded), depayer); gst_bin_add_many (GST_BIN (pipeline), rtspsrc, depayer, parser, queue, decoder, filter, sink, NULL); /* link everything together */ if (!gst_element_link_many (depayer, parser, queue, decoder, filter, sink, NULL)) { g_print ("Failed to link one or more elements!\n"); return -1; } /* run */ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { GstMessage *msg; g_print ("Failed to start up pipeline!\n"); /* check if there is an error message with details on the bus */ msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0); if (msg) { GError *err = NULL; gst_message_parse_error (msg, &err, NULL); g_print ("ERROR: %s\n", err->message); g_error_free (err); gst_message_unref (msg); } return -1; } g_main_loop_run (loop); /* clean up */ gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); g_source_remove (watch_id); g_main_loop_unref (loop); return 0; } |
In reply to this post by Joona Laine
0:00:02.913797906 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:5477:gst_rtspsrc_try_send:<rtspsrc0> receive interrupted
0:00:02.913841639 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:7500:gst_rtspsrc_pause:<rtspsrc0> PAUSE interrupted 0:00:02.922788913 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:5477:gst_rtspsrc_try_send:<rtspsrc0> receive interrupted 0:00:02.922838980 6077 0x1c07320 WARN rtspsrc gstrtspsrc.c:6971:gst_rtspsrc_close:<rtspsrc0> TEARDOWN interrupted Okay, so one thing seems to be certain. The above warnings come when I set the pipeline to GST_STATE_NULL. If I only set them to PAUSED then I don't get any warnings but no resources can be freed until the pipeline is in the NULL state. Any help would be highly appreciated. |
Free forum by Nabble | Edit this page |