Deep stream error when trying to inference with 2 cameras

i am trying to use 2 usb cameras and pass this as input to my pre-trainned model TRTBS2, since i dont have 2 usb cameras at the moment i am making one source as videotestsrc and the other as one of the camera i have i.e /dev/video0. The pipeline i intend to make is like

v4l2src1 -> nvvideoconvert1 ->|
                              |-> mux -> nvinfer -> nvvideoconvert -> nvosd -> video-renderer
v4l2src2 -> nvvideoconvert2 ->|

i have made modification to the code accordingly but its returning the error as shown in addition the osd is being called twice once it returns output of 2 inferences and the other only one. what is going on here ?

• Jetson nano dev kit with 4gb ram
• DeepStream Version 5.1
• JetPack Version 4.5.1

dstest1_pgie_config.txt

[property]
gpu-id=0
batch-size=2
model-engine-file=/home/datakalp/TRTBS2.trt
network-type=100
#force-implicit-batch-dim=2
output-io-formats=model:fp16
output-tensor-meta=1
#interval=0
gie-unique-id=1
output-blob-names =model
scaling-filter=0
scaling-compute-hw=0

code

#!/usr/bin/env python3

##############################################
import sys
sys.path.append('../')
import gi
import numpy as np
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
from ctypes import *
import ctypes
import time 
def bus_call(bus, message, loop):
    t = message.type
    if t == Gst.MessageType.EOS:
        sys.stdout.write("End-of-stream\n")
        loop.quit()
    elif t==Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        sys.stderr.write("Warning: %s: %s\n" % (err, debug))
    elif t == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        sys.stderr.write("Error: %s: %s\n" % (err, debug))
        loop.quit()
    return True



import platform
def is_aarch64():
    return True


sys.path.append('../../../../lib')
  
#from bindings.jetson import pyds
import pyds
st=time.time()


def osd_sink_pad_buffer_probe(pad, info, u_data):
    frame_number = 0
    num_rects = 0
    global st
    gst_buffer = info.get_buffer()
    if not gst_buffer:
        print("Unable to get GstBuffer ")
        return
    batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
    l_frame = batch_meta.frame_meta_list
    while l_frame is not None:
        try:
            frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
            l_user = frame_meta.frame_user_meta_list
            while l_user is not None:
                user_meta = pyds.NvDsUserMeta.cast(l_user.data)
                meta = pyds.NvDsInferTensorMeta.cast(user_meta.user_meta_data)
                print(meta.num_output_layers)
                frame_number = frame_meta.frame_num
                print("Frame numbers :",frame_number)
                layer = pyds.get_nvds_LayerInfo(meta, 0)
                ptr = ctypes.cast(pyds.get_ptr(layer.buffer), ctypes.POINTER(ctypes.c_float))
                v = np.ctypeslib.as_array(ptr, shape=(14,))
                et=time.time()
                print("time taken =",et-st)
                st=et
                print(v)
                try:
                    l_user = l_user.next
                except StopIteration:
                    break

        except StopIteration:
            break

        try:
            l_frame = l_frame.next
        except StopIteration:
            break
        

    return Gst.PadProbeReturn.OK


