This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM68A: AM68A

Part Number: AM68A


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