Help to add rtsp source in deepstream_lpr_app

Hi, deepstream_lpr_app uses mp4 file as input source.
Could you help to make rtsp camera as source?

Here is part of C code:

/* Create gstreamer elements */
  /* Create Pipeline element that will form a connection of other elements */
  pipeline = gst_pipeline_new ("pipeline"); 

  /* Create nvstreammux instance to form batches from one or more sources. */
  streammux = gst_element_factory_make ("nvstreammux", "stream-muxer");

  if (!pipeline || !streammux) {
      g_printerr ("One element could not be created. Exiting.\n");
      return -1;
  }

  gst_bin_add (GST_BIN(pipeline), streammux);
  
  /* Multiple source files */
  for (src_cnt=0; src_cnt<(guint)argc-5; src_cnt++) {
    /* Only h264 element stream with mp4 container is supported. */
    g_snprintf (ele_name, 64, "file_src_%d", src_cnt);

    /* Source element for reading from the file */
    source[src_cnt] = gst_element_factory_make ("filesrc", ele_name);

    g_snprintf (ele_name, 64, "mp4demux_%d", src_cnt);
    mp4demux[src_cnt] = gst_element_factory_make ("qtdemux", ele_name);

    g_snprintf (ele_name, 64, "h264parser_%d", src_cnt);
    h264parser[src_cnt] = gst_element_factory_make ("h264parse", ele_name);
      
    g_snprintf (ele_name, 64, "parsequeue_%d", src_cnt);
    parsequeue[src_cnt] = gst_element_factory_make ("queue", ele_name);

    /* Use nvdec_h264 for hardware accelerated decode on GPU */
    g_snprintf (ele_name, 64, "decoder_%d", src_cnt);
    decoder[src_cnt] = gst_element_factory_make ("nvv4l2decoder", ele_name);
      
    if(!source[src_cnt] || !h264parser[src_cnt] || !decoder[src_cnt] ||
       !mp4demux[src_cnt]) {
      g_printerr ("One element could not be created. Exiting.\n");
      return -1;
    }
      
    gst_bin_add_many (GST_BIN (pipeline), source[src_cnt], mp4demux[src_cnt],
        h264parser[src_cnt], parsequeue[src_cnt], decoder[src_cnt], NULL);
      
    g_snprintf (pad_name_sink, 64, "sink_%d", src_cnt);
    sinkpad = gst_element_get_request_pad (streammux, pad_name_sink);
    g_print("Request %s pad from streammux\n",pad_name_sink);
    if (!sinkpad) {
      g_printerr ("Streammux request sink pad failed. Exiting.\n");
      return -1;
    }

    srcpad = gst_element_get_static_pad (decoder[src_cnt], pad_name_src);
    if (!srcpad) {
      g_printerr ("Decoder request src pad failed. Exiting.\n");
      return -1;
    }

    if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK) {
      g_printerr ("Failed to link decoder to stream muxer. Exiting.\n");
      return -1;
    }

    if(!gst_element_link_pads (source[src_cnt], "src", mp4demux[src_cnt],
          "sink")) {
      g_printerr ("Elements could not be linked: 0. Exiting.\n");
      return -1;
    }

    g_signal_connect (mp4demux[src_cnt], "pad-added", G_CALLBACK (cb_new_pad),
                      h264parser[src_cnt]);

    if (!gst_element_link_many (h264parser[src_cnt], parsequeue[src_cnt],
           decoder[src_cnt], NULL)) {
      g_printerr ("Elements could not be linked: 1. Exiting.\n");
    }

    /* we set the input filename to the source element */
    g_object_set (G_OBJECT (source[src_cnt]), "location",
        argv[4+src_cnt], NULL);

    gst_object_unref (sinkpad);
    gst_object_unref (srcpad);
  }

Here is working python code with rtsp source:

def create_source_bin(index,uri):
    print("Creating source bin")

    # Create a source GstBin to abstract this bin's content from the rest of the
    # pipeline
    bin_name="source-bin-%02d" %index
    print(bin_name)
    nbin=Gst.Bin.new(bin_name)
    if not nbin:
        sys.stderr.write(" Unable to create source bin \n")

    # Source element for reading from the uri.
    # We will use decodebin and let it figure out the container format of the
    # stream and the codec and plug the appropriate demux and decode plugins.
    uri_decode_bin=Gst.ElementFactory.make("uridecodebin", "uri-decode-bin")
    if not uri_decode_bin:
        sys.stderr.write(" Unable to create uri decode bin \n")
    # We set the input uri to the source element
    uri_decode_bin.set_property("uri",uri)
    # Connect to the "pad-added" signal of the decodebin which generates a
    # callback once a new pad for raw data has beed created by the decodebin
    uri_decode_bin.connect("pad-added",cb_newpad,nbin)
    uri_decode_bin.connect("child-added",decodebin_child_added,nbin)

    # We need to create a ghost pad for the source bin which will act as a proxy
    # for the video decoder src pad. The ghost pad will not have a target right
    # now. Once the decode bin creates the video decoder and generates the
    # cb_newpad callback, we will set the ghost pad target to the video decoder
    # src pad.
    Gst.Bin.add(nbin,uri_decode_bin)
    bin_pad=nbin.add_pad(Gst.GhostPad.new_no_target("src",Gst.PadDirection.SRC))
    if not bin_pad:
        sys.stderr.write(" Failed to add ghost pad in source bin \n")
        return None
    return nbin

