UDP sink 를 이용한 Deepstream RTSP 출력
(Gstreamer 기반) NVIDIA Deepstream 예제들은 다양한 형태로 구현되어 있다. Gstreamer 로 대부분 구현하고 NVIDIA Deepstream plugin을 사용하는 예제도 있고, NVIDIA Deepstream framework 을 사용하는 예제도 제공된다.
대표적으로 deepstream-test1 가 Gstreamer 스타일로 구현되어 있고, 다음의 NVIDIA plugin 을 사용한다.
- nvv4l2decoder
- nvstreammux
- nvinfer
- nvvideoconvert
- nvdsosd
- nveglglessink
반면에 deepstream-test5 의 경우, apps-common 에 있는 NVIDIA Deepstream framework 을 사용한다. apps-common 에 Gstreamer API 이 Wrapping 되어 구현되어 있다.
제공되는 예제들에서 sink 를 변경하는 방법은 다양하겠지만, deepstream-test5 와 비슷한 deepstream-occupancy-analytic 의 sink 를 기존 EGL 을 통한 화면 sink 가 아닌 UDP 를 통한 RTSP sink 로 수정해보자.
테스트 환경
- NVIDIA Xavier NX devkit (16G emmc module)
- nvme ssd root file system 사용
- Jetpack 4.6 (L4T R32.6.1)
소스 다운로드
이 포스팅에서는 아래의 코드를 이용한다.
https://github.com/NVIDIA-AI-IOT/deepstream-occupancy-analytics
Deepstream 예제 위치로 이용하여 git clone 으로 소스를 복제한다.
$ cd /opt/nvidia/deepstream/deepstream-6.0/sources/apps/sample_apps
$ git clone https://github.com/NVIDIA-AI-IOT/deepstream-occupancy-analytics
모델 다운로드
deepstream-occupancy-analytic 의 README.md 에 의하면 model.sh 를 실행하여 peoplenet.zip 를 다운로드하라고 되어있다. 2022년 7월 기준으로 model.sh 의 download link 에서 다운로드 되지 않는다. 아래의 경로에서 수동으로 다운로드 한다.
https://catalog.ngc.nvidia.com/orgs/nvidia/models/tlt_peoplenet
소스 빌드하기
Deepstream 6.0 에서 테스트하기 위해 ds_6.0 브랜치로 체크아웃 한다.
$ git checkout ds_6.0
$ git branch
* ds_6.0
master
테스트를 위해 deepstream-occupancy-analytic 의 message brocker 를 disable 한다.
$ git diff config/test5_config_file_src_infer_tlt.txt
diff --git a/config/test5_config_file_src_infer_tlt.txt b/config/test5_config_file_src_infer_tlt.txt
index 2a8cc2e..2243011 100644
--- a/config/test5_config_file_src_infer_tlt.txt
+++ b/config/test5_config_file_src_infer_tlt.txt
@@ -91,7 +91,7 @@ output-file=resnet.mp4
source-id=0
[sink1]
-enable=1
+enable=0
#Type - 1=FakeSink 2=EglSink 3=File 4=UDPSink 5=nvoverlaysink 6=MsgConvBroker
type=6
msg-conv-config=dstest5_msgconv_sample_config.txt
이 코드를 Deepstream 6.0 으로 빌드할 경우, meta message 의 일부 field 가 빠져서 build error 가 발생한다. 어플리케이션에서 build error 발생하는 부분을 임시 삭제한다.
$ git diff deepstream_test5_app_main.c
diff --git a/deepstream_test5_app_main.c b/deepstream_test5_app_main.c
index bb0d985..5f5d2f0 100644
--- a/deepstream_test5_app_main.c
+++ b/deepstream_test5_app_main.c
@@ -311,7 +311,7 @@ meta_copy_func (gpointer data, gpointer user_data)
}
}
- g_print(" %s %d source id: %d, Enter: %d, Exit: %d\n",__func__,__LINE__, dstMeta->source_id, dstMeta->lccum_cnt_entry, dstMeta->lccum_cnt_exit);
+// g_print(" %s %d source id: %d, Enter: %d, Exit: %d\n",__func__,__LINE__, dstMeta->source_id, dstMeta->lccum_cnt_entry, dstMeta->lccum_cnt_exit);
return dstMeta;
}
@@ -410,10 +410,10 @@ generate_event_msg_meta (gpointer data, gint class_id, gboolean useTs,
meta->type = NVDS_EVENT_ENTRY;
meta->objType = NVDS_OBJECT_TYPE_PERSON;
meta->objClassId = PERSON_ID;
- meta->occupancy = obj_params->lccum_cnt;
- meta->lccum_cnt_entry = obj_params->lcc_cnt_entry;
- meta->lccum_cnt_exit = obj_params->lcc_cnt_exit ;
- meta->source_id = obj_params->source_id;
+// meta->occupancy = obj_params->lccum_cnt;
+// meta->lccum_cnt_entry = obj_params->lcc_cnt_entry;
+// meta->lccum_cnt_exit = obj_params->lcc_cnt_exit ;
+// meta->source_id = obj_params->source_id;
// g_print("source id: %d, Enter: %d, Exit: %d\n", meta->source_id, meta->lccum_cnt_entry, meta->lccum_cnt_exit);
}
터미널에서 CUDA_VER=10.2 로 설정하고 make 로 빌드하자.
$ sudo CUDA_VER=10.2 make
입력 변경하기 (filesrc > v4l2 camera)
이 예제는 h.264 filesrc 를 사용하고 있지만, 카메라로 입력을 받기 위해 기존의 filesrc source 는 enable=0 로 처리하고, 다음 2개의 source 를 config 파일 (test5_config_file_src_infer_tlt.txt) 에 추가하였다.
[source3]
enable=1
num-sources=2
type=1
camera-width=1920
camera-height=1080
camera-fps-n=65
camera-fps-d=1
camera-csi-sensor-id=1
camera-v4l2-dev-node=0
drop-frame-interval=5
[source2]
enable=1
num-sources=2
type=1
camera-width=1920
camera-height=1080
camera-fps-n=65
camera-fps-d=1
camera-v4l2-dev-node=1
그리고 추가된 source 가 동시에 화면에 출력될 수 있도록 display 항목에 height 를 늘려준다. (720 px → 1440 px)
[tiled-display]
enable=1
rows=2
columns=1
width=1280
height=1440
gpu-id=0
#(0): nvbuf-mem-default - Default memory allocated, specific to particular platform
#(1): nvbuf-mem-cuda-pinned - Allocate Pinned/Host cuda memory, applicable for Tesla
#(2): nvbuf-mem-cuda-device - Allocate Device cuda memory, applicable for Tesla
#(3): nvbuf-mem-cuda-unified - Allocate Unified cuda memory, applicable for Tesla
#(4): nvbuf-mem-surface-array - Allocate Surface Array memory, applicable for Jetson
nvbuf-memory-type=0
출력 변경하기 (EGL > UDP RTSP)
화면 출력을 UDP RTSP 로 변경하기 위해 config 파일의 다른 sink 는 모두 enable=0 하고, 아래의 RTSPStreaming 를 추가하였다.
[sink3]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming
type=4
#1=mp4 2=mkv
container=1
#1=h264 2=h265 3=mpeg4
codec=1
sync=0
bitrate=40000000
iframeinterval=30
rtsp-port=8554
udp-port=5400
#width=1280
#height=1440
profile=2
#udp-buffer-size=4000000
어플리케이션 실행하기
빌드가 정상적으로 끝나면, 터미널에서 테스트로 어플리케이션을 실행해본다.
$ ./deepstream-test5-analytics -c config/test5_config_file_src_infer_tlt.txt
테스트 하기
어플리케이션을 실행하면 rtsp://(IP Address)/ds-test 에서 영상이 전송된다. 아래와 같이 gstreamer 를 이용해서 영상을 수시할 수 있다.
$ gst-launch-1.0 rtspsrc location='rtsp://192.168.1.6:8554/ds-test' ! rtph264depay ! h264parse ! decodebin ! autovideosink
또는 VLC Player 와 같은 어플리케이션을 통해 영상을 수신, 재생할 수 있다.
Post-Mortem
- 이 포스팅은 Deepstream 시각화를 위해 테스트 하였다. config 파일의 sink 에서 bitrate 를 통해 영상의 품질을 조정할 수 있으나, RTSP 로 인코딩 및 전송 되는 영상의 품질 저하와 지연은 감수해야한다.
참고자료
아래 Deepstream 관련 다양한 포스팅을 참고한다.
https://makepluscode.tistory.com/category/NVIDIA%20Jeston/Deepstream
'NVIDIA Jeston > Deepstream' 카테고리의 다른 글
NVIDIA Jeston deepstream RTSP 수신 (0) | 2022.08.03 |
---|---|
딥스트림 입력 소스를 V4L2 카메라로 변경하는 방법 (0) | 2022.07.17 |
Deepstream Test1 객체 검출결과 RTSP 전송 (0) | 2022.07.17 |
Deepstream 를 이용하여 유동인구를 분석해보자! (0) | 2022.07.15 |
Deepstream 오브젝트 트래커 예제 실행하기 (0) | 2022.07.13 |
Deepstream graphviz dot 그래프를 이용한 시각화 (0) | 2022.07.13 |
Deepstream 6.0 Yolov2 Yolov3 예제 실행하기 (0) | 2022.07.11 |
Deepstream 처음 설치하고 실행하기 (1) | 2022.07.10 |