def main(args):
    # Check input arguments
    if len(args) != 2:
        sys.stderr.write("usage: %s <v4l2-device-path>\n" % args[0])
        sys.exit(1)

    # Standard GStreamer initialization
    GObject.threads_init()
    Gst.init(None)

    # Create gstreamer elements
    # Create Pipeline element that will form a connection of other elements
    print("Creating Pipeline \n ")
    pipeline = Gst.Pipeline()

    if not pipeline:
        sys.stderr.write(" Unable to create Pipeline \n")

    # Source element for reading from the file
    print("Creating Source \n ")
    source1 = Gst.ElementFactory.make("v4l2src", "usb-cam-source1") ##v4l2src
    source2 = Gst.ElementFactory.make("videotestsrc", "usb-cam-source2") ##v4l2src
    
    if not source1:
        sys.stderr.write(" Unable to create Source1 \n")
    if not source2:
        sys.stderr.write(" Unable to create Source2 \n")

    caps_v4l2src1 = Gst.ElementFactory.make("capsfilter", "v4l2src_caps_1")
    if not caps_v4l2src1:
        sys.stderr.write(" Unable to create v4l2src capsfilter \n")

    caps_v4l2src2 = Gst.ElementFactory.make("capsfilter", "v4l2src_caps_2")
    if not caps_v4l2src2:
        sys.stderr.write(" Unable to create v4l2src capsfilter \n")

    print("Creating Video Converter \n")

    # Adding videoconvert -> nvvideoconvert as not all
    # raw formats are supported by nvvideoconvert;
    # Say YUYV is unsupported - which is the common
    # raw format for many logi usb cams
    # In case we have a camera with raw format supported in
    # nvvideoconvert, GStreamer plugins' capability negotiation
    # shall be intelligent enough to reduce compute by
    # videoconvert doing passthrough (TODO we need to confirm this)


    # videoconvert to make sure a superset of raw formats are supported
    vidconvsrc1 = Gst.ElementFactory.make("videoconvert", "convertor_src1_1")
    if not vidconvsrc1:
        sys.stderr.write(" Unable to create videoconvert \n")

    vidconvsrc2 = Gst.ElementFactory.make("videoconvert", "convertor_src1_2")
    if not vidconvsrc2:
        sys.stderr.write(" Unable to create videoconvert \n")

    # nvvideoconvert to convert incoming raw buffers to NVMM Mem (NvBufSurface API)
    nvvidconvsrc1 = Gst.ElementFactory.make("nvvideoconvert", "convertor_src2_1")
    if not nvvidconvsrc1:
        sys.stderr.write(" Unable to create Nvvideoconvert \n")

    caps_vidconvsrc1 = Gst.ElementFactory.make("capsfilter", "nvmm_caps_1")
    if not caps_vidconvsrc1:
        sys.stderr.write(" Unable to create capsfilter \n")

    nvvidconvsrc2 = Gst.ElementFactory.make("nvvideoconvert", "convertor_src2_2")
    if not nvvidconvsrc2:
        sys.stderr.write(" Unable to create Nvvideoconvert \n")

    caps_vidconvsrc2 = Gst.ElementFactory.make("capsfilter", "nvmm_caps_2")
    if not caps_vidconvsrc2:
        sys.stderr.write(" Unable to create capsfilter \n")

######################################################################################
    # Create nvstreammux instance to form batches from one or more sources.
    streammux = Gst.ElementFactory.make("nvstreammux", "Stream-muxer")
    if not streammux:
        sys.stderr.write(" Unable to create NvStreamMux \n")

    # Use nvinfer to run inferencing on camera's output,
    # behaviour of inferencing is set through config file
    pgie = Gst.ElementFactory.make("nvinfer", "primary-inference")
    if not pgie:
        sys.stderr.write(" Unable to create pgie \n")

    # Use convertor to convert from NV12 to RGBA as required by nvosd
    nvvidconv = Gst.ElementFactory.make("nvvideoconvert", "convertor")
    if not nvvidconv:
        sys.stderr.write(" Unable to create nvvidconv \n")

    # Create OSD to draw on the converted RGBA buffer
    nvosd = Gst.ElementFactory.make("nvdsosd", "onscreendisplay")

    if not nvosd:
        sys.stderr.write(" Unable to create nvosd \n")

    # Finally render the osd output
    if is_aarch64():
        transform = Gst.ElementFactory.make("nvegltransform", "nvegl-transform")

    print("Creating EGLSink \n")
    sink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer")
    if not sink:
        sys.stderr.write(" Unable to create egl sink \n")
###########################################################################################
    print("Playing cam %s " %args[1])

    caps_v4l2src1.set_property('caps', Gst.Caps.from_string("video/x-raw, framerate=30/1"))
    caps_v4l2src2.set_property('caps', Gst.Caps.from_string("video/x-raw, framerate=30/1"))

    caps_vidconvsrc1.set_property('caps', Gst.Caps.from_string("video/x-raw(memory:NVMM)"))
    caps_vidconvsrc2.set_property('caps', Gst.Caps.from_string("video/x-raw(memory:NVMM)"))
        

    source1.set_property('device', args[1])
