How to correctly handle interrupts with multiple queues (using appsink) ?
simo zz
simon.zz at yahoo.com
Tue Sep 12 15:31:30 UTC 2017
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_EOSgboolean 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20170912/c40e326b/attachment-0001.html>
More information about the gstreamer-devel
mailing list