<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yui_3_16_0_ym19_1_1505226458817_4846">Hello,</div><div id="yui_3_16_0_ym19_1_1505226458817_4851"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_5735">I am developing a C program which uses the following pipeline</div><div id="yui_3_16_0_ym19_1_1505226458817_4889"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_4897" dir="ltr"><b id="yui_3_16_0_ym19_1_1505226458817_4896">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</b></div><div id="yui_3_16_0_ym19_1_1505226458817_4935" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_5753" dir="ltr">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).<br></div><div id="yui_3_16_0_ym19_1_1505226458817_4940" dir="ltr">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. <br></div><div id="yui_3_16_0_ym19_1_1505226458817_5782" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_5797" dir="ltr">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 "<font id="yui_3_16_0_ym19_1_1505226458817_5920" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5921">Interrupt: Stopping pipeline ..." </b>(code below) and nothing more.<br></font></div><div id="yui_3_16_0_ym19_1_1505226458817_4999" dir="ltr">The code involved in the restart handling is the following:</div><div id="yui_3_16_0_ym19_1_1505226458817_5036" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_5229" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">// global variables<br id="yui_3_16_0_ym19_1_1505226458817_5165"></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5331" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5348" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5349">// use </b></font><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">sigUsr1Watch for interrupt<br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5359" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">guint sigUsr1Watch;</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5330" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">// timeval is set when main starts, <br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5364" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">// then sum it a value in seconds<br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5360" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">time_t timeval;</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5372" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">// gstreamer loop<br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5373" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">GMainLoop *loop;</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5375" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">// restart control variable<br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5376" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">gboolean restart;<br id="yui_3_16_0_ym19_1_1505226458817_5169"><br id="yui_3_16_0_ym19_1_1505226458817_5170">// GstData is the struct containing the pipeline elements<br id="yui_3_16_0_ym19_1_1505226458817_5171">gboolean irqUsr1Handler(GstData *user_data)<br id="yui_3_16_0_ym19_1_1505226458817_5172">{<br id="yui_3_16_0_ym19_1_1505226458817_5173"> GstElement *pipeline = (GstElement *) user_data->pipeline;<br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5679" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> GstElement *appsink = (GstElement *) user_data->appsink;<br id="yui_3_16_0_ym19_1_1505226458817_5175"><br id="yui_3_16_0_ym19_1_1505226458817_5176"> g_print("Interrupt: Stopping pipeline ...\n");<br id="yui_3_16_0_ym19_1_1505226458817_5177"> // stop emitting signals from appsink<br id="yui_3_16_0_ym19_1_1505226458817_5178"> gst_app_sink_set_emit_signals(GST_APP_SINK(appsink), false);</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5819" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> // send EOS to the pipeline<br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5838" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> gst_element_send_event(pipeline, gst_event_new_eos());<br id="yui_3_16_0_ym19_1_1505226458817_5180"><br id="yui_3_16_0_ym19_1_1505226458817_5181"> restart = true;<br id="yui_3_16_0_ym19_1_1505226458817_5182"> sigUsr1Watch = 0;<br id="yui_3_16_0_ym19_1_1505226458817_5183"> return ELR_INTERRUPT;<br id="yui_3_16_0_ym19_1_1505226458817_5184">}<br id="yui_3_16_0_ym19_1_1505226458817_5185"></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_6013" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"><br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_6012" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_6036" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_6037">// </b></font><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"><font id="yui_3_16_0_ym19_1_1505226458817_6038" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_6039">dataProbe is the appsink callback function,</b></font></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_6076" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"><font id="yui_3_16_0_ym19_1_1505226458817_6038" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_6039">// executed when "new-sample" signal is catched<br></b></font></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_6040" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"><font id="yui_3_16_0_ym19_1_1505226458817_6038" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_6039"></b></font>GstFlowReturn dataProbe(GstElement *source)<br id="yui_3_16_0_ym19_1_1505226458817_5187">{ <br id="yui_3_16_0_ym19_1_1505226458817_5188"> g_print("data probe\n");<br id="yui_3_16_0_ym19_1_1505226458817_5189"> GstMapInfo map;<br id="yui_3_16_0_ym19_1_1505226458817_5190"> GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(source));<br id="yui_3_16_0_ym19_1_1505226458817_5191"> GstBuffer *buffer = gst_sample_get_buffer(sample);<br id="yui_3_16_0_ym19_1_1505226458817_5192"> gst_buffer_ref(buffer);<br id="yui_3_16_0_ym19_1_1505226458817_5193"> gst_buffer_map (buffer, &map, GST_MAP_READ);<br id="yui_3_16_0_ym19_1_1505226458817_5194"> <br id="yui_3_16_0_ym19_1_1505226458817_5195"> // do something with map.data here ...<br id="yui_3_16_0_ym19_1_1505226458817_5196"><br id="yui_3_16_0_ym19_1_1505226458817_5197"> gst_buffer_unmap(buffer, &map);<br id="yui_3_16_0_ym19_1_1505226458817_5198"> gst_buffer_unref(buffer);<br id="yui_3_16_0_ym19_1_1505226458817_5199"> gst_sample_unref(sample);<br id="yui_3_16_0_ym19_1_1505226458817_5200"></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5402" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> <br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5401" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> // check if time is elapsed<br></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5406" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> if(time(NULL) > timeval)<br id="yui_3_16_0_ym19_1_1505226458817_5202"> raise(SIGUSR1);<br id="yui_3_16_0_ym19_1_1505226458817_5203"><br id="yui_3_16_0_ym19_1_1505226458817_5204"> return GST_FLOW_OK;<br id="yui_3_16_0_ym19_1_1505226458817_5205">}<br id="yui_3_16_0_ym19_1_1505226458817_5206"></b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_6080" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_6079" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">// Gst Bus message handler function</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_6090" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_6105" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_6106">// here I catch the </b></font><font id="yui_3_16_0_ym19_1_1505226458817_6107" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_6108">GST_MESSAGE_EOS</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_6091" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237">gboolean gstMsgHandler(GstBus *bus, GstMessage *message, gpointer user_data)<br id="yui_3_16_0_ym19_1_1505226458817_5208">{<br id="yui_3_16_0_ym19_1_1505226458817_5209"> GstElement *pipeline = (GstElement *) user_data;<br id="yui_3_16_0_ym19_1_1505226458817_5210"><br id="yui_3_16_0_ym19_1_1505226458817_5211"> switch (GST_MESSAGE_TYPE (message))<br id="yui_3_16_0_ym19_1_1505226458817_5212"> {</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5425" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> case GST_MESSAGE_EOS:<br id="yui_3_16_0_ym19_1_1505226458817_5214"> {</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5450" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5441" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5442"> // we have received the EOS.</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5464" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5469" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5470"> </b></font><font id="yui_3_16_0_ym19_1_1505226458817_5481" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5480">// we can stop the loop, close the pipeline and restart everything.</b></font><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"><font id="yui_3_16_0_ym19_1_1505226458817_5437" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5438"> </b></font> </b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5427" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5318" face="Courier New, courier, monaco, monospace, sans-serif"><b id="yui_3_16_0_ym19_1_1505226458817_5237"> g_print("Got EOS from element \"%s\".\n", GST_MESSAGE_SRC_NAME (message));<br id="yui_3_16_0_ym19_1_1505226458817_5216"> if (restart && g_main_loop_is_running(loop))<br id="yui_3_16_0_ym19_1_1505226458817_5217"> {<br id="yui_3_16_0_ym19_1_1505226458817_5218"> g_main_loop_quit(loop);<br id="yui_3_16_0_ym19_1_1505226458817_5219"> g_main_loop_unref(loop);<br id="yui_3_16_0_ym19_1_1505226458817_5220"> }<br id="yui_3_16_0_ym19_1_1505226458817_5221"> break;<br id="yui_3_16_0_ym19_1_1505226458817_5222"> }<br id="yui_3_16_0_ym19_1_1505226458817_5223"> default:<br id="yui_3_16_0_ym19_1_1505226458817_5224"> break;<br id="yui_3_16_0_ym19_1_1505226458817_5225"> }<br id="yui_3_16_0_ym19_1_1505226458817_5226"><br id="yui_3_16_0_ym19_1_1505226458817_5227"> return true;<br id="yui_3_16_0_ym19_1_1505226458817_5228">}</b></font></div><div id="yui_3_16_0_ym19_1_1505226458817_5539" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_5548" dir="ltr"><font id="yui_3_16_0_ym19_1_1505226458817_5547" face="HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif">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:</font></div><div id="yui_3_16_0_ym19_1_1505226458817_5609" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_5610" dir="ltr"><b id="yui_3_16_0_ym19_1_1505226458817_5608">v4l2src device=/dev/webcam !
videoconvert ! video/x-raw,width=544,height=288 ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/path/to/video.mp4 <br></b></div><div id="yui_3_16_0_ym19_1_1505226458817_5618" dir="ltr"><b id="yui_3_16_0_ym19_1_1505226458817_5608"><br></b></div><div id="yui_3_16_0_ym19_1_1505226458817_5578" dir="ltr">everything works fine and I am able to restart the pipeline correctly.<br></div><div id="yui_3_16_0_ym19_1_1505226458817_5727" dir="ltr">Is the appsink causing these problems ?<br></div><div id="yui_3_16_0_ym19_1_1505226458817_5690" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1505226458817_5691" dir="ltr">What is the correct way to handle interrupt and signals in presence of multiple queues like my situation ?<br></div><div id="yui_3_16_0_ym19_1_1505226458817_5726" dir="ltr">Thank you in advance.</div><div id="yui_3_16_0_ym19_1_1505226458817_5725" dir="ltr">Regards,</div><div id="yui_3_16_0_ym19_1_1505226458817_5724" dir="ltr">Simon<br></div></div></body></html>