Tool/software:
Hello,
I have written a GStreamer script for object detection with output handled by splitmuxsink. The same code structure works fine when displaying the output using autovideosink, but I'm experiencing a memory leak with splitmuxsink.
I tried resolving the issue by adding a capsfilter element with a resolution of 640x480 before passing the data to the encoder even though in my working pipeline it isnt necessary, but it didn’t work. I also attempted changing the capsfilter on postprocess.sink from 480x480 to 640x480, but that didn’t help either.
It seems like the encoder might be expecting a specific format, or there could be a linkage issue causing the memory leak.
The error I’m encountering is:
GLib-ERROR **: 12:57:49.054: /usr/src/debug/glib-2.0/2.78.6/glib/gmem.c:169: failed to allocate 26435423784 bytes
Trace/breakpoint trap (core dumped)
I will provide logs with GST_DEBUG=4 for further analysis.
0:00:00.000219175 7105 0x1eb1be00 INFO GST_INIT gst.c:576:init_pre: Initializing GStreamer Core Library version 1.22.12
0:00:00.000304622 7105 0x1eb1be00 INFO GST_INIT gst.c:577:init_pre: Using library installed in /usr/lib
0:00:00.000359109 7105 0x1eb1be00 INFO GST_INIT gst.c:595:init_pre: Linux am68a-sk 6.6.44-ti-01478-g541c20281af7-dirty #1 SMP PREEMPT Thu Nov 14 19:20:24 UTC 2024 aarch64
0:00:00.000844270 7105 0x1eb1be00 INFO GST_INIT gstmessage.c:129:_priv_gst_message_initialize: init messages
0:00:00.001866055 7105 0x1eb1be00 INFO GST_INIT gstcontext.c:86:_priv_gst_context_initialize: init contexts
0:00:00.002313735 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:324:_priv_gst_plugin_initialize: registering 0 static plugins
0:00:00.002551811 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:232:gst_plugin_register_static: registered static plugin "staticelements"
0:00:00.002609172 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:234:gst_plugin_register_static: added static plugin "staticelements", result: 1
0:00:00.002712305 7105 0x1eb1be00 INFO GST_REGISTRY gstregistry.c:1836:ensure_current_registry: reading registry cache: /root/.cache/gstreamer-1.0/registry.aarch64.bin
0:00:00.040822551 7105 0x1eb1be00 INFO GST_REGISTRY gstregistrybinary.c:683:priv_gst_registry_binary_read_cache: loaded /root/.cache/gstreamer-1.0/registry.aarch64.bin in 0.038027 seconds
0:00:00.041079882 7105 0x1eb1be00 INFO GST_REGISTRY gstregistry.c:1703:scan_and_update_registry: Validating plugins from registry cache: /root/.cache/gstreamer-1.0/registry.aarch64.bin
0:00:00.046753367 7105 0x1eb1be00 INFO GST_REGISTRY gstregistry.c:1795:scan_and_update_registry: Registry cache has not changed
0:00:00.046817508 7105 0x1eb1be00 INFO GST_REGISTRY gstregistry.c:1871:ensure_current_registry: registry reading and updating done
0:00:00.046872809 7105 0x1eb1be00 INFO GST_INIT gst.c:805:init_post: GLib runtime version: 2.78.6
0:00:00.046894435 7105 0x1eb1be00 INFO GST_INIT gst.c:807:init_post: GLib headers version: 2.78.6
0:00:00.046910640 7105 0x1eb1be00 INFO GST_INIT gst.c:809:init_post: initialized GStreamer successfully
0:00:00.047023513 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "pipeline"
0:00:00.695316619 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgstvideo4linux2.so" loaded
0:00:00.697629554 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "v4l2src"
0:00:00.697714666 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseSrc@0x1eb38a10> adding pad 'src'
0:00:00.699144270 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgstcoreelements.so" loaded
0:00:00.699334434 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "capsfilter"
0:00:00.699402736 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1edab730> adding pad 'sink'
0:00:00.699438322 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1edab730> adding pad 'src'
0:00:00.700550378 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgstjpeg.so" loaded
0:00:00.700831875 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "jpegdec"
0:00:00.700921692 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstVideoDecoder@0x1edba520> adding pad 'sink'
0:00:00.700960113 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstVideoDecoder@0x1edba520> adding pad 'src'
0:00:00.701836794 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgstvideoconvertscale.so" loaded
0:00:00.702356906 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "videoconvert"
0:00:00.702455264 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ed9c3f0> adding pad 'sink'
0:00:00.702497170 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ed9c3f0> adding pad 'src'
0:00:00.702547066 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "capsfilter"
0:00:00.702588407 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1eb2ba80> adding pad 'sink'
0:00:00.702622112 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1eb2ba80> adding pad 'src'
0:00:00.727844542 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgsttiovx.so" loaded
0:00:00.728323878 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "tiovxmultiscaler"
0:00:00.728444401 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstTIOVXSimo@0x1ede0070> adding pad 'sink'
0:00:00.728509843 7105 0x1eb1be00 INFO tiovxcontext gsttiovxcontext.c:141:gst_tiovx_context_init: Calling appInit() from GST!
APP: Init ... !!!
21352.078224 s: MEM: Init ... !!!
21352.078264 s: MEM: Initialized DMA HEAP (fd=10) !!!
21352.078393 s: MEM: Init ... Done !!!
21352.078410 s: IPC: Init ... !!!
21352.123192 s: IPC: Init ... Done !!!
REMOTE_SERVICE: Init ... !!!
REMOTE_SERVICE: Init ... Done !!!
21352.129933 s: GTC Frequency = 200 MHz
APP: Init ... Done !!!
21352.130022 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_ERROR
21352.130032 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_WARNING
21352.130039 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_INFO
21352.130928 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-0
21352.131096 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-1
21352.131203 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-2
21352.131320 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-3
21352.131333 s: VX_ZONE_INFO: [tivxInitLocal:126] Initialization Done !!!
21352.131340 s: VX_ZONE_INFO: Globally Disabled VX_ZONE_INFO
0:00:00.786089197 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "queue"
0:00:00.786226060 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstQueue@0x1ee23800> adding pad 'sink'
0:00:00.786279736 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstQueue@0x1ee23800> adding pad 'src'
0:00:00.786330497 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "queue"
0:00:00.786374788 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstQueue@0x1ee261a0> adding pad 'sink'
0:00:00.786411184 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstQueue@0x1ee261a0> adding pad 'src'
0:00:00.786459670 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "capsfilter"
0:00:00.786502761 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee28c50> adding pad 'sink'
0:00:00.786538552 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee28c50> adding pad 'src'
0:00:00.786570893 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "capsfilter"
0:00:00.786607664 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee29890> adding pad 'sink'
0:00:00.786654985 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee29890> adding pad 'src'
0:00:00.787025179 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "tiovxdlpreproc"
0:00:00.787114131 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee2d010> adding pad 'sink'
0:00:00.787157202 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee2d010> adding pad 'src'
0:00:00.787223334 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "capsfilter"
0:00:00.787268055 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee2e150> adding pad 'sink'
0:00:00.787299605 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee2e150> adding pad 'src'
0:00:00.807448109 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgstti.so" loaded
0:00:00.807777237 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "tidlinferer"
0:00:00.807945536 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee3c010> adding pad 'sink'
0:00:00.807996567 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee3c010> adding pad 'src'
0:00:00.808233843 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "tidlpostproc"
0:00:00.808346236 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstTIDLPostProc@0x1ee3e1f0> adding pad 'tensor'
0:00:00.808392692 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstTIDLPostProc@0x1ee3e1f0> adding pad 'sink'
0:00:00.812295995 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgstmultifile.so" loaded
0:00:00.812687424 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "splitmuxsink"
0:00:00.812771461 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "videoconvert"
0:00:00.812846793 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee44a10> adding pad 'sink'
0:00:00.812888984 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseTransform@0x1ee44a10> adding pad 'src'
0:00:00.813145060 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "v4l2h264enc"
0:00:00.813224832 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstVideoEncoder@0x1ee472d0> adding pad 'sink'
0:00:00.813267163 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstVideoEncoder@0x1ee472d0> adding pad 'src'
0:00:00.816839203 7105 0x1eb1be00 INFO GST_PLUGIN_LOADING gstplugin.c:987:_priv_gst_plugin_load_file_for_registry: plugin "/usr/lib/gstreamer-1.0/libgstvideoparsersbad.so" loaded
0:00:00.817085478 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "h264parse"
0:00:00.817178561 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseParse@0x1ee4cd60> adding pad 'sink'
0:00:00.817230292 7105 0x1eb1be00 INFO GST_ELEMENT_PADS gstelement.c:758:gst_element_add_pad:<GstBaseParse@0x1ee4cd60> adding pad 'src'
0:00:00.817284203 7105 0x1eb1be00 INFO baseparse gstbaseparse.c:4064:gst_base_parse_set_pts_interpolation:<GstH264Parse@0x1ee4cd60> PTS interpolation: no
0:00:00.817306919 7105 0x1eb1be00 INFO baseparse gstbaseparse.c:4082:gst_base_parse_set_infer_ts:<GstH264Parse@0x1ee4cd60> TS inferring: no
0:00:00.817349130 7105 0x1eb1be00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:489:gst_element_factory_create_with_properties: creating element "splitmuxsink"
0:00:00.817446302 7105 0x1eb1be00 INFO GST_EVENT gstevent.c:1687:gst_event_new_reconfigure: creating reconfigure event
0:00:00.817503383 7105 0x1eb1be00 INFO GST_EVENT gstevent.c:1687:gst_event_new_reconfigure: creating reconfigure event
0:00:00.817535159 7105 0x1eb1be00 INFO GST_EVENT gstevent.c:1687:gst_event_new_reconfigure: creating reconfigure event
0:00:00.820708335 7105 0x1eb1be00 INFO GST_EVENT gstevent.c:1687:gst_event_new_reconfigure: creating reconfigure event
0:00:00.820808777 7105 0x1eb1be00 INFO GST_EVENT gstevent.c:1687:gst_event_new_reconfigure: creating reconfigure event
(nihalfinal:7105): GLib-ERROR **: 13:19:42.530: /usr/src/debug/glib-2.0/2.78.6/glib/gmem.c:169: failed to allocate 26435423784 bytes
Trace/breakpoint trap (core dumped)
#include <gst/gst.h>
#include <glib.h>
int main(int argc, char *argv[]) {
GstElement *pipeline, *source, *jpeg_caps, *jpegdec, *videoconvert, *nv12_caps;
GstElement *scaler_split, *detect_queue ,*sink_queue, *detect_caps, *sink_caps ,*preproc, *tensor_caps, *inference, *postproc;
GstElement *videoconvert_display ,*display_sink;
GstBus *bus;
GstMessage *msg;
GstStateChangeReturn ret;
gboolean terminate = FALSE;
gst_init(&argc, &argv);
// Create elements
pipeline = gst_pipeline_new("video-pipeline");
source = gst_element_factory_make("v4l2src", "source");
jpeg_caps = gst_element_factory_make("capsfilter", "jpeg_caps");
jpegdec = gst_element_factory_make("jpegdec", "jpegdec");
videoconvert = gst_element_factory_make("videoconvert", "videoconvert");
nv12_caps = gst_element_factory_make("capsfilter", "nv12_caps");
scaler_split = gst_element_factory_make("tiovxmultiscaler", "scaler_split");
detect_queue = gst_element_factory_make("queue","detect_queue");
sink_queue = gst_element_factory_make("queue", "sink_queue");
detect_caps = gst_element_factory_make("capsfilter","detect_caps");
sink_caps = gst_element_factory_make("capsfilter","sink_caps");
preproc = gst_element_factory_make("tiovxdlpreproc","preproc");
tensor_caps = gst_element_factory_make("capsfilter","tensor_caps");
inference = gst_element_factory_make("tidlinferer","inference");
postproc = gst_element_factory_make("tidlpostproc","postproc");
videoconvert_display = gst_element_factory_make("videoconvert","videoconvert_display");
display_sink = gst_element_factory_make("autovideosink","display_sink");
if (!pipeline || !source || !jpeg_caps || !jpegdec || !videoconvert || !nv12_caps
|| !scaler_split || !detect_queue || !detect_caps || !preproc || !tensor_caps || !inference
|| !sink_queue || !sink_caps || !postproc || !videoconvert_display || !display_sink) {
g_printerr("Not all elements could be created.\n");
return -1;
}
// Configure elements
g_object_set(G_OBJECT(source),
"device", "/dev/video-usb-cam0",
"io-mode", 2,
NULL);
// JPEG caps
GstCaps *jpeg_caps_val = gst_caps_new_simple("image/jpeg",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
"framerate", GST_TYPE_FRACTION, 30, 1,
NULL);
g_object_set(G_OBJECT(jpeg_caps), "caps", jpeg_caps_val, NULL);
gst_caps_unref(jpeg_caps_val);
// NV12 caps
GstCaps *nv12_caps_val = gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "NV12",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
NULL);
g_object_set(G_OBJECT(nv12_caps), "caps", nv12_caps_val, NULL);
gst_caps_unref(nv12_caps_val);
//detect_caps
GstCaps *detect_caps_val = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 320,
"height", G_TYPE_INT, 320,
NULL);
g_object_set(G_OBJECT(detect_caps),"caps", detect_caps_val, NULL);
gst_caps_unref(detect_caps_val);
//preproc
g_object_set(G_OBJECT(preproc),"model","/opt/model_zoo/TFL-OD-2020-ssdLite-mobDet-DSP-coco-320x320",
"out-pool-size",4,
NULL);
//tensor_caps
GstCaps *tensor_caps_val = gst_caps_new_simple("application/x-tensor-tiovx",
NULL);
g_object_set(G_OBJECT(tensor_caps),"caps",tensor_caps_val,NULL);
gst_caps_unref(tensor_caps_val);
//inference
g_object_set(G_OBJECT(inference),"target", 1,
"model","/opt/model_zoo/TFL-OD-2020-ssdLite-mobDet-DSP-coco-320x320",
NULL);
//sink caps
GstCaps *sink_caps_val = gst_caps_new_simple("video/x-raw",
"width",G_TYPE_INT, 480,
"height",G_TYPE_INT,480,
NULL);
g_object_set(G_OBJECT(sink_caps),"caps",sink_caps_val,NULL);
gst_caps_unref(sink_caps_val);
//postproc
g_object_set(G_OBJECT(postproc),"model","/opt/model_zoo/TFL-OD-2020-ssdLite-mobDet-DSP-coco-320x320",
"alpha",0.4,
"viz-threshold", 0.6,
"top-N",5,
"display-model",TRUE,
NULL);
//splitmuxsink
// Add elements to pipeline
gst_bin_add_many(GST_BIN(pipeline),
source, jpeg_caps, jpegdec, videoconvert, nv12_caps,
scaler_split,detect_queue, detect_caps, preproc, tensor_caps, inference,
sink_queue, sink_caps, postproc,videoconvert_display,display_sink,
NULL);
// Link elements
if (!gst_element_link_many(source, jpeg_caps, jpegdec, videoconvert, nv12_caps,scaler_split,NULL)) {
g_printerr("Source to nv12_caps link failed.\n");
return -1;
}
if (!gst_element_link_many(detect_queue, detect_caps,preproc,tensor_caps,inference,NULL)){
g_printerr("Detection branch link failed!");
return -1;
}
//manually link inference output to post.tensor
GstPad *inference_src = gst_element_get_static_pad(inference, "src");
GstPad *post_tensor = gst_element_get_static_pad(postproc, "tensor");
if (gst_pad_link(inference_src, post_tensor) != GST_PAD_LINK_OK){
g_printerr("Failed to link inference to post.tensor");
return -1;
}
gst_object_unref(inference_src);
gst_object_unref(post_tensor);
if(!gst_element_link_many(sink_queue,sink_caps,NULL)){
g_printerr("scaler postproc.sink link failed!");
return -1;
}
//Link display branch to post.sink
GstPad *sink_src = gst_element_get_static_pad(sink_caps, "src");
GstPad *post_sink = gst_element_get_static_pad(postproc, "sink");
if (gst_pad_link(sink_src, post_sink) != GST_PAD_LINK_OK){
g_printerr("Failed to link sink src to post.sink\n");
return -1;
}
gst_object_unref(sink_src);
gst_object_unref(post_sink);
if(!gst_element_link_many(postproc,videoconvert_display, display_sink,NULL)){
g_printerr("Failed to link postproc to displaysink");
return -1;
}
// Link multiscaler to both detection and sink branches
GstPad *scaler_src_pad1 = gst_element_request_pad_simple(scaler_split, "src_%u");
GstPad *scaler_src_pad2 = gst_element_request_pad_simple(scaler_split, "src_%u");
GstPad *detect_sink_pad = gst_element_get_static_pad(detect_queue, "sink");
GstPad *sink_sink_pad = gst_element_get_static_pad(sink_queue, "sink");
if (gst_pad_link(scaler_src_pad1, detect_sink_pad) != GST_PAD_LINK_OK ||
gst_pad_link(scaler_src_pad2, sink_sink_pad) != GST_PAD_LINK_OK) {
g_printerr("Failed to link tee branches\n");
return -1;
}
gst_object_unref(scaler_src_pad1);
gst_object_unref(scaler_src_pad2);
gst_object_unref(detect_sink_pad);
gst_object_unref(sink_sink_pad);
// Start pipeline
ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr("Unable to set the pipeline to the playing state.\n");
gst_object_unref(pipeline);
return -1;
}
// Bus message handling
bus = gst_element_get_bus(pipeline);
do {
msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_STATE_CHANGED);
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error(msg, &err, &debug_info);
g_printerr("Error received from element %s: %s\n",
GST_OBJECT_NAME(msg->src), err->message);
g_printerr("Debugging information: %s\n",
debug_info ? debug_info : "none");
g_clear_error(&err);
g_free(debug_info);
terminate = TRUE;
break;
case GST_MESSAGE_EOS:
g_print("End of stream reached.\n");
terminate = TRUE;
break;
case GST_MESSAGE_STATE_CHANGED:
if (GST_MESSAGE_SRC(msg) == GST_OBJECT(pipeline)) {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
g_print("Pipeline state changed from %s to %s\n",
gst_element_state_get_name(old_state),
gst_element_state_get_name(new_state));
}
break;
default:
g_printerr("Unexpected message received.\n");
break;
}
gst_message_unref(msg);
}
} while (!terminate);
// Cleanup
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}