#    source2.set_property('device', args[1])    

######################
    streammux.set_property('width', 224)
    streammux.set_property('height', 224)
    streammux.set_property('batch-size', 2)
    streammux.set_property('batched-push-timeout', 4000000)
    streammux.set_property('live-source', 1)
    pgie.set_property('config-file-path', "dstest1_pgie_config.txt")
    # Set sync = false to avoid late frame drops at the display-sink
    sink.set_property('sync', False)
###########################################################################################

    print("Adding elements to Pipeline \n")
    pipeline.add(source1)
    pipeline.add(caps_v4l2src1)
    pipeline.add(vidconvsrc1)
    pipeline.add(nvvidconvsrc1)
    pipeline.add(caps_vidconvsrc1)

    pipeline.add(source2)
    pipeline.add(caps_v4l2src2)
    pipeline.add(vidconvsrc2)
    pipeline.add(nvvidconvsrc2)
    pipeline.add(caps_vidconvsrc2)
#####################

    pipeline.add(streammux)
    pipeline.add(pgie)
    pipeline.add(nvvidconv)
    pipeline.add(nvosd)
    pipeline.add(sink)
    if is_aarch64():
        pipeline.add(transform)
############################################################################################
    # we link the elements together
    # v4l2src -> nvvideoconvert -> mux -> 
    # nvinfer -> nvvideoconvert -> nvosd -> video-renderer
    print("Linking elements in the Pipeline \n")

    source1.link(caps_v4l2src1)
    source2.link(caps_v4l2src2)

    caps_v4l2src1.link(vidconvsrc1)
    caps_v4l2src2.link(vidconvsrc2)

    vidconvsrc1.link(nvvidconvsrc1)
    vidconvsrc2.link(nvvidconvsrc2)

    nvvidconvsrc1.link(caps_vidconvsrc1)
    nvvidconvsrc2.link(caps_vidconvsrc2)

##############################################################################################

    sinkpad1 = streammux.get_request_pad("sink_0")
    sinkpad2 = streammux.get_request_pad("sink_1")

    if not sinkpad1:
        sys.stderr.write(" Unable to get the sink pad of streammux \n")

    srcpad1 = caps_vidconvsrc1.get_static_pad("src")
    srcpad2 = caps_vidconvsrc2.get_static_pad("src")

    if not srcpad2:
        sys.stderr.write(" Unable to get source pad of caps_vidconvsrc \n")

    srcpad1.link(sinkpad1)
    srcpad2.link(sinkpad2)


################################################################################################

    streammux.link(pgie)
    pgie.link(nvvidconv)
    nvvidconv.link(nvosd)
    if is_aarch64():
        nvosd.link(transform)
        transform.link(sink)
    else:
        nvosd.link(sink)

    # create an event loop and feed gstreamer bus mesages to it
    loop = GObject.MainLoop()
    bus = pipeline.get_bus()
    bus.add_signal_watch()
    bus.connect ("message", bus_call, loop)

    # Lets add probe to get informed of the meta data generated, we add probe to
    # the sink pad of the osd element, since by that time, the buffer would have
    # had got all the metadata.
    #osdsinkpad = nvosd.get_static_pad("sink")
    osdsinkpad = pgie.get_static_pad("src")
    if not osdsinkpad:
        sys.stderr.write(" Unable to get sink pad of nvosd \n")

    osdsinkpad.add_probe(Gst.PadProbeType.BUFFER, osd_sink_pad_buffer_probe, 0)

    # start play back and listen to events
    print("Starting pipeline \n")
    pipeline.set_state(Gst.State.PLAYING)
    try:
        loop.run()
    except:
        pass
    # cleanup
    pipeline.set_state(Gst.State.NULL)

if __name__ == '__main__':
    sys.exit(main(sys.argv))

output
the array in the output is the tensor output from the model

Creating Pipeline 
 
Creating Source 
 
