Hello everyone,
Jetson Xavier NX
The below code, “RTSP from camera” and “Output to RTSP” along with it’s “Supporting functions”, worked fine on Xavier NX. It was grabbing a RTSP feed from a camera and making it available on another RTSP stream.
Jetson Orin AGX
The same code runs on Orin AGX but the feed that comes through is heavily distorted as per the attached image.
I then tried running the below Python script (which is very similar in content) and the video stream comes through undistorted.
Is this a behavior that anyone recognises?
Thank you in advance.
RTSP from camera:
videoCaptureBackend = cv::CAP_GSTREAMER;
videoSource = "rtspsrc location=" + addressIn + " latency=0 ! rtph264depay ! queue ! h264parse ! nvv4l2decoder ! nvvidconv ! video/x-raw,format=BGRx ! queue ! videoconvert ! video/x-raw, format=BGR ! queue ! appsink";
video_cap = cv::VideoCapture(videoSource, videoCaptureBackend);
Output to RTSP :
gst_init(nullptr, nullptr);
rtsp_loop = g_main_loop_new(nullptr, FALSE);
GstRTSPServer* rtsp_server = gst_rtsp_server_new();
gst_rtsp_server_set_service(rtsp_server, port_number.c_str());
GstRTSPMediaFactory* factory = gst_rtsp_media_factory_new();
std::string launch = "( appsrc name=rtsp_src format=GST_FORMAT_TIME max-latency=0 caps=video/x-raw,format=BGR,width=1920,height=1080 ! videoconvert ! video/x-raw,format=(string)RGBA ! nvvidconv ! nvv4l2h265enc ! video/x-h265 ! rtph265pay name=pay0 pt=96 )";
gst_rtsp_media_factory_set_launch(factory, launch.c_str());
g_signal_connect(factory, "media-configure", (GCallback)rtsp_media_configure, nullptr);
GstRTSPMountPoints* mounts = gst_rtsp_server_get_mount_points(rtsp_server);
gst_rtsp_mount_points_add_factory(mounts, address.substr(address_last_slash_pos).c_str(), factory);
g_object_unref(mounts);
g_main_loop_run(rtsp_loop);
Supporting functions:
void rtsp_need_data(GstElement* appsrc, guint unused, RTSPContext *ctx) {
GstBuffer* buffer = gst_buffer_new_allocate(NULL, rtsp_data_size, NULL);
gst_buffer_fill(buffer, 0, rtsp_manager.receive().data, rtsp_data_size);
GST_BUFFER_PTS(buffer) = ctx->timestamp;
GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 30);
ctx->timestamp += GST_BUFFER_DURATION(buffer);
GstFlowReturn ret; // Not used, but prevent annoying warnings
g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
gst_buffer_unref(buffer);
}
void rtsp_media_configure(GstRTSPMediaFactory* factory, GstRTSPMedia* media, gpointer user_data) {
GstElement *element = gst_rtsp_media_get_element(media);
GstElement *appsrc = gst_bin_get_by_name_recurse_up(GST_BIN(element), "rtsp_src");
g_object_set_data_full(G_OBJECT(media), "my-extra-data", nullptr, (GDestroyNotify)g_free);
g_signal_connect(appsrc, "need-data", (GCallback)rtsp_need_data, g_new0(RTSPContext, 1));
gst_object_unref(appsrc);
gst_object_unref(element);
}
Python example:
Gst.init(None)
mainloop = GLib.MainLoop()
server = GstRtspServer.RTSPServer()
mounts = server.get_mount_points()
test_factory = GstRtspServer.RTSPMediaFactory()
test_factory.set_launch('rtspsrc location=' + address_in+ ' latency=0 ! rtph264depay ! queue ! h264parse ! nvv4l2decoder ! nvvidconv ! video/x-raw,format=BGRx ! nvvidconv ! nvv4l2h264enc ! rtph264pay name=pay0')
mounts.add_factory("/test", vimbasrc_factory)
server.attach(None)
mainloop.run()