C++ implementation failed to obtain RTSP stream

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU):orin nano 4GB
• DeepStream Version : 6.3.0
• JetPack Version (valid for Jetson only): 5.1.3
TensorRT Version:8.5

When I installed deepstream SDK on orin nano, I created configuration file to test.

[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5
#gie-kitti-output-dir=streamscl

[tiled-display]
enable=1
rows=1
columns=1
width=1280
height=720

[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP 5=CSI
type=4
uri=rtsp://192.168.0.12:8554/test
camera-width=1280
camera-height=720
camera-fps-n=30
camera-fps-d=1

[sink0]
enable=1
#Type - 1=FakeSink 2=EglSink/nv3dsink(Jetson only) 3=File 4=RTSPStreaming 5=nvdrmvideosink
type=2
sync=0
conn-id=0
width=0
height=0
plane-id=1
source-id=0

[sink1]
enable=0
type=3
#1=mp4 2=mkv
container=1
#1=h264 2=h265 3=mpeg4
codec=1
#encoder type 0=Hardware 1=Software
enc-type=0
sync=0
bitrate=2000000
#H264 Profile - 0=Baseline 2=Main 4=High
#H265 Profile - 0=Main 1=Main10
# set profile only for hw encoder, sw encoder selects profile based on sw-preset
profile=0
output-file=out.mp4
source-id=0

[sink2]
enable=0
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=nvdrmvideosink
type=4
#1=h264 2=h265
codec=1
#encoder type 0=Hardware 1=Software
enc-type=0
sync=0
bitrate=4000000
#H264 Profile - 0=Baseline 2=Main 4=High
#H265 Profile - 0=Main 1=Main10
# set profile only for hw encoder, sw encoder selects profile based on sw-preset
profile=0
# set below properties in case of RTSPStreaming
rtsp-port=8554
udp-port=5400

[osd]
enable=1
border-width=2
text-size=15
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Serif
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0

[streammux]
##Boolean property to inform muxer that sources are live
live-source=1
batch-size=1
##time out in usec, to wait after the first buffer is available
##to push the batch even if the complete batch is not formed
batched-push-timeout=40000
## Set muxer output width and height
width=1280
height=720
## If set to TRUE, system timestamp will be attached as ntp timestamp
## If set to FALSE, ntp timestamp from rtspsrc, if available, will be attached
# attach-sys-ts-as-ntp=1

# config-file property is mandatory for any gie section.
# Other properties are optional and if set will override the properties set in
# the infer config file.
[primary-gie]
enable=1
model-engine-file=../../models/Primary_Detector/resnet10.caffemodel_b1_gpu0_int8.engine
#Required to display the PGIE labels, should be added even when using config-file
#property
batch-size=1
#Required by the app for OSD, not a plugin property
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
interval=0
#Required by the app for SGIE, when used along with config-file property
gie-unique-id=1
config-file=config_infer_primary.txt

[tests]
file-loop=0

Executing the following command will work properly:

deepstream-app -c test.txt

After verifying that the functionality was feasible, I implemented a similar function using C++, but it did not run properly:

#include <stdio.h>
#include <gst/gst.h>
#include <glib.h>

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;
}

int main(int argc, char* argv[])
{
    GMainLoop *loop = NULL;
    GstElement *pipeline = NULL, *source = NULL, *rtph264depay = NULL, *appsink = NULL;
    GstBus *bus = NULL;
    GstMessage *msg = NULL;
    GstStateChangeReturn ret;

    gst_init(&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    pipeline = gst_pipeline_new("rtsp-pipeline");

    source = gst_element_factory_make("rtspsrc", "source");
    rtph264depay = gst_element_factory_make("rtph264depay", "demux");
    appsink = gst_element_factory_make("appsink", "sink");


    if (!pipeline || !source || !rtph264depay || !appsink)
    {
        printf("create element failed!\n");
        return -1;
    }

    g_object_set(source, "location", "rtsp://192.168.0.12:8554/test", NULL);

    gst_bin_add_many(GST_BIN(pipeline), source, rtph264depay, appsink, NULL);
    if (!gst_element_link_many(source, rtph264depay, appsink, NULL))
    {
        g_printerr ("Elements could not be linked: 1. Exiting.\n");
        return -1;
    }

    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref (GST_OBJECT (pipeline));

    return 0;
}

Please help me resolve this exception so that I can obtain the RTSP stream normally.

Best R

This problem is not related with DeepStream, It’s just a gstreamer usage.

GstPad of rtspsrc is called request pad, it’s available only when the audio/video coming.

The following is an example. For similar questions, please go to the gstreamer community to discuss

#include <glib.h>
#include <gst/gst.h>
#include <stdio.h>

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;
}

static void cb_newpad(GstElement *rtspsrc, GstPad *src_pad, gpointer data) {
  GstElement *capsfilter = (GstElement *)data;
  GstCaps *caps = gst_pad_get_current_caps(src_pad);
  if (!caps) {
    caps = gst_pad_query_caps(src_pad, NULL);
  }
  const GstStructure *str = gst_caps_get_structure(caps, 0);
  const gchar *name = gst_structure_get_name(str);
  const gchar *media = gst_structure_get_string(str, "media");
  gboolean is_video = (!g_strcmp0(media, "video"));

  printf("name %s == media %s\n", name, media);
  if (g_strrstr(name, "x-rtp") && is_video) {
    GstPad *sink_pad = gst_element_get_static_pad(capsfilter, "sink");
    GstPadLinkReturn ret = gst_pad_link(src_pad, sink_pad);
    if (GST_PAD_LINK_FAILED(ret)) {
      g_print("Pad link failed: %d\n", ret);
      return;
    }
    g_print("Pad link success \n");
    gst_object_unref(sink_pad);
  }
}

int main(int argc, char *argv[]) {
  GMainLoop *loop = NULL;
  GstElement *pipeline = NULL, *source = NULL, *caps_filter = NULL,
             *rtph264depay = NULL, *sink = NULL;
  GstBus *bus = NULL;
  GstMessage *msg = NULL;
  guint bus_watch_id;
  GstStateChangeReturn ret;

  gst_init(&argc, &argv);
  loop = g_main_loop_new(NULL, FALSE);

  pipeline = gst_pipeline_new("rtsp-pipeline");

  source = gst_element_factory_make("rtspsrc", "source");

  caps_filter = gst_element_factory_make("capsfilter", "capsfilter");
  if (!caps_filter) {
    g_printerr("Caps_filter could not be created. Exiting.\n");
    return -1;
  }
  GstCaps *caps = gst_caps_from_string(
      "application/x-rtp, media=video, encoding-name=H264");
  g_object_set(G_OBJECT(caps_filter), "caps", caps, NULL);
  gst_caps_unref(caps);

  rtph264depay = gst_element_factory_make("rtph264depay", "demux");
  GstElement *h264parser = gst_element_factory_make("h264parse", "h264-parser");
  GstElement *nvv4l2decoder =
      gst_element_factory_make("nvv4l2decoder", "nvv4l2decoder");
  sink = gst_element_factory_make("nv3dsink", "sink");

  if (!pipeline || !source || !rtph264depay || !sink) {
    printf("create element failed!\n");
    return -1;
  }


  g_object_set(source, "location", "rtsp://192.168.0.12:8554/test", NULL);
  g_signal_connect(G_OBJECT(source), "pad-added", G_CALLBACK(cb_newpad),
                   caps_filter);

  /* we add a message handler */
  bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
  bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
  gst_object_unref(bus);

  gst_bin_add_many(GST_BIN(pipeline), source, caps_filter, rtph264depay,
                   h264parser, nvv4l2decoder, sink, NULL);
  if (!gst_element_link_many(caps_filter, rtph264depay, h264parser,
                             nvv4l2decoder, sink, NULL)) {
    g_printerr("Elements could not be linked: 1. Exiting.\n");
    return -1;
  }

  gst_element_set_state(pipeline, GST_STATE_PLAYING);

  /* Wait till pipeline encounters an error or EOS */
  g_print("Running...\n");
  g_main_loop_run(loop);

  gst_element_set_state(pipeline, GST_STATE_NULL);
  g_print("Deleting pipeline\n");
  gst_object_unref(GST_OBJECT(pipeline));
  g_source_remove(bus_watch_id);
  g_main_loop_unref(loop);

  return 0;
}

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