Creating Video Converter 

Creating EGLSink 

Playing cam /dev/video0 
Adding elements to Pipeline 

Linking elements in the Pipeline 

Starting pipeline 


Using winsys: x11 
0:00:14.533667281  5866     0x27aee2a0 INFO                 nvinfer gstnvinfer.cpp:619:gst_nvinfer_logger:<primary-inference> NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::deserializeEngineAndBackend() <nvdsinfer_context_impl.cpp:1702> [UID = 1]: deserialized trt engine from :/home/datakalp/TRTBS2.trt
INFO: [Implicit Engine Info]: layers num: 2
0   INPUT  kFLOAT input_1         3x224x224       
1   OUTPUT kFLOAT model           7               

0:00:14.533883607  5866     0x27aee2a0 INFO                 nvinfer gstnvinfer.cpp:619:gst_nvinfer_logger:<primary-inference> NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::generateBackendContext() <nvdsinfer_context_impl.cpp:1806> [UID = 1]: Use deserialized engine model: /home/datakalp/TRTBS2.trt
0:00:14.581756224  5866     0x27aee2a0 INFO                 nvinfer gstnvinfer_impl.cpp:313:notifyLoadModelStatus:<primary-inference> [UID 1]: Load new model:dstest1_pgie_config.txt sucessfully
1
Frame numbers : 0
time taken = 19.74429178237915
[4.20090556e-02 1.98064178e-01 1.30707845e-02 1.28212143e-02
 5.73024713e-03 3.37661221e-03 3.88992106e-04 3.12028192e-02
 1.84033155e-01 2.60765791e-01 3.75078875e-03 6.06131835e-05
 6.43685577e-04 4.17315750e-04]
1
Frame numbers : 0
time taken = 0.0049092769622802734
[3.1202819e-02 1.8403316e-01 2.6076579e-01 3.7507887e-03 6.0613183e-05
 6.4368558e-04 4.1731575e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]
ERROR: Batch size not 1
1
Frame numbers : 1
time taken = 0.19626688957214355
[3.2040078e-02 1.7064616e-01 9.1610271e-03 9.5224855e-03 5.0603319e-03
 2.7900375e-03 2.9827765e-04 3.3652965e-02 1.9329959e-01 2.3899394e-01
 4.1662562e-03 8.1562241e-05 7.9162960e-04 4.9553596e-04]
1
Frame numbers : 1
time taken = 0.0024995803833007812
[3.3652965e-02 1.9329959e-01 2.3899394e-01 4.1662562e-03 8.1562241e-05
 7.9162960e-04 4.9553596e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]
ERROR: Batch size not 1
1
Frame numbers : 2
time taken = 0.005126953125
[3.4815196e-02 1.6066070e-01 8.9161275e-03 1.1244561e-02 6.2412592e-03
 2.9810327e-03 3.8296363e-04 2.1822827e-02 1.7036992e-01 2.1027938e-01
 2.1997981e-03 4.4001186e-05 4.6917639e-04 3.0061632e-04]
1
Frame numbers : 2
time taken = 0.0019373893737792969
[2.1822827e-02 1.7036992e-01 2.1027938e-01 2.1997981e-03 4.4001186e-05
 4.6917639e-04 3.0061632e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]
ERROR: Batch size not 1
1
Frame numbers : 3
time taken = 0.013925790786743164
[3.8250063e-02 1.7724052e-01 1.1158031e-02 1.0408314e-02 5.4059001e-03
 3.0515101e-03 4.0133507e-04 2.0371294e-02 1.5610491e-01 2.3686911e-01
 2.4534282e-03 3.0241959e-05 3.5281325e-04 2.2871332e-04]
1
Frame numbers : 3
time taken = 0.001600027084350586
[2.0371294e-02 1.5610491e-01 2.3686911e-01 2.4534282e-03 3.0241959e-05
 3.5281325e-04 2.2871332e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]
