Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,420 changes: 1,924 additions & 496 deletions .ci/test.sh

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
LATEST CHANGES
==============

ZED SDK v5.2
--------------
- Add NV12 zero-copy capture support on Jetson (GMSL cameras) via ``stream-type=6``
- Add NV12 stereo side-by-side zero-copy mode via ``stream-type=7``
- Add AUTO stream-type negotiation (``stream-type=-1``) that prefers NV12 zero-copy when available
- Add AUTO resolution mode that selects the best resolution for requested FPS based on camera model
- Add flexible output resolution negotiation with ranged caps for non-NVMM formats
- Add BGR and GRAY8 output format support for zedsrc and zedxonesrc
- Add ``fixate`` callback for proper caps negotiation during pipeline setup
- Add side-by-side left+right image stream type (``stream-type=5``, #79)
- Add Jetson pipeline scripts: NV12 encoding, RTSP/SRT/UDP streaming, benchmarks
- Add runtime SVO recording control (``svo-recording-enable``, ``svo-recording-filename``, ``svo-recording-compression``, #78)
- Add ``output-rectified-image`` property for ZED X One (#71)
- Add GEN_3 positional tracking, NEURAL_LIGHT depth mode, custom YOLO model support
- Add SDK version compile-time check to catch version mismatches early
- Add test script (``.ci/test.sh``) with fast, extensive, and benchmark modes
- Default camera FPS changed from 15 to 30
- Default camera resolution changed to AUTO
- Deprecated ``async-image-retrieval`` property in zedsrc (no-op, kept for backward compatibility)
- Fixed incorrect VGA resolution mapping and ``memcpy`` buffer overflow in data mux
- Fixed ``sprintf`` buffer safety issues
- Fixed multi-instance issues (replaced static buffer counters with per-instance variables)
- Fixed floating-point math issues and AEC_AGC enum handling
- Added latency query handlers to prevent crashes during pipeline queries
- Disabled shadow warnings for older ZED SDK compatibility
- Improved code formatting consistency and documentation typos
- SDK version requirement updated to 5.2

ZED SDK v5.1
--------------
- Fix memleak on demux chain
Expand Down
115 changes: 104 additions & 11 deletions README.md

Large diffs are not rendered by default.

282 changes: 183 additions & 99 deletions gst-zed-data-mux/gstzeddatamux.cpp

Large diffs are not rendered by default.

264 changes: 160 additions & 104 deletions gst-zed-demux/gstzeddemux.cpp

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions gst-zed-od-overlay/gstzedodoverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,14 @@ gboolean gst_zedoddisplaysink_event(GstBaseTransform *base, GstEvent *event) {
gst_video_info_from_caps(&vinfo_in, caps);
filter->img_left_w = vinfo_in.width;
filter->img_left_h = vinfo_in.height;
if (vinfo_in.height == 752 || vinfo_in.height == 1440 || vinfo_in.height == 2160 ||
vinfo_in.height == 2484) {

// Detect composite (stacked) stereo streams by their doubled height.
// Known stereo heights: VGA=752, HD720=1440, HD1080=2160, HD1200=2400, HD2K=2484.
// Disambiguation: 3840×2160 is 4K mono (ZED X One), NOT stereo.
// HD1080 stereo is 1920×2160 — only halve when width <= 2208.
if (vinfo_in.height == 752 || vinfo_in.height == 1440 || vinfo_in.height == 2400 ||
vinfo_in.height == 2484 ||
(vinfo_in.height == 2160 && vinfo_in.width <= 2208)) {
filter->img_left_h /= 2; // Only half buffer size if the stream is composite
}

Expand All @@ -384,8 +390,9 @@ static GstFlowReturn gst_zed_od_overlay_transform_ip(GstBaseTransform *base, Gst
gst_object_sync_values(GST_OBJECT(filter), GST_BUFFER_TIMESTAMP(outbuf));

if (FALSE == gst_buffer_map(outbuf, &map_buf, GstMapFlags(GST_MAP_READ | GST_MAP_WRITE))) {
GST_WARNING_OBJECT(filter, "Could not map buffer for write/read");
return GST_FLOW_OK;
GST_ELEMENT_ERROR(filter, RESOURCE, FAILED,
("Could not map buffer for write/read"), (NULL));
return GST_FLOW_ERROR;
}

// Get left image (upper half memory buffer)
Expand All @@ -396,6 +403,7 @@ static GstFlowReturn gst_zed_od_overlay_transform_ip(GstBaseTransform *base, Gst

if (meta == NULL) // Metadata not found
{
gst_buffer_unmap(outbuf, &map_buf);
GST_ELEMENT_ERROR(filter, RESOURCE, FAILED,
("No ZED metadata [GstZedSrcMeta] found in the stream'"), (NULL));
return GST_FLOW_ERROR;
Expand Down
68 changes: 18 additions & 50 deletions gst-zed-rtsp-server/zed-rtsp-launch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
static char *port = (char *) DEFAULT_RTSP_PORT;
static char *host = (char *) DEFAULT_RTSP_HOST;

static GOptionEntry entries[] = {{"port", 'p', 0, G_OPTION_ARG_STRING, &port, "Port to listen on( default: " DEFAULT_RTSP_PORT ")", "PORT"},
{"address", 'a', 0, G_OPTION_ARG_STRING, &host, "Host address( default: " DEFAULT_RTSP_HOST ")", "HOST"},
static GOptionEntry entries[] = {{"port", 'p', 0, G_OPTION_ARG_STRING, &port,
"Port to listen on( default: " DEFAULT_RTSP_PORT ")", "PORT"},
{"address", 'a', 0, G_OPTION_ARG_STRING, &host,
"Host address( default: " DEFAULT_RTSP_HOST ")", "HOST"},
{NULL}};

static void client_connected(GstRTSPServer *server, GstRTSPClient *client) {
Expand All @@ -55,7 +57,8 @@ int main(int argc, char *argv[]) {

optctx =
g_option_context_new("PIPELINE-DESCRIPTION - ZED RTSP Server, Launch\n\n"
"Example: gst-zed-rtsp-server zedsrc ! videoconvert ! 'video/x-raw, format=(string)I420' ! x264enc ! rtph264pay pt=96 name=pay0");
"Example: gst-zed-rtsp-server zedsrc ! videoconvert ! 'video/x-raw, "
"format=(string)I420' ! x264enc ! rtph264pay pt=96 name=pay0");
g_option_context_add_main_entries(optctx, entries, NULL);
g_option_context_add_group(optctx, gst_init_get_option_group());
if (!g_option_context_parse(optctx, &argc, &argv, &error)) {
Expand All @@ -80,12 +83,15 @@ int main(int argc, char *argv[]) {
// make a null-terminated version of argv
argvn = g_new0(char *, argc);
memcpy(argvn, args + 1, sizeof(char *) * (argc - 1));
{ pipeline = (GstElement *) gst_parse_launchv((const gchar **) argvn, &error); }
{
pipeline = (GstElement *) gst_parse_launchv((const gchar **) argvn, &error);
}
g_free(argvn);

if (!pipeline) {
if (error) {
gst_printerr("ERROR - pipeline could not be constructed: %s.\n", GST_STR_NULL(error->message));
gst_printerr("ERROR - pipeline could not be constructed: %s.\n",
GST_STR_NULL(error->message));
g_clear_error(&error);
} else {
gst_printerr("ERROR - pipeline could not be constructed.\n");
Expand All @@ -99,16 +105,19 @@ int main(int argc, char *argv[]) {

GstElement *payload = gst_bin_get_by_name(GST_BIN(pipeline), "pay0");
if (!payload) {
gst_printerr("ERROR - at least a payload with name 'pay0' must be present in the pipeline.\n");
gst_printerr("Example: zedsrc ! videoconvert ! video/x-raw, format=(string)I420 ! x264enc ! rtph264pay pt=96 name=pay0\n");
gst_printerr(
"ERROR - at least a payload with name 'pay0' must be present in the pipeline.\n");
gst_printerr("Example: zedsrc ! videoconvert ! video/x-raw, format=(string)I420 ! x264enc "
"! rtph264pay pt=96 name=pay0\n");
return 1;
}
g_object_unref(payload);
gst_object_unref(pipeline);
// <---- Check launch pipeline correctness */

// ----> Create RTSP Server pipeline
// Note: `gst_rtsp_media_factory_set_launch` requires a GstBin element, the easier way to create it is to enclose
// Note: `gst_rtsp_media_factory_set_launch` requires a GstBin element, the easier way to create
// it is to enclose
// the pipeline in round brackets '(' ')'.
std::string rtsp_pipeline;
rtsp_pipeline = "( ";
Expand Down Expand Up @@ -140,15 +149,6 @@ int main(int argc, char *argv[]) {
factory = gst_rtsp_media_factory_new();
gst_rtsp_media_factory_set_launch(factory, rtsp_pipeline.c_str());
gst_rtsp_media_factory_set_shared(factory, TRUE);

/* Don't suspend/reset the pipeline when no clients - ZED camera takes time to initialize */
gst_rtsp_media_factory_set_suspend_mode(factory, GST_RTSP_SUSPEND_MODE_NONE);

/* Don't send EOS when last client disconnects */
gst_rtsp_media_factory_set_eos_shutdown(factory, FALSE);

/* Set buffer mode to allow for camera startup latency */
gst_rtsp_media_factory_set_latency(factory, 500); /* 500ms buffer */

/* attach the test factory to the /test url */
gst_rtsp_mount_points_add_factory(mounts, "/zed-stream", factory);
Expand All @@ -161,43 +161,11 @@ int main(int argc, char *argv[]) {

g_signal_connect(server, "client-connected", (GCallback) client_connected, NULL);

/* Pre-create and prepare the media so camera initializes before clients connect */
/* start serving */
g_print(" ZED RTSP Server \n");
g_print("-----------------\n");
g_print(" * Initializing camera (this may take a few seconds)...\n");

GstRTSPUrl *url = NULL;
GstRTSPResult parse_result = gst_rtsp_url_parse(("rtsp://" + std::string(host) + ":" + std::string(port) + "/zed-stream").c_str(), &url);
GstRTSPMedia *media = NULL;
if (parse_result != GST_RTSP_OK || url == NULL) {
g_printerr(" * Warning: Failed to parse RTSP URL, media will not be pre-created\n");
} else {
media = gst_rtsp_media_factory_construct(factory, url);
gst_rtsp_url_free(url);
}

if (media) {
GstRTSPThread *thread = gst_rtsp_thread_pool_get_thread(
gst_rtsp_server_get_thread_pool(server),
GST_RTSP_THREAD_TYPE_MEDIA, NULL);
if (gst_rtsp_media_prepare(media, thread)) {
g_print(" * Camera ready!\n");
} else {
g_printerr(" * Warning: Failed to prepare media, clients may experience delays\n");
g_object_unref(media);
media = NULL;
}
}

g_print(" * Stream ready at rtsp://%s:%s/zed-stream\n", host, port);
g_print("-----------------\n");
g_main_loop_run(loop);

/* Cleanup */
if (media) {
gst_rtsp_media_unprepare(media);
g_object_unref(media);
}

return 0;
}
Loading