Stream 3 USB3 cameras from a USB3 hub on Jetson Orin Nano

Hello, I am using a Jetson Orin Nano with Deepstream 7.0. Currently I am trying to connect 3 USB3 cameras through a USB hub. I am able to open and stream each camera individually but not more than one. The only way I can stream at least two cameras is if I connect one by USB3 and the other by USB2 due to the bandwidth issue.

Currently when trying to run my code below to stream from the 3 cameras I get the below message with 3 windows open, where at least one camera turns on and captures the first frame. How can I get 3 cameras to stream simultaneously?

#!/usr/bin/env python3

import sys
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstBase', '1.0')
gi.require_version('GstVideo', '1.0')
from gi.repository import GLib, Gst

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

    # Standard GStreamer initialization
    Gst.init(None)

    # Create GStreamer pipeline
    pipeline = Gst.Pipeline()

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

    # Create source elements for each video device
    sources = []
    queues = []
    vidconvs = []
    sinks = []
    for i, device_path in enumerate(args[1:]):
        # Create source element for each video device
        source = Gst.ElementFactory.make("v4l2src", f"source-{i}")
        if not source:
            sys.stderr.write(f"Unable to create source element for device {i}\n")
            sys.exit(1)
        source.set_property('device', device_path)
        
        # Create videoconvert element
        vidconv = Gst.ElementFactory.make("videoconvert", f"converter-{i}")
        if not vidconv:
            sys.stderr.write(f"Unable to create videoconvert element for device {i}\n")
            sys.exit(1)

        # Create capsfilter element to set resolution
        capsfilter = Gst.ElementFactory.make("capsfilter", f"capsfilter-{i}")
        caps = Gst.Caps.from_string("video/x-raw, format=YUY2, width=640, height=480, framerate=60/1")
        # caps = Gst.Caps.from_string("image/jpeg, width=640, height=480, framerate=60/1, format=MJPG")

        capsfilter.set_property("caps", caps)
        
        queue = Gst.ElementFactory.make("queue", f"queue-{i}")
        queue.set_property("max-size-buffers", 2)  # Limit buffers to avoid memory issues
        queue.set_property("max-size-bytes", 0)  # Unlimited
        queue.set_property("max-size-time", 0)   # Unlimited

        # Create xvimagesink element
        sink = Gst.ElementFactory.make("xvimagesink", f"sink-{i}")
        if not sink:
            sys.stderr.write(f"Unable to create sink element for device {i}\n")
            sys.exit(1)

        # Add elements to the pipeline
        pipeline.add(source)
        pipeline.add(vidconv)
        pipeline.add(capsfilter)
        pipeline.add(queue)
        pipeline.add(sink)

        # Link elements
        source.link(vidconv)
        vidconv.link(capsfilter)
        capsfilter.link(sink)
        queue.link(sink)


    # Create an event loop and feed GStreamer bus messages to it
    loop = GLib.MainLoop()
    bus = pipeline.get_bus()
    bus.add_signal_watch()
    bus.connect("message", lambda bus, msg: loop.quit() if msg.type == Gst.MessageType.EOS else True)

    # Start playback and listen to events
    print("Starting pipeline \n")
    pipeline.set_state(Gst.State.PLAYING)
    try:
        loop.run()
    except KeyboardInterrupt:
        pass

    # Clean up
    print("Stopping pipeline \n")
    pipeline.set_state(Gst.State.NULL)

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

sudo GST_DEBUG=3 python3 multistream.py /dev/video0 /dev/video2 /dev/video3
Starting pipeline 

