Last active
August 12, 2023 11:30
-
-
Save tutorgaming/55490ac88a3d91302be1d8fd44ac8055 to your computer and use it in GitHub Desktop.
RTSP Stream through GStreamer + STDOUT on Jetson Xavier AGX
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
""" | |
RTSP Stream Reader Class for Jetson Xavier AGX | |
Requirement : Jetpack, OpenCV 4.4 with CUDA-Enabled | |
Tested RTSP Stream from | |
- HIKVISION DS-2CD2021-IAX [1280*720 Main-Stream Selected] | |
CPU Used : 20-35% on Jetson AGX | |
GPU Used : 0-30% on Jetson AGX | |
# TEST COMMAND | |
gst-launch-1.0 rtspsrc \ | |
location=rtsp://path_to_rtsp_stream latency=200 ! \ | |
rtph264depay ! h264parse ! \ | |
nvv4l2decoder drop-frame-interval=2 ! \ | |
nvvideoconvert ! \ | |
video/x-raw,width=1280,height=720,format=I420 ! \ | |
queue ! nveglglessink window-x=0 window-y=0 window-width=1280 window-height=720 | |
# References | |
CasiaFan/deepstream_gstreamer_decoding_with_python.py | |
- https://medium.com/@fanzongshaoxing/use-nvidia-deepstream-to-accelerate-h-264-video-stream-decoding-8f0fec764778 | |
- https://gist.github.com/CasiaFan/684ec8c36624fb5ff61360c71ee9e4ec | |
I420 Convertsion | |
- https://github.com/ArduCAM/MIPI_Camera/blob/master/RPI/python/capture2opencv.py | |
Author : C3MX <[email protected]> | |
Date : 6-May-2021 | |
""" | |
############################################ | |
# IMPORT | |
############################################ | |
import subprocess | |
import numpy as np | |
import cv2 | |
############################################ | |
# GLOBAL PARAM | |
############################################ | |
RTSP_PATH = "rtsp://path_to_rtsp_stream" | |
BUFFSIZE = 10 | |
GSTREAMER_COMMAND = [ | |
"gst-launch-1.0", | |
"rtspsrc" , | |
"location={}".format(RTSP_PATH), "latency=200", "!", | |
"queue", "!", | |
"rtph264depay", "!", | |
"h264parse", "!", | |
"nvv4l2decoder", "drop-frame-interval=2", "!", | |
"nvvideoconvert", "!", | |
"video/x-raw,format=(string)I420", "!", | |
"queue", "!", | |
"filesink", "location=/dev/stdout" | |
] | |
############################################ | |
# CLASS | |
############################################ | |
class StreamReader(object): | |
""" | |
Class to Create RTSP Stream | |
""" | |
def __init__(self): | |
# Subprocess to use gstreamer PIPELINE | |
self.gst_stream = subprocess.Popen( | |
GSTREAMER_COMMAND, | |
stdout=subprocess.PIPE, | |
bufsize=BUFFSIZE, | |
) | |
# Video Config (use I420 Format) | |
self.width = 1280 | |
self.height = 720 | |
self.receive_height = (self.height * 3) //2 | |
self.receive_width = self.width | |
# Prepare the Stream | |
# Removing Log Text from stdout | |
LOG_LENGTH = 497 | |
RTSP_SRC_LENGTH = len(RTSP_PATH) | |
self.gst_stream.stdout.read(LOG_LENGTH+RTSP_SRC_LENGTH) | |
# Start the Stream process | |
print("Init Complete - Begin Process !") | |
self.receive_rtsp_loop() | |
def receive_rtsp_loop(self): | |
""" | |
Receive RTSP Stream directly from STDOUT | |
""" | |
while True: | |
# Read Stream from STDOUT | |
image = self.gst_stream.stdout.read(int(self.receive_height*self.receive_width)) | |
image = np.fromstring(image, dtype=np.uint8).reshape((self.receive_height, self.receive_width)) | |
image = cv2.cvtColor(image, cv2.COLOR_YUV2BGR_I420) | |
# Do Processing Here | |
self.process(image) | |
# Visualizing | |
cv2.imshow("image", image) | |
# End Condition | |
if cv2.waitKey(5) & 0xFF == ord('q'): | |
break | |
# Close the Stream Sub-process | |
self.gst_stream.terminate() | |
cv2.destroyAllWindows() | |
def process(self, input_image): | |
""" | |
Do Some Image Processing Here :) | |
""" | |
pass | |
############################################ | |
# MAIN | |
############################################ | |
STREAM = StreamReader() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
""" | |
[OPENCV-VideoCapture-Based-GST-APPSINK] | |
RTSP Stream Reader Class for Jetson Xavier AGX | |
Requirement : Jetpack, OpenCV 4.4 with CUDA-Enabled | |
Tested RTSP Stream from | |
- HIKVISION DS-2CD2021-IAX [1280*720 Main-Stream Selected] | |
CPU Used : 20-35% on Jetson AGX with many thread spawned | |
GPU Used : 0-30% on Jetson AGX | |
Author : C3MX <[email protected]> | |
Date : 6-May-2021 | |
""" | |
import numpy as np | |
import cv2 | |
RTSP_PATH = "rtsp://path_to_rtsp" | |
GSTREAMER_COMMAND = ( | |
"rtspsrc location={}".format(RTSP_PATH)+ " " + "latency=200 !" + | |
"queue !"+ " " + "rtph264depay !" + " " + | |
"h264parse !"+ " " + | |
"nvv4l2decoder"+ " " + "drop-frame-interval=2"+ " " + "!"+ " " + | |
"nvvideoconvert !" + " " + | |
"video/x-raw,format=(string)I420"+ " " + "!"+ " " + | |
"queue"+ " " + "!"+ " " + | |
"appsink" | |
) | |
cap = cv2.VideoCapture(GSTREAMER_COMMAND, cv2.CAP_GSTREAMER) | |
while(True): | |
# Capture frame-by-frame | |
ret, frame = cap.read() | |
# Our operations on the frame come here | |
image = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_I420) | |
# Display the resulting frame | |
cv2.imshow('frame',image) | |
if cv2.waitKey(10) & 0xFF == ord('q'): | |
break | |
# When everything done, release the capture | |
cap.release() | |
cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a lot!