ERROR: Batch size not 1
1
Frame numbers : 4
time taken = 0.009780645370483398
[4.0616777e-02 1.5960999e-01 1.0248601e-02 1.2821214e-02 7.2890772e-03
 3.8543637e-03 5.5711169e-04 1.7848738e-02 1.4903529e-01 2.2661245e-01
 2.1074724e-03 2.5867434e-05 2.6738262e-04 2.6323833e-04]
1
Frame numbers : 4
time taken = 0.0018284320831298828
[1.7848738e-02 1.4903529e-01 2.2661245e-01 2.1074724e-03 2.5867434e-05
 2.6738262e-04 2.6323833e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]

(python3:5866): GStreamer-CRITICAL **: 10:40:34.561: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
ERROR: Batch size not 1

(python3:5866): GStreamer-CRITICAL **: 10:40:34.572: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
1
Frame numbers : 5
time taken = 0.014841556549072266
[3.8683493e-02 1.8403316e-01 1.1687257e-02 1.4447852e-02 5.8426056e-03
 3.1115087e-03 4.0133507e-04 1.8511046e-02 1.4033625e-01 2.2884512e-01
 1.8748617e-03 1.3525267e-05 2.9137006e-04 1.3873413e-04]
1
Frame numbers : 5
time taken = 0.0016908645629882812
[1.8511046e-02 1.4033625e-01 2.2884512e-01 1.8748617e-03 1.3525267e-05
 2.9137006e-04 1.3873413e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]

(python3:5866): GStreamer-CRITICAL **: 10:40:34.577: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
ERROR: Batch size not 1

(python3:5866): GStreamer-CRITICAL **: 10:40:34.578: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
1
Frame numbers : 6
time taken = 0.018940448760986328
[3.5745811e-02 1.9682619e-01 1.1463797e-02 1.1597362e-02 4.7367490e-03
 2.7900375e-03 3.1258780e-04 1.9681409e-02 1.5052763e-01 2.2695492e-01
 1.9117693e-03 1.6314541e-05 2.9137006e-04 2.0342697e-04]
1
Frame numbers : 6
time taken = 0.0016493797302246094
[1.9681409e-02 1.5052763e-01 2.2695492e-01 1.9117693e-03 1.6314541e-05
 2.9137006e-04 2.0342697e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]

(python3:5866): GStreamer-CRITICAL **: 10:40:34.598: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
ERROR: Batch size not 1

(python3:5866): GStreamer-CRITICAL **: 10:40:34.599: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
1
Frame numbers : 7
time taken = 0.025816917419433594
[0.04076927 0.16198196 0.01219413 0.01272271 0.00646314 0.00341628
 0.00046918 0.08151976 0.18491465 0.23213601 0.00989806 0.00023969
 0.00305151 0.00144376]
1
Frame numbers : 7
time taken = 0.002254486083984375
[0.08151976 0.18491465 0.23213601 0.00989806 0.00023969 0.00305151
 0.00144376 0.         0.         0.         0.         0.
 0.         0.        ]

(python3:5866): GStreamer-CRITICAL **: 10:40:34.626: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
ERROR: Batch size not 1

(python3:5866): GStreamer-CRITICAL **: 10:40:34.628: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
1
Frame numbers : 8
time taken = 0.025276660919189453
[0.0349467  0.17511447 0.01001357 0.01115803 0.00519988 0.00263167
 0.00033535 0.09186979 0.21833587 0.18907149 0.01292047 0.00135112
 0.00626553 0.00685048]
1
Frame numbers : 8
time taken = 0.0017209053039550781
[0.09186979 0.21833587 0.18907149 0.01292047 0.00135112 0.00626553
 0.00685048 0.         0.         0.         0.         0.
 0.         0.        ]
ERROR: Batch size not 1
1
Frame numbers : 9
time taken = 0.024301767349243164
[0.03767939 0.18257122 0.01036816 0.0119611  0.00542694 0.00303965
 0.00038899 0.09842541 0.23616375 0.20609397 0.01652956 0.00126936
 0.0060504  0.00522013]
1
Frame numbers : 9
time taken = 0.001505136489868164
[0.09842541 0.23616375 0.20609397 0.01652956 0.00126936 0.0060504
 0.00522013 0.         0.         0.         0.         0.
 0.         0.        ]

