Serious issue with nvh264enc gstreamer plugin

I am not able to restart or control the RTSP media if I am using nvh264enc instead of x264enc at the launch_str in the following code, because of this issue, we are not able to properly close the connections from clients. Please let me know if there is any solution to this.

#!/usr/bin/python
# --------------------------------------------------------------------------- #
# Supporting arguments
# --------------------------------------------------------------------------- #
# --------------------------------------------------------------------------- #
# Use gi to import GStreamer functionality
# --------------------------------------------------------------------------- #
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
gi.require_version('GstVideo', '1.0')
import argparse
import logging
import json
import time
import os.path
import subprocess
import signal
import sys
from ctypes import *
from gi.repository import GObject, Gst, Gio, GstVideo, GstRtspServer, GLib
from threading import Thread, Lock
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
gi.require_version('GstVideo', '1.0')
parser = argparse.ArgumentParser(description="gst-rtsp-launch-py V0.2")
parser.add_argument('-v', '--verbose', action='store_true',
                    help='Make script chatty')
args = parser.parse_args()


# --------------------------------------------------------------------------- #
# configure the service logging
# --------------------------------------------------------------------------- #
logging.basicConfig()
log = logging.getLogger()

# --------------------------------------------------------------------------- #
# import misc standard libraries
# --------------------------------------------------------------------------- #


if args.verbose:
    log.setLevel(logging.DEBUG)
else:
    log.setLevel(logging.INFO)

def on_debug(category, level, dfile, dfctn, dline, source, message, user_data):
    if source:
        print('Debug {} {}'.format(
            Gst.DebugLevel.get_name(level), message.get()))
    else:
        print('Debug {}: {}'.format(
            Gst.DebugLevel.get_name(level), message.get()))

if not Gst.debug_is_active():
    Gst.debug_set_active(True)
    level = Gst.debug_get_default_threshold()
    Gst.debug_set_default_threshold(Gst.DebugLevel.INFO)
    if level < Gst.DebugLevel.ERROR:
        Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
    Gst.debug_add_log_function(on_debug, None)
    Gst.debug_remove_log_function(Gst.debug_log_default)

cam_mutex = Lock()
# -------------------


class StreamServer:
    def __init__(self):
        signal.signal(signal.SIGTERM, self.exit_gracefully)
        Gst.init(None)
        self.mainloop = GLib.MainLoop()
        self.server = GstRtspServer.RTSPServer()
        self.mounts = self.server.get_mount_points()

        self.factory = GstRtspServer.RTSPMediaFactory()
        # Factory must be shared to allow multiple connections
        self.factory.set_shared(True)
        self.context_id = 0
        self.running = False
        self.stayAwake = True

        GLib.threads_init()
        log.info("StreamServer initialized")

    def exit_gracefully(self, signum, frame):
        self.stop()
        self.stayAwake = False


    def launch(self):
        log.debug("StreamServer.launch")
        if self.running:
            log.debug("StreamServer.launch called on running instance.")
            self.stop()  # Need to stop any instances first

        launch_str = 'videotestsrc ' \
                             ' ! queue' \
                             ' ! videoconvert' \
                             ' ! video/x-raw,format=I420' \
                             ' ! x264enc' \
                             ' ! rtph264pay config-interval=1 pt=96 name=pay0' \
                             ''
        log.debug(launch_str)
        cam_mutex.acquire()
        try:
            log.info("Starting service on port " +
                     str(8555)+" at url /video1")
            self.factory.set_launch(launch_str)
            self.server.set_service("8555")
            self.mounts.add_factory("/video", self.factory)
            self.context_id = self.server.attach(None)

            # mainloop.run()
            self.mainthread = Thread(target=self.mainloop.run)
            self.mainthread.daemon = True
            self.mainthread.start()
            self.running = True
        finally:
            cam_mutex.release()
        log.info("Running RTSP Server")

    def start(self):
        while True:
            print("Sleeping for 10 seconds")
            time.sleep(20)
            self.restart()

    def disconnect_all(self, a, b):
        return GstRtspServer.RTSPFilterResult.REMOVE

    def stop(self):
        if self.running:
            print("Suspending server")
            log.debug("Suspending RTSP Server")
            cam_mutex.acquire()
            try:
                print(self.context_id)
                print(self.server.client_filter(self.disconnect_all))
                time.sleep(0.3)
                self.mainloop.quit()
                self.mainthread.join()
                self.mounts.remove_factory("/video")
                GLib.Source.remove(self.context_id)
                self.running = False
            finally:
                cam_mutex.release()

    def restart(self):
        # TODO: Manipulate the running pipe rather than destroying and recreating it.
        self.stop()
        self.launch()


