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