(python3:5866): GStreamer-CRITICAL **: 10:40:34.679: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
ERROR: Batch size not 1

(python3:5866): GStreamer-CRITICAL **: 10:40:34.680: gst_mini_object_unref: assertion '(g_atomic_int_get (&mini_object->lockstate) & LOCK_MASK) < 4' failed
1

I see you run on Jetson devices, how about add nvegltransform before nveglglessink?

i have done that in this code itself. transform before sink

But i did not find nvegltransform in your code?

if is_aarch64():
transform = Gst.ElementFactory.make(“nvegltransform”, “nvegl-transform”)

i have solved the issue with demux after inference

code:

#!/usr/bin/env python3

################################################################################
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
################################################################################

import sys
sys.path.append('../')
import gi
import numpy as np
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
from ctypes import *
import ctypes
import time 
def bus_call(bus, message, loop):
    t = message.type
    if t == Gst.MessageType.EOS:
        sys.stdout.write("End-of-stream\n")
        loop.quit()
    elif t==Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        sys.stderr.write("Warning: %s: %s\n" % (err, debug))
    elif t == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        sys.stderr.write("Error: %s: %s\n" % (err, debug))
        loop.quit()
    return True



import platform
def is_aarch64():
    return True


sys.path.append('../../../../lib')
  
#from bindings.jetson import pyds
import pyds
st=time.time()


def osd_sink_pad_buffer_probe(pad, info, u_data):
    frame_number = 0
    num_rects = 0
    global st
    gst_buffer = info.get_buffer()
    if not gst_buffer:
        print("Unable to get GstBuffer ")
        return
    batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
    l_frame = batch_meta.frame_meta_list
    while l_frame is not None:
        try:
            frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
            l_user = frame_meta.frame_user_meta_list
            while l_user is not None:
                user_meta = pyds.NvDsUserMeta.cast(l_user.data)
                meta = pyds.NvDsInferTensorMeta.cast(user_meta.user_meta_data)
                print(meta.num_output_layers)
                frame_number = frame_meta.frame_num
                print("Frame numbers :",frame_number)
                layer = pyds.get_nvds_LayerInfo(meta, 0)
                ptr = ctypes.cast(pyds.get_ptr(layer.buffer), ctypes.POINTER(ctypes.c_float))
                v = np.ctypeslib.as_array(ptr, shape=(14,))
                et=time.time()
                print("time taken =",et-st)
                st=et
                print(v)
                try:
                    l_user = l_user.next
                except StopIteration:
                    break

        except StopIteration:
            break

        try:
            l_frame = l_frame.next
        except StopIteration:
            break
        

    return Gst.PadProbeReturn.OK


def main(args):
    # Check input arguments
    # Standard GStreamer initialization
    GObject.threads_init()
    Gst.init(None)

    # Create gstreamer elements
    # Create Pipeline element that will form a connection of other elements
    print("Creating Pipeline \n ")
    pipeline = Gst.Pipeline()

    if not pipeline:
        sys.stderr.write(" Unable to create Pipeline \n")