Cause the python code use uridecodebin as source, so you can just input your rtsp source. About the C demo, you can modify the code.
You should create the rtspsrc and rtph264depay plugin instead of filesrc, qtdemux, h264parse and queue plugin.

gst_element_factory_make ("rtspsrc", ele_name);
gst_element_factory_make ("rtph264depay", ele_name);

Yes, but i do not understand how to connect pads together.

Now it works from rtsp camera, but looks like 2 streams started from same camera source:

for( src_cnt = 0; src_cnt < guint( argc ) - 3; src_cnt ++ )
    {
        g_snprintf( ele_name, 64, "rtp_src_%d", src_cnt );
        source[ src_cnt ] = gst_element_factory_make( "rtspsrc", ele_name );

        g_snprintf( ele_name, 64, "depay_%d", src_cnt);
        depay[ src_cnt ] = gst_element_factory_make( "rtph264depay", ele_name );

        g_snprintf( ele_name, 64, "h264parser_%d", src_cnt );
        h264parser[ src_cnt ] = gst_element_factory_make( "h264parse", ele_name );

        // Use nvdec_h264 for hardware accelerated decode on GPU
        g_snprintf( ele_name, 64, "decoder_%d", src_cnt );
        decoder[ src_cnt ] = gst_element_factory_make( "nvv4l2decoder", ele_name );

        if( not source[ src_cnt ] or not decoder[ src_cnt ] or not depay[ src_cnt ] or not h264parser[ src_cnt ] )
        {
            g_printerr( "One element could not be created. Exiting.\n" );
            return - 1;
        }

        g_snprintf( ele_name, 64, "parsequeue_%d", src_cnt );
        parsequeue[ src_cnt ] = gst_element_factory_make( "queue", ele_name );

        gst_bin_add_many( GST_BIN( pipeline ), source[ src_cnt ], depay[ src_cnt ], h264parser[ src_cnt ], parsequeue[ src_cnt ], decoder[ src_cnt ], nullptr );

        g_snprintf( pad_name_sink, 64, "sink_%d", src_cnt );
        sinkpad = gst_element_get_request_pad( streammux, pad_name_sink );
        g_print( "Request %s pad from streammux\n", pad_name_sink );
        if( not sinkpad )
        {
            g_printerr( "Streammux request sink pad failed. Exiting.\n" );
            return - 1;
        }

        srcpad = gst_element_get_static_pad( decoder[ src_cnt ], pad_name_src );
        if( not srcpad )
        {
            g_printerr( "Decoder request src pad failed. Exiting.\n" );
            return - 1;
        }

        if( gst_pad_link( srcpad, sinkpad ) != GST_PAD_LINK_OK )
        {
            g_printerr( "Failed to link decoder to stream muxer. Exiting.\n" );
            return - 1;
        }

        if( not gst_element_link_many( depay[ src_cnt ], h264parser[ src_cnt ], parsequeue[ src_cnt ], decoder[ src_cnt ], nullptr ) )
        {
            g_printerr( "Elements could not be linked: 0. Exiting.\n" );
            return - 1;
        }

        g_signal_connect( source[ src_cnt ], "pad-added", G_CALLBACK( on_pad_added ), depay[ src_cnt ] );

        // we set the input filename to the source element
        g_object_set( G_OBJECT( source[ src_cnt ] ), "location", argv[ 2 + src_cnt ], nullptr );
        g_object_set( G_OBJECT( source[ src_cnt ] ), "do-rtcp", TRUE, nullptr );
        g_object_set( G_OBJECT( source[ src_cnt ] ), "latency", 0, nullptr );

        gst_object_unref( sinkpad );
        gst_object_unref( srcpad );
    }


I think pipeline wrong, something doing twice.

Have removed h26parser and queue at all, now single stream.

But often app crashes:

Looks like some none utf symbols detected and gtk crashes.
I have setlocale(LC_ALL,“en_US.utf8”); in main.cpp and custom_lpr_parser.

Why is here segfault?

It was my mistake, i made dict in code directly, not from file.
From file dict.txt stable.

Please explain what for dict file?
I removed some symbols for better cyrillic recognition but it works bad.
Example: Q never appears on car plate so i want delete it from dict. Otherwise sometimes O becomes Q.

Hi @vsw , Please open a new topic about this O and Q problem to avoid confusion of the topic problem. Thanks

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