Rtspsrc not linking with rtph264depay!

Please provide complete information as applicable to your setup.

**• Hardware Platform ----> GPU
**• DeepStream Version -----> 6.4
• TensorRT Version ----> 8.6
**• NVIDIA GPU Driver Version ----> 545

I am trying with rtspsrc —> rtph264depay → h264parse ----> nvv4l2decoder ----> streammux

But rtspsrc not able to link with rtph264depay other element are linking properly.

source = Gst.ElementFactory.make(“rtspsrc”, “rtspsrc_for_”+str(cam_id))
if not source:
sys.stderr.write(" Unable to create rtspsrc \n")
source.set_property(“location”, uri_name)
source.set_property(“latency”, 5000)
source.set_property(‘protocols’,4)
self.pipeline.add(source)

        rtpdepay = Gst.ElementFactory.make("rtph264depay", "rtph264depay_for_"+str(cam_id))
        if not rtpdepay:
            sys.stderr.write(" Unable to create rtpdepay parser \n")
        self.pipeline.add(rtpdepay)

        h264parser = Gst.ElementFactory.make("h264parse", "h264-parser_"+str(cam_id))
        if not h264parser:
            sys.stderr.write(" Unable to create h264 parser \n")
        self.pipeline.add(h264parser)

        decoder = Gst.ElementFactory.make("nvv4l2decoder", "nvv4l2-decoder_"+str(cam_id))
        if not decoder:
            sys.stderr.write(" Unable to create Nvv4l2 Decoder \n")
        self.pipeline.add(decoder)

        source.link(rtpdepay)
        rtpdepay.link(h264parser)
        h264parser.link(decoder)

        padname = "sink_%u" % i
        sinkpad = streammux_main.get_request_pad(padname)
        if not sinkpad:
            sys.stderr.write("Unable to create sink pad bin \n")
        srcpad = decoder.get_static_pad("src")
        if not srcpad:
            sys.stderr.write("Unable to create src pad bin \n")
        srcpad.link(sinkpad)

this is the code for this particular part
and I’m attaching pipeline picture also

Use uridecodebin to replace these

Or Build the following pipeline

gst-launch-1.0 -e rtspsrc location=rtsp://"your rtsp uri" ! application/x-rtp, media=video, encoding-name=H264  ! queue ! rtph264depay ! decodebin ! nvvideoconvert ! 'video/x-raw(memory:NVMM),format=NV12' ! mux.sink_0 nvstreammux name=mux batch-size=1 width=1280 height=720 ! nvinfer config-file-path=/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-test1/dstest1_pgie_config.yml ! nvvideoconvert ! "video/x-raw(memory:NVMM), format=RGBA" ! nvdsosd ! nvvideoconvert ! nv3dsink

Hi @junshengy with uridecodebin It’s working I am trying without Uridecodebin and not using any bin !
and create the pipeline, If you have any suggestion for that please share !

I have given a solution, just use nvv4l2decoder to replace decodebin

Okey ! Let’s me do once and I will get back to you quickly !

@junshengy
I have done this ---->
source = Gst.ElementFactory.make(“rtspsrc”, “rtspsrc_for_”+str(cam_id))
if not source:
sys.stderr.write(" Unable to create rtspsrc \n")
source.set_property(“location”, uri_name)
source.set_property(“latency”, 2000)
# source.set_property(‘protocols’,4)
self.pipeline.add(source)

        rtpdepay = Gst.ElementFactory.make("rtph264depay", "rtph264depay_for_"+str(cam_id))
        if not rtpdepay:
            sys.stderr.write(" Unable to create rtpdepay parser \n")
        self.pipeline.add(rtpdepay)

        h264parser = Gst.ElementFactory.make("h264parse", "h264-parser_"+str(cam_id))
        if not h264parser:
            sys.stderr.write(" Unable to create h264 parser \n")
        self.pipeline.add(h264parser)

        decoder = Gst.ElementFactory.make("decodebin", "nvv4l2-decoder_"+str(cam_id))
        if not decoder:
            sys.stderr.write(" Unable to create Nvv4l2 Decoder \n")
        self.pipeline.add(decoder)

        source.link(rtpdepay)
        rtpdepay.link(h264parser)
        h264parser.link(decoder)

        padname = "sink_%u" % i
        sinkpad = streammux_main.get_request_pad(padname)
        if not sinkpad:
            sys.stderr.write("Unable to create sink pad bin \n")
        srcpad = decoder.get_static_pad("src")
        print("SRCPAD ----> ", srcpad)
        if not srcpad:
            sys.stderr.write("Unable to create src pad bin \n")
        srcpad.link(sinkpad)