#####################################################################################
    # Source element for reading from the file
    print("Creating Source \n ")
    source1 = Gst.ElementFactory.make("v4l2src", "usb-cam-source1") ##v4l2src
    source2 = Gst.ElementFactory.make("v4l2src", "usb-cam-source2") ##v4l2src
    
    if not source1:
        sys.stderr.write(" Unable to create Source1 \n")
    if not source2:
        sys.stderr.write(" Unable to create Source2 \n")

    caps_v4l2src1 = Gst.ElementFactory.make("capsfilter", "v4l2src_caps_1")
    if not caps_v4l2src1:
        sys.stderr.write(" Unable to create v4l2src capsfilter \n")

    caps_v4l2src2 = Gst.ElementFactory.make("capsfilter", "v4l2src_caps_2")
    if not caps_v4l2src2:
        sys.stderr.write(" Unable to create v4l2src capsfilter \n")

    print("Creating Video Converter \n")

    # Adding videoconvert -> nvvideoconvert as not all
    # raw formats are supported by nvvideoconvert;
    # Say YUYV is unsupported - which is the common
    # raw format for many logi usb cams
    # In case we have a camera with raw format supported in
    # nvvideoconvert, GStreamer plugins' capability negotiation
    # shall be intelligent enough to reduce compute by
    # videoconvert doing passthrough (TODO we need to confirm this)


    # videoconvert to make sure a superset of raw formats are supported
    vidconvsrc1 = Gst.ElementFactory.make("videoconvert", "convertor_src1_1")
    if not vidconvsrc1:
        sys.stderr.write(" Unable to create videoconvert \n")

    vidconvsrc2 = Gst.ElementFactory.make("videoconvert", "convertor_src1_2")
    if not vidconvsrc2:
        sys.stderr.write(" Unable to create videoconvert \n")

    # nvvideoconvert to convert incoming raw buffers to NVMM Mem (NvBufSurface API)
    nvvidconvsrc1 = Gst.ElementFactory.make("nvvideoconvert", "convertor_src2_1")
    if not nvvidconvsrc1:
        sys.stderr.write(" Unable to create Nvvideoconvert \n")

    caps_vidconvsrc1 = Gst.ElementFactory.make("capsfilter", "nvmm_caps_1")
    if not caps_vidconvsrc1:
        sys.stderr.write(" Unable to create capsfilter \n")

    nvvidconvsrc2 = Gst.ElementFactory.make("nvvideoconvert", "convertor_src2_2")
    if not nvvidconvsrc2:
        sys.stderr.write(" Unable to create Nvvideoconvert \n")

    caps_vidconvsrc2 = Gst.ElementFactory.make("capsfilter", "nvmm_caps_2")
    if not caps_vidconvsrc2:
        sys.stderr.write(" Unable to create capsfilter \n")

#####################################################################################
    # Create nvstreammux instance to form batches from one or more sources.
    streammux = Gst.ElementFactory.make("nvstreammux", "Stream-muxer")
    if not streammux:
        sys.stderr.write(" Unable to create NvStreamMux \n")

    # Use nvinfer to run inferencing on camera's output,
    # behaviour of inferencing is set through config file
    pgie = Gst.ElementFactory.make("nvinfer", "primary-inference")
    if not pgie:
        sys.stderr.write(" Unable to create pgie \n")
    
    streamdemux = Gst.ElementFactory.make("nvstreamdemux", "Stream-demuxer")
    if not streamdemux:
        sys.stderr.write(" Unable to create NvStreamDeMux \n")

######################################################################################

    # Use convertor to convert from NV12 to RGBA as required by nvosd
    nvvidconv1 = Gst.ElementFactory.make("nvvideoconvert", "convertor1")
    if not nvvidconv1:
        sys.stderr.write(" Unable to create nvvidconv1 \n")


    # Create OSD to draw on the converted RGBA buffer
    nvosd1 = Gst.ElementFactory.make("nvdsosd", "onscreendisplay1")

    if not nvosd1:
        sys.stderr.write(" Unable to create nvosd1 \n")

    transform1 = Gst.ElementFactory.make("nvegltransform", "nvegl-transform1")

    print("Creating EGLSink \n")
    sink1 = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer1")
    if not sink1:
        sys.stderr.write(" Unable to create egl sink1 \n")


#####################################################################################
    #print("Playing cam %s " %args[1])

    caps_v4l2src1.set_property('caps', Gst.Caps.from_string("video/x-raw, framerate=30/1"))
    caps_v4l2src2.set_property('caps', Gst.Caps.from_string("video/x-raw, framerate=30/1"))

    caps_vidconvsrc1.set_property('caps', Gst.Caps.from_string("video/x-raw(memory:NVMM)"))
    caps_vidconvsrc2.set_property('caps', Gst.Caps.from_string("video/x-raw(memory:NVMM)"))
        

    source1.set_property('device', "/dev/video0")
    source2.set_property('device', "/dev/video1")    

