3D Sensor Metadata (LiDAR & radar)#
DL Streamer’s 3D pipelines carry two kinds of metadata:
Raw-sensor metadata — custom
GstMetatypes attached alongside the buffer payload by the sensor-parsing/processing elements. These describe the frame and the sensor-specific results (point clouds, clusters, low-level tracks). Two types are defined:LidarMeta— produced byg3dlidarparse(offline BIN/PCD replay) andg3dlidarsrc(live device capture)GstRadarProcessMeta— produced byg3dradarprocess
3D detections — the oriented 3D bounding boxes produced by
g3dinferenceand consumed byg3dobjectfuserare stored asGstAnalytics3DODMtdinside the buffer’sGstAnalyticsRelationMetacontainer. That type is documented with the rest of the analytics metadata in GStreamer Analytics Metadata.
This page documents the two raw-sensor GstMeta types. These are standalone
GstMeta attached directly to the buffer.
LidarMeta#
LidarMeta frames a raw LiDAR point cloud. It is attached by one of two
producers — g3dlidarparse, which parses a recorded BIN/PCD frame from disk,
or g3dlidarsrc, which captures frames live from a device — each emitting a
dense float payload with one LidarMeta per buffer. The two are byte-for-byte
compatible, so downstream elements accept either source unchanged.
g3dinference reads the meta to validate and voxelize the payload before
inference.
The point coordinates themselves are not stored in the meta: they live in
the buffer payload as a flat float32 array, four floats per point
(x, y, z, intensity). LidarMeta only carries the point count and the framing
information needed to interpret and time-align that payload:
typedef struct _LidarMeta {
GstMeta meta;
guint lidar_point_count; /* points in this frame; payload = count * 4 * sizeof(float) */
size_t frame_id; /* sequential frame id from the source stream */
GstClockTime exit_source_timestamp; /* clock time when the buffer left the source element */
GstClockTime exit_g3dinference_timestamp;/* clock time when the buffer left g3dinference */
guint stream_id; /* STREAM_START group-id, for multi-stream pipelines */
} LidarMeta;
Fields#
Field |
Type |
Description |
|---|---|---|
|
|
Number of points in the frame. The payload is |
|
|
Sequential frame identifier from the source stream. |
|
|
Clock time when the buffer exited the source element ( |
|
|
Clock time when the buffer exited |
|
|
Stream identifier (group-id from |
LidarMeta API#
Symbol |
Description |
|---|---|
|
The |
|
The |
|
Attaches a |
LidarMeta C example#
#include <dlstreamer/gst/metadata/g3d_lidar_meta.h>
/* Consumer side (e.g. g3dinference): read the framing, validate the payload. */
LidarMeta *lm = (LidarMeta *)gst_buffer_get_meta(buffer, LIDAR_META_API_TYPE);
if (lm) {
GstMapInfo map;
gst_buffer_map(buffer, &map, GST_MAP_READ);
gsize expected = (gsize)lm->lidar_point_count * 4 * sizeof(gfloat);
if (map.size == expected) {
const gfloat *points = (const gfloat *)map.data; /* [x0,y0,z0,i0, x1,y1,z1,i1, ...] */
/* ... voxelize / run inference ... */
}
gst_buffer_unmap(buffer, &map);
}
LidarMeta lifecycle#
g3dlidarparse / g3dlidarsrc g3dinference
parse BIN/PCD | capture live read LidarMeta (count, frame_id, stream_id)
add_lidar_meta(count, ...) ─────▶ map payload, verify size == count*4*float
payload = float32[count*4] run inference, add GstAnalytics3DODMtd
caps: application/x-lidar set exit_g3dinference_timestamp
GstRadarProcessMeta#
GstRadarProcessMeta carries the full output of the mmWave radar signal
pipeline for one frame. g3dradarprocess runs detection, clustering, and
tracking on each raw radar frame and attaches one GstRadarProcessMeta with
three result groups: detected reflection points, clusters, and tracked objects.
All the array fields are heap-allocated and owned by the meta.
struct _GstRadarProcessMeta {
GstMeta meta;
guint64 frame_id;
/* Point clouds — one entry per detected reflection point */
gint point_clouds_len;
gfloat *ranges; /* distance to the reflection point */
gfloat *speeds; /* Doppler (radial) velocity */
gfloat *angles; /* azimuth angle */
gfloat *snrs; /* signal-to-noise ratio */
/* Cluster result — points grouped into objects */
gint num_clusters;
gint *cluster_idx; /* per-point cluster index */
gfloat *cluster_cx; /* cluster centre x */
gfloat *cluster_cy; /* cluster centre y */
gfloat *cluster_rx; /* cluster extent (radius) x */
gfloat *cluster_ry; /* cluster extent (radius) y */
gfloat *cluster_av; /* average velocity per cluster */
/* Tracking result — objects tracked across frames */
gint num_tracked_objects;
gint *tracker_ids; /* stable per-object track id */
gfloat *tracker_x; /* position estimate x (sHat[0]) */
gfloat *tracker_y; /* position estimate y (sHat[1]) */
gfloat *tracker_vx; /* velocity x (sHat[2]) */
gfloat *tracker_vy; /* velocity y (sHat[3]) */
};
Result groups#
Group |
Count field |
Arrays |
Meaning |
|---|---|---|---|
Point clouds |
|
|
Raw detected reflection points (range, Doppler speed, azimuth angle, SNR). |
Clusters |
|
|
Nearby points grouped into candidate objects, each with a centre |
Tracking |
|
|
Objects tracked across frames, each with a stable |
GstRadarProcessMeta API#
Symbol |
Description |
|---|---|
|
The |
|
The |
|
Attaches a |
Note:
GstRadarProcessMetahas no transform function, so it is not automatically copied when a buffer is transformed or copied. Read it on the buffer produced directly byg3dradarprocess.
GstRadarProcessMeta C example#
#include <dlstreamer/gst/metadata/g3d_radarprocess_meta.h>
GstRadarProcessMeta *rm =
(GstRadarProcessMeta *)gst_buffer_get_meta(buffer, GST_RADAR_PROCESS_META_API_TYPE);
if (rm) {
g_print("frame %" G_GUINT64_FORMAT ": %d points, %d clusters, %d tracks\n",
rm->frame_id, rm->point_clouds_len, rm->num_clusters, rm->num_tracked_objects);
for (gint i = 0; i < rm->num_tracked_objects; i++)
g_print(" track %d at (%.2f, %.2f) v=(%.2f, %.2f)\n",
rm->tracker_ids[i], rm->tracker_x[i], rm->tracker_y[i],
rm->tracker_vx[i], rm->tracker_vy[i]);
}