It’s giving “Unable to create src pad bin”
How I can link to streammux ?

Save the following code to /opt/nvidia/deepstream/deepstream/sources/deepstream_python_apps/apps/deepstream-test1/deepstream_test_rtsp.py.

then python3 deepstream_test_rtsp.py "rtsp://xxx"

#!/usr/bin/env python3

################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################################################################################

import sys
sys.path.append('../')
import os
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GLib, Gst
from common.is_aarch_64 import is_aarch64
from common.bus_call import bus_call

import pyds

PGIE_CLASS_ID_VEHICLE = 0
PGIE_CLASS_ID_BICYCLE = 1
PGIE_CLASS_ID_PERSON = 2
PGIE_CLASS_ID_ROADSIGN = 3
MUXER_BATCH_TIMEOUT_USEC = 33000

def osd_sink_pad_buffer_probe(pad,info,u_data):
    frame_number=0
    num_rects=0

    gst_buffer = info.get_buffer()
    if not gst_buffer:
        print("Unable to get GstBuffer ")
        return

    # Retrieve batch metadata from the gst_buffer
    # Note that pyds.gst_buffer_get_nvds_batch_meta() expects the
    # C address of gst_buffer as input, which is obtained with hash(gst_buffer)
    batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
    l_frame = batch_meta.frame_meta_list
    while l_frame is not None:
        try:
            # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta
            # The casting is done by pyds.NvDsFrameMeta.cast()
            # The casting also keeps ownership of the underlying memory
            # in the C code, so the Python garbage collector will leave
            # it alone.
            frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
        except StopIteration:
            break

        #Intiallizing object counter with 0.
        obj_counter = {
            PGIE_CLASS_ID_VEHICLE:0,
            PGIE_CLASS_ID_PERSON:0,
            PGIE_CLASS_ID_BICYCLE:0,
            PGIE_CLASS_ID_ROADSIGN:0
        }
        frame_number=frame_meta.frame_num
        num_rects = frame_meta.num_obj_meta
        l_obj=frame_meta.obj_meta_list
        while l_obj is not None:
            try:
                # Casting l_obj.data to pyds.NvDsObjectMeta
                obj_meta=pyds.NvDsObjectMeta.cast(l_obj.data)
            except StopIteration:
                break
            obj_counter[obj_meta.class_id] += 1
            obj_meta.rect_params.border_color.set(0.0, 0.0, 1.0, 0.8) #0.8 is alpha (opacity)
            try: 
                l_obj=l_obj.next
            except StopIteration:
                break

        # Acquiring a display meta object. The memory ownership remains in
        # the C code so downstream plugins can still access it. Otherwise
        # the garbage collector will claim it when this probe function exits.
        display_meta=pyds.nvds_acquire_display_meta_from_pool(batch_meta)
        display_meta.num_labels = 1
        py_nvosd_text_params = display_meta.text_params[0]
        # Setting display text to be shown on screen
        # Note that the pyds module allocates a buffer for the string, and the
        # memory will not be claimed by the garbage collector.
        # Reading the display_text field here will return the C address of the
        # allocated string. Use pyds.get_string() to get the string content.
        py_nvosd_text_params.display_text = "Frame Number={} Number of Objects={} Vehicle_count={} Person_count={}".format(frame_number, num_rects, obj_counter[PGIE_CLASS_ID_VEHICLE], obj_counter[PGIE_CLASS_ID_PERSON])

        # Now set the offsets where the string should appear
        py_nvosd_text_params.x_offset = 10
        py_nvosd_text_params.y_offset = 12

        # Font , font-color and font-size
        py_nvosd_text_params.font_params.font_name = "Serif"
        py_nvosd_text_params.font_params.font_size = 10
        # set(red, green, blue, alpha); set to White
        py_nvosd_text_params.font_params.font_color.set(1.0, 1.0, 1.0, 1.0)

        # Text background color
        py_nvosd_text_params.set_bg_clr = 1
        # set(red, green, blue, alpha); set to Black
        py_nvosd_text_params.text_bg_clr.set(0.0, 0.0, 0.0, 1.0)
        # Using pyds.get_string() to get display_text as string
        print(pyds.get_string(py_nvosd_text_params.display_text))
        pyds.nvds_add_display_meta_to_frame(frame_meta, display_meta)
        try:
            l_frame=l_frame.next
        except StopIteration:
            break
    return Gst.PadProbeReturn.OK	