0:00:00.601730048  8464 0xffff98000b70 ERROR         v4l2bufferpool gstv4l2bufferpool.c:706:gst_v4l2_buffer_pool_streamon:<source-2:pool0:src> error with STREAMON 28 (No space left on device)
0:00:00.601881024  8464 0xffff98000b70 ERROR             bufferpool gstbufferpool.c:572:gst_buffer_pool_set_active:<source-2:pool0:src> start failed
0:00:00.601935616  8464 0xffff98000b70 WARN                 v4l2src gstv4l2src.c:759:gst_v4l2src_decide_allocation:<source-2> error: Failed to allocate required memory.
0:00:00.601951552  8464 0xffff98000b70 WARN                 v4l2src gstv4l2src.c:759:gst_v4l2src_decide_allocation:<source-2> error: Buffer pool activation failed
0:00:00.602107232  8464 0xffff98000b70 WARN                 basesrc gstbasesrc.c:3347:gst_base_src_prepare_allocation:<source-2> Subclass failed to decide allocation
0:00:00.602162240  8464 0xffff98000b70 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<source-2> error: Internal data stream error.
0:00:00.602173952  8464 0xffff98000b70 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<source-2> error: streaming stopped, reason not-negotiated (-4)
0:00:00.604507360  8464 0xffff98000da0 ERROR         v4l2bufferpool gstv4l2bufferpool.c:706:gst_v4l2_buffer_pool_streamon:<source-1:pool0:src> error with STREAMON 28 (No space left on device)
0:00:00.604540448  8464 0xffff98000da0 ERROR             bufferpool gstbufferpool.c:572:gst_buffer_pool_set_active:<source-1:pool0:src> start failed
0:00:00.604556512  8464 0xffff98000da0 WARN                 v4l2src gstv4l2src.c:759:gst_v4l2src_decide_allocation:<source-1> error: Failed to allocate required memory.
0:00:00.604564608  8464 0xffff98000da0 WARN                 v4l2src gstv4l2src.c:759:gst_v4l2src_decide_allocation:<source-1> error: Buffer pool activation failed
0:00:00.604593376  8464 0xffff98000da0 WARN                 basesrc gstbasesrc.c:3347:gst_base_src_prepare_allocation:<source-1> Subclass failed to decide allocation
0:00:00.604620736  8464 0xffff98000da0 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<source-1> error: Internal data stream error.
0:00:00.604630080  8464 0xffff98000da0 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<source-1> error: streaming stopped, reason not-negotiated (-4)

Below is the output of $ lsusb -t

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=tegra-xusb/4p, 10000M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 10000M
        |__ Port 1: Dev 11, If 0, Class=Hub, Driver=hub/4p, 5000M
            |__ Port 1: Dev 12, If 0, Class=Video, Driver=uvcvideo, 5000M
            |__ Port 1: Dev 12, If 1, Class=Video, Driver=uvcvideo, 5000M
            |__ Port 2: Dev 15, If 1, Class=Video, Driver=uvcvideo, 5000M
            |__ Port 2: Dev 15, If 0, Class=Video, Driver=uvcvideo, 5000M
            |__ Port 3: Dev 16, If 1, Class=Video, Driver=uvcvideo, 5000M
            |__ Port 3: Dev 16, If 0, Class=Video, Driver=uvcvideo, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=tegra-xusb/4p, 480M
    |__ Port 2: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 8, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 4: Dev 15, If 2, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 4: Dev 15, If 0, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 4: Dev 15, If 1, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 3: Dev 14, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 3: Dev 3, If 0, Class=Wireless, Driver=rtk_btusb, 12M
    |__ Port 3: Dev 3, If 1, Class=Wireless, Driver=rtk_btusb, 12M

and the cameras compatibilities from $v4l2-ctl --list-formats-ext

ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'MJPG' (Motion-JPEG, compressed)
		Size: Discrete 1920x1080
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 640x480
			Interval: Discrete 0.017s (60.000 fps)
	[1]: 'YUYV' (YUYV 4:2:2)
		Size: Discrete 1920x1080
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 640x480
			Interval: Discrete 0.017s (60.000 fps)

Please let me know if you need anymore information from me!

Hi,
It looks same as
connected more than two usb cameras problem on deepstream-app (Jetson Nano Dev Kit) - #12 by DaneLLL

On Orin Nano developer kit, there is one type-C port. Would suggest shift one or two cameras to the port to use the bandwidth.

Hi,
We are able to shift cameras around to get our 3 cameras to stream together at 640x480 at 60 fps. Is there a way to increase the resolution or would that be the max? Also is there a way to do this only through the hub and not by shifting cameras to different ports? Any cameras or hubs that are recommended for this?