######################
    streammux.set_property('width', 224)
    streammux.set_property('height', 224)
    streammux.set_property('batch-size', 2)
    streammux.set_property('batched-push-timeout', 4000000)
    streammux.set_property('live-source', 1)
    pgie.set_property('config-file-path', "dstest1_pgie_config.txt")
    # Set sync = false to avoid late frame drops at the display-sink
    sink1.set_property('sync', False)
#####################################################################################

    print("Adding elements to Pipeline \n")
    pipeline.add(source1)
    pipeline.add(caps_v4l2src1)
    pipeline.add(vidconvsrc1)
    pipeline.add(nvvidconvsrc1)
    pipeline.add(caps_vidconvsrc1)

    pipeline.add(source2)
    pipeline.add(caps_v4l2src2)
    pipeline.add(vidconvsrc2)
    pipeline.add(nvvidconvsrc2)
    pipeline.add(caps_vidconvsrc2)
#####################
    pipeline.add(streamdemux)
    pipeline.add(streammux)
    pipeline.add(pgie)
    pipeline.add(nvvidconv1)
    pipeline.add(nvosd1)
    pipeline.add(sink1)
    pipeline.add(transform1)
    

######################################################################################
    # we link the elements together
    # v4l2src -> nvvideoconvert -> mux -> 
    # nvinfer -> nvvideoconvert -> nvosd -> video-renderer
    print("Linking elements in the Pipeline \n")

    source1.link(caps_v4l2src1)
    source2.link(caps_v4l2src2)

    caps_v4l2src1.link(vidconvsrc1)
    caps_v4l2src2.link(vidconvsrc2)

    vidconvsrc1.link(nvvidconvsrc1)
    vidconvsrc2.link(nvvidconvsrc2)

    nvvidconvsrc1.link(caps_vidconvsrc1)
    nvvidconvsrc2.link(caps_vidconvsrc2)

#####################################################################################

    sinkpad1 = streammux.get_request_pad("sink_0")
    sinkpad2 = streammux.get_request_pad("sink_1")

    if not sinkpad1:
        sys.stderr.write(" Unable to get the sink pad of streammux \n")

    srcpad1 = caps_vidconvsrc1.get_static_pad("src")
    srcpad2 = caps_vidconvsrc2.get_static_pad("src")

    if not srcpad2:
        sys.stderr.write(" Unable to get source pad of caps_vidconvsrc \n")

    srcpad1.link(sinkpad1)
    srcpad2.link(sinkpad2)


#####################################################################################

    streammux.link(pgie)
    pgie.link(streamdemux)
    streamdemux.link(nvvidconv1)
    nvvidconv1.link(nvosd1)
    nvosd1.link(transform1)
    transform1.link(sink1) 

#####################################################################################
    pgie_batch_size = pgie.get_property("batch-size")
    print("pgie_batch_size",pgie_batch_size)
    if (pgie_batch_size != 2):
        print("WARNING: Overriding infer-config batch-size", pgie_batch_size, " with number of sources ",
              2, " \n")
        pgie.set_property("batch-size", 2)
#####################################################################################


    # create an event loop and feed gstreamer bus mesages to it
    loop = GObject.MainLoop()
    bus = pipeline.get_bus()
    bus.add_signal_watch()
    bus.connect ("message", bus_call, loop)

    # Lets add probe to get informed of the meta data generated, we add probe to
    # the sink pad of the osd element, since by that time, the buffer would have
    # had got all the metadata.
    #osdsinkpad = nvosd.get_static_pad("sink")
    osdsinkpad = pgie.get_static_pad("src")
    if not osdsinkpad:
        sys.stderr.write(" Unable to get sink pad of nvosd \n")

    osdsinkpad.add_probe(Gst.PadProbeType.BUFFER, osd_sink_pad_buffer_probe, 0)

    # start play back and listen to events
    print("Starting pipeline \n")
    pipeline.set_state(Gst.State.PLAYING)
    try:
        loop.run()
    except:
        pass
    # cleanup
    pipeline.set_state(Gst.State.NULL)

if __name__ == '__main__':
    sys.exit(main(sys.argv))