def cb_newpad(rtspsrc, element_src_pad, data):
    print("In cb_newpad\n")
    caps = element_src_pad.get_current_caps()
    if not caps:
        caps = element_src_pad.query_caps()
    gststruct = caps.get_structure(0)
    gstname = gststruct.get_name()
    media = gststruct.get_string("media")
    encoding_name = gststruct.get_string("encoding-name")

    filter = data
    print(f"filter {type(filter)}")
    print(f"gstname = {gstname}, media = {media}, encoding_name = {encoding_name}")
    if media.find("video") != -1 and gstname.find("x-rtp"):
        sinkpad = filter.get_static_pad("sink")
        element_src_pad.link(sinkpad)
        #print(f"ret === {ret}")


def main(args):
    # Check input arguments
    if len(args) != 2:
        sys.stderr.write("usage: %s rtspuri>\n" % args[0])
        sys.exit(1)

    # Standard GStreamer initialization
    Gst.init(None)

    # Create gstreamer elements
    # Create Pipeline element that will form a connection of other elements
    print("Creating Pipeline \n ")
    pipeline = Gst.Pipeline()

    if not pipeline:
        sys.stderr.write(" Unable to create Pipeline \n")

    # Source element for reading from the file
    print("Creating Source \n ")
    source = Gst.ElementFactory.make("rtspsrc", "file-source")
    if not source:
        sys.stderr.write(" Unable to create Source \n")

    caps = Gst.Caps.from_string("application/x-rtp, media=video, encoding-name=H264")
    filter = Gst.ElementFactory.make("capsfilter", "filter")
    filter.set_property("caps", caps)

    rtpdepay = Gst.ElementFactory.make("rtph264depay", "rtph264depay")
    if not rtpdepay:
        sys.stderr.write(" Unable to create rtpdepay parser \n")

    source.set_property("location", args[1])
    source.connect("pad-added", cb_newpad, filter)

    # Since the data format in the input file is elementary h264 stream,
    # we need a h264parser
    print("Creating H264Parser \n")
    h264parser = Gst.ElementFactory.make("h264parse", "h264-parser")
    if not h264parser:
        sys.stderr.write(" Unable to create h264 parser \n")

    # Use nvdec_h264 for hardware accelerated decode on GPU
    print("Creating Decoder \n")
    decoder = Gst.ElementFactory.make("nvv4l2decoder", "nvv4l2-decoder")
    if not decoder:
        sys.stderr.write(" Unable to create Nvv4l2 Decoder \n")

    # Create nvstreammux instance to form batches from one or more sources.
    streammux = Gst.ElementFactory.make("nvstreammux", "Stream-muxer")
    if not streammux:
        sys.stderr.write(" Unable to create NvStreamMux \n")

    # Use nvinfer to run inferencing on decoder's output,
    # behaviour of inferencing is set through config file
    pgie = Gst.ElementFactory.make("nvinfer", "primary-inference")
    if not pgie:
        sys.stderr.write(" Unable to create pgie \n")

    # Use convertor to convert from NV12 to RGBA as required by nvosd
    nvvidconv = Gst.ElementFactory.make("nvvideoconvert", "convertor")
    if not nvvidconv:
        sys.stderr.write(" Unable to create nvvidconv \n")

    # Create OSD to draw on the converted RGBA buffer
    nvosd = Gst.ElementFactory.make("nvdsosd", "onscreendisplay")

    if not nvosd:
        sys.stderr.write(" Unable to create nvosd \n")

    # Finally render the osd output
    if is_aarch64():
        print("Creating nv3dsink \n")
        sink = Gst.ElementFactory.make("nv3dsink", "nv3d-sink")
        if not sink:
            sys.stderr.write(" Unable to create nv3dsink \n")
    else:
        print("Creating EGLSink \n")
        sink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer")
        if not sink:
            sys.stderr.write(" Unable to create egl sink \n")

    print("Playing file %s " %args[1])
    source.set_property('location', args[1])
    if os.environ.get('USE_NEW_NVSTREAMMUX') != 'yes': # Only set these properties if not using new gst-nvstreammux
        streammux.set_property('width', 1920)
        streammux.set_property('height', 1080)
        streammux.set_property('batched-push-timeout', MUXER_BATCH_TIMEOUT_USEC)
    
    streammux.set_property('batch-size', 1)
    pgie.set_property('config-file-path', "dstest1_pgie_config.txt")

    print("Adding elements to Pipeline \n")
    pipeline.add(source)
    pipeline.add(filter)
    pipeline.add(rtpdepay)
    pipeline.add(h264parser)
    pipeline.add(decoder)
    pipeline.add(streammux)
    pipeline.add(pgie)
    pipeline.add(nvvidconv)
    pipeline.add(nvosd)
    pipeline.add(sink)

    # we link the elements together
    # file-source -> h264-parser -> nvh264-decoder ->
    # nvinfer -> nvvidconv -> nvosd -> video-renderer
    print("Linking elements in the Pipeline \n")
    filter.link(rtpdepay)
    rtpdepay.link(h264parser)
    h264parser.link(decoder)

    sinkpad = streammux.get_request_pad("sink_0")
    if not sinkpad:
        sys.stderr.write(" Unable to get the sink pad of streammux \n")
    srcpad = decoder.get_static_pad("src")
    if not srcpad:
        sys.stderr.write(" Unable to get source pad of decoder \n")
    srcpad.link(sinkpad)
    streammux.link(pgie)
    pgie.link(nvvidconv)
    nvvidconv.link(nvosd)
    nvosd.link(sink)

    # create an event loop and feed gstreamer bus mesages to it
    loop = GLib.MainLoop()
    bus = pipeline.get_bus()
    bus.add_signal_watch()
    bus.connect ("message", bus_call, loop)

    # Lets add probe to get informed of the meta data generated, we add probe to
    # the sink pad of the osd element, since by that time, the buffer would have
    # had got all the metadata.
    osdsinkpad = nvosd.get_static_pad("sink")
    if not osdsinkpad:
        sys.stderr.write(" Unable to get sink pad of nvosd \n")

    osdsinkpad.add_probe(Gst.PadProbeType.BUFFER, osd_sink_pad_buffer_probe, 0)

    # start play back and listen to events
    print("Starting pipeline \n")
    pipeline.set_state(Gst.State.PLAYING)
    try:
        loop.run()
    except:
        pass
    # cleanup
    pipeline.set_state(Gst.State.NULL)

if __name__ == '__main__':
    sys.exit(main(sys.argv))

Thank you @junshengy
It’s works !

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