Can't finish Python Deepstream app properly with Ctrl+C

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU)
GPU
• DeepStream Version
deepstream-5.0
• TensorRT Version
7.0.0-1+cuda10.2
• NVIDIA GPU Driver Version (valid for GPU only)
Driver Version: 460.32.03
• Issue Type( questions, new requirements, bugs)
Error/Question

I have a Python Deepstream app and I want it to end properly when pressed Ctrl+C.

My pipeline has the following elements (less important elements are skipped, just to have an idea):

source -> streammux -> tee -> nvinfer -> nvvideoconvert -> nvdosd -> filesink
                        |---> filesink

My main code is:

self.loop = GObject.MainLoop.new(None, False)
GLib.unix_signal_add(-100, 2, self.handle_sigint, None)
self.bus = self.gst_pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.connect("message", self.bus_message_handler)
self.gst_pipeline.set_state(Gst.State.PLAYING)
self.loop.run()

The bus message handler function:

def bus_message_handler(self, bus, message: Gst.Message) -> bool:
    t = message.type
    logger.info(f"****************** Message received {t}")
    if t == Gst.MessageType.EOS:
        logger.success("End of Stream")
        self.loop.quit()
    elif t == Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        logger.warning(f"{err}: {debug}")
    elif t == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        logger.error(f"{err}: {debug}")
        self.gst_error = f"{err}: {debug}"
        self.loop.quit()
    return True

And finally the sigint handler function:

def handle_sigint(self, user_data=None):
    logger.info("SIGINT detected. Sending EOS...")
    self.gst_pipeline.send_event(Gst.Event.new_eos())
    self.bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.EOS)

The expected behaviour would be:

Run -> Ctrl+C pressed -> Print "SIGINT detected. Sending EOS..." -> Print "End of Stream"

But “End of Stream” is never printed out. Why the EOS message is not being received by the bus_message_handler? How is the proper way of implementing this Ctrl+C functionality to end properly the app? Currently the app finishes without receiving the EOS message, so the saved videos are corrupt.

Thanks.

Ok, so the issue is handle_sigint sent an Event but bus_message_handler didn’t reveive it, right?

Yes. It looks like the bus_message_handler didn’t receive this message…

Hello,

In the handle_sigint function, self.bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.EOS) is called after sending the EOS event with self.gst_pipeline.send_event(Gst.Event.new_eos()). Looking at the gstreamer documentation, it seems that the EOS message is popped from the bus before it can reach the message handler. Instead, you can try passing the popped message directly into your message handler function as follows:


def handle_sigint(self, user_data=None):

logger.info("SIGINT detected. Sending EOS...")

self.gst_pipeline.send_event(Gst.Event.new_eos())

self.bus_message_handler(self.bus, self.bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.EOS))

Doing so should result in your expected behaviour on pressing ctrl + c. Hope this helps!

3 Likes