Search code examples
clinuxgstreamerglib

Interrupt handle is not called after added with g_unix_signal_add


I am learning about gstreamer and I have a simple program where I want to end a stream gracefully after pressing CTRL+C in Linux. For this, I've read the source code for gst-launch and saw that g_unix_signal_add() is used for adding the signals. In my code I've added the line:

signal_watch_intr_id = g_unix_signal_add (SIGINT,
                       (GSourceFunc) intr_handler, data.pipeline);

where data is a structure containing the pipeline. My handling function is:

static gboolean
intr_handler (gpointer user_data)
{
  printf("handling interrupt.\n");
  GstElement *pipeline = (GstElement *) user_data;


  /* post an application specific message */
  gst_element_post_message (GST_ELEMENT (pipeline),
      gst_message_new_application (GST_OBJECT (pipeline),
          gst_structure_new ("GstLaunchInterrupt",
              "message", G_TYPE_STRING, "Pipeline interrupted", NULL)));

  /* remove signal handler */
  signal_watch_intr_id = 0;
  return G_SOURCE_REMOVE;
}

I expect it to print "handling interrupt." to the console, make the pipeline send a GST_MESSAGE_APPLICATION type message which then will be handled to stop the pipeline. However, the application simply does nothing after a SIGINT now. Because it does NOTHING, I know it changes the default handle, but I don't understand why it does not call the handling function. Can someone help me do this handling?


Solution

  • As Philip's comments suggested, the problem was that I wasn't running a main loop and using gst_bus_timed_pop() to get the messages from the bus. By using a GMainLoop and adding a bus watcher(using gst_bus_add_watch) with a bus callback function, I managed to catch the interrupt as I wanted to.