if __name__ == '__main__':
    streamServer = StreamServer()
    streamServer.launch()
    streamServer.start()

Please find the below details as well.

the GPU is NVIDIA GeForce RTX 3050 Ti Laptop GPU

The gstreamer version is 1.20.3

nvcc version is

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Tue_May__3_18:49:52_PDT_2022
Cuda compilation tools, release 11.7, V11.7.64
Build cuda_11.7.r11.7/compiler.31294372_0

using Video_Codec_SDK_9.0.20 to build the nvenc and nvdec

2 Likes

Sorry for the late. I will check and feedback.

sure @Amycao , We are in dire need. Please connect me if any clarifications needed.

Do you mean function def restart(self) not work? I run with ds 6.1.1 on T4, i can restart the StreamServer. i used gstreamer 1.16.2 and used nvv4l2h264enc instead of nvh264enc, there no nvh264enc plugin. can you try nvv4l2h264enc?

test.py:85: PyGIDeprecationWarning: Since version 3.11, calling threads_init is no longer needed. See: Projects/PyGObject/Threading - GNOME Wiki!
GLib.threads_init()
INFO:root:StreamServer initialized
DEBUG:root:StreamServer.launch
DEBUG:root:videotestsrc ! queue ! videoconvert ! video/x-raw,format=I420 ! v4l2h264enc ! rtph264pay config-interval=1 pt=96 name=pay0
INFO:root:Starting service on port 8555 at url /video1
INFO:root:Running RTSP Server
Sleeping for 20 seconds
Suspending server
DEBUG:root:Suspending RTSP Server
1

DEBUG:root:StreamServer.launch
DEBUG:root:videotestsrc ! queue ! videoconvert ! video/x-raw,format=I420 ! v4l2h264enc ! rtph264pay config-interval=1 pt=96 name=pay0
INFO:root:Starting service on port 8555 at url /video1
INFO:root:Running RTSP Server
Sleeping for 20 seconds

Hi @Amycao , We are stuck with gstreamer bad plugins such as nvenc and nvdec as of now. These plugins are available for x86 laptops. Could you please try with this plugin.

There no nvenc and nvdec gstreamer plugin.

ajith@ajith-OMEN-by-HP-Laptop-16-c0xxx:~$ gst-inspect-1.0 nvdec
Factory Details:
  Rank                     primary (256)
  Long-name                NVDEC video decoder
  Klass                    Codec/Decoder/Video/Hardware
  Description              NVDEC video decoder
  Author                   Ericsson AB, http://www.ericsson.com

Plugin Details:
  Name                     nvdec
  Description              GStreamer NVDEC plugin
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstnvdec.so
  Version                  1.16.2
  License                  BSD
  Source module            gst-plugins-bad
  Source release date      2019-12-03
  Binary package           GStreamer Bad Plug-ins source release
  Origin URL               Unknown package origin

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstVideoDecoder
                         +----GstNvDec

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      video/x-h264
          stream-format: byte-stream
              alignment: au
      video/x-h265
          stream-format: byte-stream
              alignment: au
      video/mpeg
            mpegversion: { (int)1, (int)2, (int)4 }
           systemstream: false
      image/jpeg
      video/x-vp8
      video/x-vp9
  
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw(memory:GLMemory)
                 format: NV12
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]
         texture-target: 2D

Hi @Amycao ,
This is the nvdec,

Please find the link as well

https://gstreamer.freedesktop.org/documentation/nvcodec/nvh264enc.html?gi-language=c#nvh264enc

Ok. you should reach to the owner, it’s not from nvidia.

Thank you @Amycao , for the replies. We are slowly moving to the jetson platform moving the gstreamer plugins from nvidia. As of now, we are adjusting to the current issues.

Hey @ajithkumar.ak95 ,
Did you find a solution for this?

we use nvv4l2h264enc and dec now, please use docker containers.

Dont depend on bare metal, it will be alright.