Deepstream pipeline end gracefully with file-loop option

PC: RTX 2070 Super
Deepstream: 6.2
Driver Version: 525.105.17
Docker image: deepstream:6.2-devel

I am working on the sample app deepstream-test3 in C++. The PERF_MODE is enabled since I want to utilize the file-loop option using nvurisrcbin plugin. Furthermore I have modified the pipeline for saving the output as a mp4 file (nvosd → nvvidconv1-> cap_filter-> h264encoder-> h264parser-> qtmux-> file_sink).

At first I disabled the file-loop option and I run the pipeline fully, the video saves correctly when the pipeline ends. However if I rerun the pipeline and interrupt the pipeline midway using (Ctrl + C), the mp4 file that gets saved is corrupted. This behavior is expected since the pipeline is not stopped gracefully. Thus to remedy this I implemented handler for interrupts as below, such that when SIGINT events are sent, the handler_interrupt function will send an eos to the pipeline to stop the pipeline gracefully. After this change when when I interrupt the pipeline midway the video file gets saved without any corruption.

However the problem starts If I enable the file-loop option, with this modified code, when the file-loop is enabled, sending (Ctrl+C) does not stop the application anymore, the code calls the handle_interrupt function but the message is not sent to the bus handler, As I observe when I press (Ctrl+C) the input video is rerun, I am assuming the application will see the EOS and rerun the input video due to file-loop option.

Thus my question is for any recommended method to enable the fileloop option and also end the pipeline gracefully when (Ctrl+C) are detected.

PS: Sorry for the long post, Any help is much appreciated.

#include <glib-unix.h>

static gboolean handle_interrupt(gpointer user_data)
{
    GstElement *pipeline = (GstElement *) user_data;
    gst_element_send_event(pipeline, gst_event_new_eos()); // Send an EOS event to the pipeline
    return G_SOURCE_CONTINUE;
}

static gboolean bus_call (GstBus * bus, GstMessage * msg, gpointer data)
{
  GMainLoop *loop = (GMainLoop *) data;
  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_EOS:
      g_print ("End of stream\n");
      g_main_loop_quit (loop);
      break;
    case GST_MESSAGE_ERROR:{
      gchar *debug;
      GError *error;
      gst_message_parse_error (msg, &error, &debug);
      g_printerr ("ERROR from element %s: %s\n",
          GST_OBJECT_NAME (msg->src), error->message);
      if (debug)
        g_printerr ("Error details: %s\n", debug);
      g_free (debug);
      g_error_free (error);
      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }
  return TRUE;
}

  //create pipeline and elements

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);
  g_unix_signal_add(SIGINT, handle_interrupt, pipeline);  //Ctrl+C events
  g_unix_signal_add(SIGTERM, handle_interrupt, pipeline); //docker stop events

Since file-loop is set to true, when file processing is completed, nvurisrcbin will process the GST_EVENT_EOS event to seek.

According to your description, I implemented a sample that can exit normally and ensure the integrity of mp4 files.

You can refer to it.

deepstream_test1_app_eos.c (11.7 KB)

Thank you very much, I have tested this implementation and it works fine for my use-case. The key takeaway was to send the eos to only the qtmux and then end the g_main loop.

One more thing I want to add, is to put the g_unix_signal_add commands just before the g_main_loop_run (loop);, otherwise if we put the g_unix_signal_add too early, during the initialization part when the model gets converted to the engine file the SIGINT/SIGTERM will not stop the program since the loop has not started yet.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.