Hello, I am developing a C program which uses the following pipeline v4l2src device=/dev/webcam ! videoconvert ! video/x-raw,width=544,height=288 ! tee name=t ! queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/path/to/video.mp4 t. ! queue ! appsink and I need to restart the pipeline every N seconds, which involves sending an EOS to the pipeline so the video can be closed (otherwise I will not be able to play with a media player). I decided to handle the restart from the appsink callback function, since I can control the timeout each time I receive a "new-sample" to appsink. The problem I am stuck on is that the interrupt is catched, but the program hangs, the EOS message in never received and nothing happens. The program remain locked showing the string "Interrupt: Stopping pipeline ..." (code below) and nothing more. The code involved in the restart handling is the following: // global variables // use sigUsr1Watch for interrupt guint sigUsr1Watch; // timeval is set when main starts, // then sum it a value in seconds time_t timeval; // gstreamer loop GMainLoop *loop; // restart control variable gboolean restart; // GstData is the struct containing the pipeline elements gboolean irqUsr1Handler(GstData *user_data) { GstElement *pipeline = (GstElement *) user_data->pipeline; GstElement *appsink = (GstElement *) user_data->appsink; g_print("Interrupt: Stopping pipeline ...\n"); // stop emitting signals from appsink gst_app_sink_set_emit_signals(GST_APP_SINK(appsink), false); // send EOS to the pipeline gst_element_send_event(pipeline, gst_event_new_eos()); restart = true; sigUsr1Watch = 0; return ELR_INTERRUPT; } // dataProbe is the appsink callback function, // executed when "new-sample" signal is catched GstFlowReturn dataProbe(GstElement *source) { g_print("data probe\n"); GstMapInfo map; GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(source)); GstBuffer *buffer = gst_sample_get_buffer(sample); gst_buffer_ref(buffer); gst_buffer_map (buffer, &map, GST_MAP_READ); // do something with map.data here ... gst_buffer_unmap(buffer, &map); gst_buffer_unref(buffer); gst_sample_unref(sample); // check if time is elapsed if(time(NULL) > timeval) raise(SIGUSR1); return GST_FLOW_OK; } // Gst Bus message handler function // here I catch the GST_MESSAGE_EOS gboolean gstMsgHandler(GstBus *bus, GstMessage *message, gpointer user_data) { GstElement *pipeline = (GstElement *) user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: { // we have received the EOS. // we can stop the loop, close the pipeline and restart everything. g_print("Got EOS from element \"%s\".\n", GST_MESSAGE_SRC_NAME (message)); if (restart && g_main_loop_is_running(loop)) { g_main_loop_quit(loop); g_main_loop_unref(loop); } break; } default: break; } return true; } The problem is of course due to a bad interrupt handling in presence of the tee and queues, because with the following pipeline using filesink only for video recording: v4l2src device=/dev/webcam !
videoconvert ! video/x-raw,width=544,height=288 ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/path/to/video.mp4 everything works fine and I am able to restart the pipeline correctly. Is the appsink causing these problems ? What is the correct way to handle interrupt and signals in presence of multiple queues like my situation ? Thank you in advance. Regards, Simon _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hello. Solved. Setting the option "flush-on-eos" for each queue and configuring the pipeline with: gst_app_sink_set_drop(GST_APP_SINK(gstData->appsink), true); gst_app_sink_set_max_buffers(GST_APP_SINK(gstData->appsink), 1); do the trick. Regards, Simon El Martes 12 de septiembre de 2017 17:31, simo zz <[hidden email]> escribió: Hello, I am developing a C program which uses the following pipeline v4l2src device=/dev/webcam ! videoconvert ! video/x-raw,width=544,height=288 ! tee name=t ! queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/path/to/video.mp4 t. ! queue ! appsink and I need to restart the pipeline every N seconds, which involves sending an EOS to the pipeline so the video can be closed (otherwise I will not be able to play with a media player). I decided to handle the restart from the appsink callback function, since I can control the timeout each time I receive a "new-sample" to appsink. The problem I am stuck on is that the interrupt is catched, but the program hangs, the EOS message in never received and nothing happens. The program remain locked showing the string "Interrupt: Stopping pipeline ..." (code below) and nothing more. The code involved in the restart handling is the following: // global variables // use sigUsr1Watch for interrupt guint sigUsr1Watch; // timeval is set when main starts, // then sum it a value in seconds time_t timeval; // gstreamer loop GMainLoop *loop; // restart control variable gboolean restart; // GstData is the struct containing the pipeline elements gboolean irqUsr1Handler(GstData *user_data) { GstElement *pipeline = (GstElement *) user_data->pipeline; GstElement *appsink = (GstElement *) user_data->appsink; g_print("Interrupt: Stopping pipeline ...\n"); // stop emitting signals from appsink gst_app_sink_set_emit_signals(GST_APP_SINK(appsink), false); // send EOS to the pipeline gst_element_send_event(pipeline, gst_event_new_eos()); restart = true; sigUsr1Watch = 0; return ELR_INTERRUPT; } // dataProbe is the appsink callback function, // executed when "new-sample" signal is catched GstFlowReturn dataProbe(GstElement *source) { g_print("data probe\n"); GstMapInfo map; GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(source)); GstBuffer *buffer = gst_sample_get_buffer(sample); gst_buffer_ref(buffer); gst_buffer_map (buffer, &map, GST_MAP_READ); // do something with map.data here ... gst_buffer_unmap(buffer, &map); gst_buffer_unref(buffer); gst_sample_unref(sample); // check if time is elapsed if(time(NULL) > timeval) raise(SIGUSR1); return GST_FLOW_OK; } // Gst Bus message handler function // here I catch the GST_MESSAGE_EOS gboolean gstMsgHandler(GstBus *bus, GstMessage *message, gpointer user_data) { GstElement *pipeline = (GstElement *) user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: { // we have received the EOS. // we can stop the loop, close the pipeline and restart everything. g_print("Got EOS from element \"%s\".\n", GST_MESSAGE_SRC_NAME (message)); if (restart && g_main_loop_is_running(loop)) { g_main_loop_quit(loop); g_main_loop_unref(loop); } break; } default: break; } return true; } The problem is of course due to a bad interrupt handling in presence of the tee and queues, because with the following pipeline using filesink only for video recording: v4l2src device=/dev/webcam !
videoconvert ! video/x-raw,width=544,height=288 ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/path/to/video.mp4 everything works fine and I am able to restart the pipeline correctly. Is the appsink causing these problems ? What is the correct way to handle interrupt and signals in presence of multiple queues like my situation ? Thank you in advance. Regards, Simon _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by simo-zz
Hello, Sorry for cross-posting, I wrote too much earlier... In fact it worked one time, and no more. So this is not a solution. Regards, Simon El Martes 12 de septiembre de 2017 17:49, simo zz <[hidden email]> escribió: Hello. Solved. Setting the option "flush-on-eos" for each queue and configuring the pipeline with: gst_app_sink_set_drop(GST_APP_SINK(gstData->appsink), true); gst_app_sink_set_max_buffers(GST_APP_SINK(gstData->appsink), 1); do the trick. Regards, Simon El Martes 12 de septiembre de 2017 17:31, simo zz <[hidden email]> escribió: Hello, I am developing a C program which uses the following pipeline v4l2src device=/dev/webcam ! videoconvert ! video/x-raw,width=544,height=288 ! tee name=t ! queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/path/to/video.mp4 t. ! queue ! appsink and I need to restart the pipeline every N seconds, which involves sending an EOS to the pipeline so the video can be closed (otherwise I will not be able to play with a media player). I decided to handle the restart from the appsink callback function, since I can control the timeout each time I receive a "new-sample" to appsink. The problem I am stuck on is that the interrupt is catched, but the program hangs, the EOS message in never received and nothing happens. The program remain locked showing the string "Interrupt: Stopping pipeline ..." (code below) and nothing more. The code involved in the restart handling is the following: // global variables // use sigUsr1Watch for interrupt guint sigUsr1Watch; // timeval is set when main starts, // then sum it a value in seconds time_t timeval; // gstreamer loop GMainLoop *loop; // restart control variable gboolean restart; // GstData is the struct containing the pipeline elements gboolean irqUsr1Handler(GstData *user_data) { GstElement *pipeline = (GstElement *) user_data->pipeline; GstElement *appsink = (GstElement *) user_data->appsink; g_print("Interrupt: Stopping pipeline ...\n"); // stop emitting signals from appsink gst_app_sink_set_emit_signals(GST_APP_SINK(appsink), false); // send EOS to the pipeline gst_element_send_event(pipeline, gst_event_new_eos()); restart = true; sigUsr1Watch = 0; return ELR_INTERRUPT; } // dataProbe is the appsink callback function, // executed when "new-sample" signal is catched GstFlowReturn dataProbe(GstElement *source) { g_print("data probe\n"); GstMapInfo map; GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(source)); GstBuffer *buffer = gst_sample_get_buffer(sample); gst_buffer_ref(buffer); gst_buffer_map (buffer, &map, GST_MAP_READ); // do something with map.data here ... gst_buffer_unmap(buffer, &map); gst_buffer_unref(buffer); gst_sample_unref(sample); // check if time is elapsed if(time(NULL) > timeval) raise(SIGUSR1); return GST_FLOW_OK; } // Gst Bus message handler function // here I catch the GST_MESSAGE_EOS gboolean gstMsgHandler(GstBus *bus, GstMessage *message, gpointer user_data) { GstElement *pipeline = (GstElement *) user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: { // we have received the EOS. // we can stop the loop, close the pipeline and restart everything. g_print("Got EOS from element \"%s\".\n", GST_MESSAGE_SRC_NAME (message)); if (restart && g_main_loop_is_running(loop)) { g_main_loop_quit(loop); g_main_loop_unref(loop); } break; } default: break; } return true; } The problem is of course due to a bad interrupt handling in presence of the tee and queues, because with the following pipeline using filesink only for video recording: v4l2src device=/dev/webcam !
videoconvert ! video/x-raw,width=544,height=288 ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/path/to/video.mp4 everything works fine and I am able to restart the pipeline correctly. Is the appsink causing these problems ? What is the correct way to handle interrupt and signals in presence of multiple queues like my situation ? Thank you in advance. Regards, Simon _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I finally solved using the g_timeout_add function. It helps me to do exactly what I need and it works like a sharm.. Here a link to an example: Regards, Simon _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hey, one thing that might help (I don't know what you are trying
to accomplish), but if you just need to rotate to a new file after
a certain period of time / file size, there is an element
splitmuxsink That might be what you are looking for!
On 9/12/2017 11:18 AM, simo zz wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hi, this is fantastic, that's what I need. I will test it as soon as possible ! Thank you Michael. Regards, Simon El Martes 12 de septiembre de 2017 22:01, Michael MacIntosh <[hidden email]> escribió: Hey, one thing that might help (I don't know what you are trying
to accomplish), but if you just need to rotate to a new file after
a certain period of time / file size, there is an element
splitmuxsink
That might be what you are looking for!
On 9/12/2017 11:18 AM, simo zz wrote:
I
finally solved using the g_timeout_add function.
It
helps me to do exactly what I need and it works
like a sharm..
Here
a link to an example:
Regards,
Simon
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |