Hardware:
- NVIDIA Jetson Nano Developer Kit with JetPack 4.6.1 on MicroSD Card
- Raspberry Pi Camera v2
Background: I am writing a program for a system that needs to be able to perform object detection on live camera feed, subsequently go into suspend mode to save power, and resume the object detection program immediately upon waking up. I’ve found that the video capturing and video analysis need to be split into two separate programs because GStreamer does not support entering suspend/resume in runtime while the GStreamer pipeline is running.
Problem: I have decided to first try UDP for transmitting video from the command line to a Python program to test having two separate programs for video capturing and video analysis. The results are that there is ~300ms of latency on the receiving end and massive amounts of frame drops. Below is the code:
Sender:
gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=1280,height=720,framerate=60/1' ! nvvidconv flip-method=2 ! 'video/x-raw(memory:NVMM),width=1280,height=720' ! tee name=t ! nvv4l2h264enc insert-sps-pps=1 idrinterval=15 ! h264parse ! rtph264pay ! udpsink host=127.0.0.1 port=5000 sync=0 t. ! queue ! nvegltransform ! nveglglessink sync=0
Receiver:
import cv2
import gi
gi.require_version("Gst", "1.0")
from gi.repository import Gst
Gst.init(None)
pipeline = (
"udpsrc port=5000 ! application/x-rtp,encoding-name=H264,payload=96 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! appsink"
)
cap = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow("UDP Video Stream", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
Note: There is litte to no frame drops and ~30ms latency when the receiver is ran with this code:
gst-launch-1.0 udpsrc port=5000 ! 'application/x-rtp,encoding-name=H264,payload=96' ! rtph264depay ! avdec_h264 ! xvimagesink sync=0
Questions:
- Is this a problem with the speed of Python? Would C or C++ be a faster alternative?
- Is UDP the best protocol for this use case? Would TCP, RTSP, or something else be better?
- Are there modifications I could make to the Python code to solve the latency and frame drop issues?
Any help is much appreciated.