Jetson Xavier AGX Ethernet over USB bandwidth

Hi,

I’m trying to stream video from the Jetson Xavier AGX Development Kit to a host PC running Windows via a USB cable. The USB cable connects from the development kit’s front USB-C connect to a type-A USB3.0 port on the Windows PC. I was able to stream a video successfully using Ethernet over USB with the RDNIS protocol, but it was severely limited by the bandwidth.

Using iperf3, I found that the network connection has a bandwidth of ~600 Mbps. Why is this not closer to the 5 Gbps of USB3.0 or 10 Gbps of USB3.1? Is there a way to increase the bandwidth?

Please let me know if there are any other details I could provide.

Thanks,
Jackson

Is this issue on NX or Xavier AGX? You file this topic on NX forum board.

Sorry. Just fixed it.

I also tried streaming video through the serial port and managed to get an output of ~3 Gbps. To confirm, both ports on the Jetson Xavier AGX and the host PC are USB3.1, which should have a bandwidth of 10 Gbps. My theory is that it’s limited by the CPU’s clock rate.

I’m by no means an expert on serial communication, but since we can’t have multiple processes writing/reading a serial port, is there any reason why the Jetson’s USB driver does not have multiple device nodes? (I’m currently using /dev/ttyGS0)

Hi Jacksonh,

I am trying to stream video from Jetson Xavier AGX to Windows PC over USB. Can you please elaborate how you achieved this? Is there a sample example you can share?

Thanks in advance!

Hi Varun,

On the Jetson side, I open an OpenCV VideoCapture for the camera. Then in a loop, I take the frames, encode it as JPEG, and determine the number of bytes after the encoding. Finally, I write a 16-byte left-justified string representing the number of bytes (will make sense on the Windows side) and the encoded image to the serial port “ttyGS0”. My rough test code is below. Note that in the code below, your frame rate will be limited by the camera’s frame rate. When I was testing the bandwidth, I would encode one frame at the beginning and send that continuously as fast as possible.

import serial
import cv2
import numpy as np
import time

sp = serial.Serial("/dev/ttyGS0", baudrate=7372800)
cap = cv2.VideoCapture(0)
cap.set(3, 1920)
cap.set(4, 1080)

while True:
    start = time.perf_counter()
    _, frame = cap.read()
    _, imgencode = cv2.imencode('.jpg', frame)
    data = np.array(imgencode)

    string_data = data.tostring()
    data_len = str(len(string_data)).ljust(16)
    data_len_encode = data_len.encode('ascii')

    sp.write(data_len_encode)
    sp.write(string_data)

    print(f"FPS: {1 / {time.perf_counter() - start}")

On the Windows PC side, I open a serial COM port that continuously reads 16 bytes so I know how many bytes I need to read next for the image, then I read that number of bytes and decode it.

import time
import cv2
import serial
import numpy as np


def _recvall(serial_port, count):
    buf = b''
    while count:
        newbuf = serial_port.read(count)
        if not newbuf:
            return None
        buf += newbuf
        count -= len(newbuf)
    return buf


def pull_image(serial_port):
    length = int(_recvall(serial_port, 16))
    string_data = _recvall(serial_port, length)
    data = np.fromstring(string_data, dtype='uint8')
    return cv2.imdecode(data, 1)


s = serial.Serial("COM12", baudrate=7372800)
print("starting...")

while True:
    start = time.perf_counter()
    image = pull_image(s)

    cv2.imshow('feed', image)
    if cv2.waitKey(1) == 27:
        break

    print(f"FPS: {1 / (time.perf_counter() - start)}")

cv2.destroyAllWindows()