Hi,
This is my first post to the mailing list so if something's wrong please let me know. I googled and searched mailing list for similar problems, tried lots of things but could not find a solution to my problem. I have a very simple pipeline as below: videotestsrc ! tee name=t t. ! queue ! autovideosink I know tee is not required here but this is a test app for my future development. I start, stop display and quit application via command line. When I run the app, nothing is displayed initially as per my design. Problem is, when I try to quit the app when it is not in displaying state, ending the app via 'q' button not works. program is stuck on line: gst_element_send_event(pipeline, gst_event_new_eos()); no eos message is received on message bus callback. My guess is something goes wrong when I block tee_src pad. To test, just run the app and press 'q' on command line. Can someone please check? Below is the code: #include <gst/gst.h> #include <iostream> #include <thread> using namespace std; static gboolean message_cb (GstBus * bus, GstMessage * message, gpointer user_data) { g_message ("get message %s", gst_structure_get_name (gst_message_get_structure(message))); GMainLoop* loop = (GMainLoop*)user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR:{ // cout << "error message received" << endl; break; } case GST_MESSAGE_WARNING:{ // cout << "warning message received" << endl; break; } case GST_MESSAGE_EOS: { // cout << "eos message received" << endl; g_main_loop_quit (loop); break; } case GST_MESSAGE_ELEMENT: { // cout << "element message received" << endl; const GstStructure *s = gst_message_get_structure (message); if (gst_structure_has_name (s, "GstBinForwarded")) { GstMessage *forward_msg = NULL; gst_structure_get (s, "message", GST_TYPE_MESSAGE, &forward_msg, NULL); if (GST_MESSAGE_TYPE (forward_msg) == GST_MESSAGE_EOS) { g_print ("EOS from element %s\n", GST_OBJECT_NAME (GST_MESSAGE_SRC (forward_msg))); cout << "forwarded eos message received" << endl; g_main_loop_quit (loop); } gst_message_unref (forward_msg); } break; } default: break; } return TRUE; } // TODO: TEST: GstPad *tee_pad; GstPad *queue_pad; GstElement *pipeline; GstElement *queue; GstElement *sink; GstElement *tee; static GstPadProbeReturn event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { GST_INFO_OBJECT(pad, "event to pad"); if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) != GST_EVENT_EOS) return GST_PAD_PROBE_PASS; gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info)); gst_element_set_state(sink, GST_STATE_NULL); gst_element_set_state(queue, GST_STATE_NULL); gst_bin_remove_many(GST_BIN(pipeline), queue, sink, nullptr); return GST_PAD_PROBE_DROP; } static GstPadProbeReturn pad_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { GST_INFO_OBJECT(pad, "pad is blocked now"); cout << "pad is blocked now" << endl; gst_pad_add_probe (queue_pad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM), event_probe_cb, nullptr, nullptr); gst_pad_send_event(queue_pad, gst_event_new_eos()); return GST_PAD_PROBE_OK; } // videotestsrc ! tee name=t t. ! queue ! autovideosink int main(int argc, char *argv[]) { gst_init (&argc, &argv); gst_debug_set_default_threshold(GST_LEVEL_INFO); /*GstElement **/pipeline = gst_pipeline_new("test_pipeline"); g_object_set (pipeline, "message-forward", TRUE, NULL); GstElement *src = gst_element_factory_make("videotestsrc", nullptr); //g_object_set (src, "is-live", TRUE, NULL); tee = gst_element_factory_make("tee", nullptr); queue = gst_element_factory_make("queue", nullptr); sink = gst_element_factory_make("autovideosink", nullptr); g_object_set (sink, "sync", false, NULL); if( !pipeline || !src || !tee || !queue || !sink ) { cout << "elements could not be created!" << endl; return -1; } // add only src & tee to pipeline gst_bin_add_many(GST_BIN(pipeline), src, tee, nullptr); // link src, tee if(!gst_element_link_many(src, tee, nullptr)) { cout << "src tee link error" << endl; return -1; } /*GstPad **/tee_pad = gst_element_get_request_pad(tee, "src_%u"); /*GstPad **/queue_pad = gst_element_get_static_pad(queue, "sink"); //gulong probe_id = 0; // block tee src pad: gulong probe_id = gst_pad_add_probe (tee_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, nullptr, nullptr, nullptr); gst_element_set_state (pipeline, GST_STATE_PLAYING); GMainLoop *loop = g_main_loop_new (NULL, FALSE); gst_bus_add_watch (GST_ELEMENT_BUS (pipeline), message_cb, loop); thread t([loop](){ g_main_loop_run (loop); }); while(true) { char c; cin >> c; if(c == 'r') { gst_bin_add_many(GST_BIN(pipeline), (GstElement*)gst_object_ref (queue), (GstElement*)gst_object_ref (sink), nullptr); gst_element_sync_state_with_parent(queue); gst_element_sync_state_with_parent(sink); // link queue, sink if(!gst_element_link_many(tee, queue, sink, nullptr)) { cout << "tee queue sink link error" << endl; return -1; } gst_pad_remove_probe(tee_pad, probe_id); //probe_id = 0; } else if(c == 's') { probe_id = gst_pad_add_probe (tee_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, pad_probe_cb, nullptr, nullptr); } else if(c == 'q') { //gst_debug_set_default_threshold(GST_LEVEL_MAX); gst_element_send_event(pipeline, gst_event_new_eos()); break; } } t.join(); return 0; } Below is the command line output when I set debug threashold to max after pressing 'q' to exit app: 0:00:02.132823400 13916 00000201FD013F90 DEBUG GST_EVENT gstevent.c:306:gst_event_new_custom: creating new event 00000201FD1F11C0 eos 28174 0:00:02.134604600 13916 00000201FD013F90 DEBUG GST_ELEMENT_PADS gstelement.c:1856:gst_element_send_event: send eos event on element test_pipeline 0:00:02.135451500 13916 00000201FD013F90 DEBUG bin gstbin.c:3133:gst_bin_send_event:<test_pipeline> Sending eos event to src children 0:00:02.136695000 13916 00000201FD013F90 DEBUG GST_STATES gstbin.c:2030:bin_element_is_src:<test_pipeline> child tee0 is not src 0:00:02.137556600 13916 00000201FD013F90 DEBUG GST_STATES gstbin.c:2030:bin_element_is_src:<test_pipeline> child videotestsrc0 is src 0:00:02.138103500 13916 00000201FD013F90 TRACE GST_REFCOUNTING gstminiobject.c:355:gst_mini_object_ref: 00000201FD1F11C0 ref 1->2 0:00:02.138812400 13916 00000201FD013F90 DEBUG GST_ELEMENT_PADS gstelement.c:1856:gst_element_send_event: send eos event on element videotestsrc0 0:00:02.140035900 13916 00000201FD013F90 DEBUG basesrc gstbasesrc.c:1786:gst_base_src_send_event:<videotestsrc0> handling event 00000201FD1F11C0 eos event: 00000201FD1F11C0, time 99:99:99.999999999, seq-num 21, (NULL) 0:00:02.140539300 13916 00000201FD013F90 DEBUG basesrc gstbasesrc.c:3679:gst_base_src_set_flushing:<videotestsrc0> flushing 1 <== stuck here Thanks in advance, Umit -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |