레이블이 Multimedia-Gstreamer인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Multimedia-Gstreamer인 게시물을 표시합니다. 모든 게시물 표시

7/10/2019

Deepstream의 Gst-nvinfer의 구조 와 TensorRT의 IPlugIn 기능

1. Deepstream의  GST-NVINFER 기본구조 

GST-NVINFER의 역할은 TensorRT를 이용하여, Gstreamer에서 Inferece를 하는 역할이다.
주기능은 Object Detection 과 Classfication이 될 것이다.

TensorRT의 경우는 자세한 설명은, 별도의 NVIDIA TensorRT를 찾아보거나, 현재 정리된 Manual을 참조하자.

GST_NVINFER는 단지 TensorRT의 기능의 역할만 하는 것이 아니라, IPlugIn이라는 확장 Interface를 제공하고 있다.
이는 공유라이브러리와 연결하여, 이기능을 확장하여 사용이 가능하다고 한다. 주로, cumtom layer에 사용이 된다.

기본동작은 Gstremer의 Pipeline구조에 따라 아래와 같이 동작하며, 이 때 전달되는 매개체들을 알아두자.


일반 Gstreamer 처럼 Input Buffer가 들어오고, Output Buffer가 나가는 형식이며,
nvll_infer는 Low Leve Library(libnvill_infer)에서 float RGB or BGR planar data를 Network의 dimention에따라 처리한다고 한다.


  • Input
  1. Gst_Buffer
  2. Meta Data (NvStreamMeta)  
  3. Caffe Model and Caffe Prototxt
  4. ONNX 
  5. UFF file    
상위 3,4,5 번 TensorRT의 지원되는 Platform부분을 보고, Parser를 보면 쉽게 이해가 간다. 

  • Output
  1. Gst_Buffer
  2. Meta Data (NvStreamMeta
  3. Infer Meta Data  (NvDsMeta: NVInfer에 의해 생성된 classes 정보 및 bounding box정보 

  • Control Paramets
Gst-nvinfer 즉, Gstreamer의 Control Parameter로 Config File에서 현재 설정되고 있다.
  1. Batch size
  2. Inference interval 
  3. Clustering parameters
  4. Class theshold
  5. Bonding Box color 
  6. Width and height of bounding box to filter boxes for downstream component

Gst-nvInfer의 구조를 보면, 다른 Gst-PlugIn의 구조도 거의 비슷하기에 관련부분을 이해하기가 쉬워지며, 중요한 것은 TensorRT를 어떻게 넣고, 이를 적용하는 것 같다.

1.1 Gst-nvinfer 의 Properties 

Gst Properties는 Gstreamer Command로 실행 했을 경우, 직접 넣을 수 있는 Argument라고 생각하면될 것 같다.
Source로 보면 g_object_set 함수를 이용하여 설정이 가능하며, 각각의 기능을 정확히 알아두자

아래의 config-file-path는 File을 이용하여  세부적으로  설정가능한데, 1.2에서 설명



1.2 Gst-nvinfer File Configuration Specifications

Gst-nvifer의 config file은  Key File Format으로 구성된다고 하는데, 아래의 사이트를 보거나, Config File을 보면 쉽게 이해간다.

[groupname]
Key=Value
  https://specifications.freedesktop.org/desktop-entry-spec/latest/

예제의 config_infer_primary.txt File Format이 Key File Format이라고 생각하면된다.
Gst-nvinfer 의 Config 파일 크게 아래와 같이 구성되며 세부 설정은 Manual을 참조
  1.  [property]   :   필수 설정이므로, 반드시 알아야 하며, 관련내용 Manual 참조 
  2.  [class-attrs-all] :  모든 class 를 위한 detection 설정 
  3.  [class-attrs-] : 특정 class-id만을 별도 설정가능 

Gst-nvinfer PlugIn만 이기능을 지원하며, 이 관련소스는 현재 Library로만 제공되어있기때문에 자세한 구조 및 Parsing 소스를 알수 없으며,
Manual 과 Sample 예제 Config를 참조하여 각 값을 보고 설정하고 테스트를 진행해야한다.

  • Gst-nvinfer(1st GIE, TensorRT)의 설정 
$ cd ~/deepstream_sdk_on_jetson/samples/configs/deepstream-app
$ cat config_infer_primary.txt  
....
[property]
net-scale-factor=0.0039215697906911373
## caffe model 
model-file=../../models/Primary_Detector/resnet10.caffemodel
## model의 Layer 구조 및 이름파악 
proto-file=../../models/Primary_Detector/resnet10.prototxt
model-engine-file=../../models/Primary_Detector/resnet10.caffemodel_b30_int8.engine
labelfile-path=../../models/Primary_Detector/labels.txt
int8-calib-file=../../models/Primary_Detector/cal_trt4.bin
batch-size=30
## 0=FP32, 1=INT8, 2=FP16 mode
network-mode=1
## 상위 labels의 class 종류가 4개 
num-detected-classes=4
interval=0
gie-unique-id=1
## 0: Custom 4 : Resnet 
parse-func=4

## 상위 proto-file의 output layer name , 즉 결과물을 보여주는 Layer 표시 
output-blob-names=conv2d_bbox;conv2d_cov/Sigmoid

#parse-bbox-func-name=NvDsInferParseCustomResnet
#custom-lib-path=/home/nvidia/deepstream_sdk_on_jetson/sources/libs/nvdsparsebbox/libnvdsparsebbox.so

## DBSCAN or  OpenCV groupRectangles for grouping detected object  (군집화)
#enable-dbscan=1

[class-attrs-all]
threshold=0.2
group-threshold=1
## Set eps=0.7 and minBoxes for enable-dbscan=1
eps=0.2
#minBoxes=3
roi-top-offset=0
roi-bottom-offset=0
detected-min-w=0
detected-min-h=0
detected-max-w=0
detected-max-h=0

## Per class configuration
#[class-attrs-2]
#threshold=0.6
#eps=0.5
#group-threshold=3
#roi-top-offset=20
#roi-bottom-offset=10
#detected-min-w=40
#detected-min-h=40
#detected-max-w=400
#detected-max-h=800




  • [propertyp]  숙지정보
  1. model-file: Caffe의 기본 Model 사용 
  2. proto-file: Caffe에서 제공하는 Layer Graph 인것 같음 
  3. model-engine-file:TensorRT용 Model Engine이며, 상위 model-file 기반으로 처음생성
  4. labelfile-path: 현재 제공되어지는 Label File 
  5. network-mode: FP32/INT8/FP16기반으로 생성가능 이를 설정 
  6. batch-szie:  들어오는 buffer의 수 (Frame/Object) , 현재 Frame이라고 생각하면됨 
  7. num-detected-classes: Label의 갯수와 맞추면됨 
  8. parse-func : [0 custom] [4: resnet] 세부사항은 Manual 

상위 파란색으로 막아진 기능은 현재 /libs/libnvdsparsebox 기능으로 기본 Binary 설치가 안되었으며, 역할은 bounding box parsing 기능이며,
사용하고 싶다면, parse-func =0 변경과 함께source/libs/libnvdparsebox/libnvdsparsebbox.so 생성후 설정 (아래의 IPlugIn에서 다시언급)


  • DBSCAN (Density-based spatial clustering of applications with noise)

상위 옵션 중에 DBSCAN이 존재하는데, 군집화를 하기위해서 사용하는 것 같으며, OpenCV 역시 비슷할 것 같다. (상위 EPS 설정과 같이 함)
  1. enable-dbscan
  2. eps=0.2

  https://bcho.tistory.com/1205


  • 관심영역 ROI(Region of Interest) 관련설정
  1. roi-top-offset=0         :  ROI의 Frame Top에서 부터 OFFSET
  2. roi-bottom-offset=0  :  ROI의Frame Bottom에서 부터 OFFSET



  • TensorRT Engine 
  1. model-engine-file
상위 *.caffemode_xxx.engine은 TensorRT용 Engine이므로, 처음 실행시 생성되며, 필요없다면 제거가능


  • 주의사항 
  1. batch-size
  2. network-mode
상위 설정값들은 아래의 deepstreeam-app 의 config 값에 의해 재해석되는되므로,  (GST-nvinfer config값을 override가 가능), 상위 설정만 보지 않고  전체설정도 같이 봐야한다.


다양한 예제 (for Telsa version)
  https://github.com/NVIDIA-AI-IOT/redaction_with_deepstream/blob/master/configs/pgie_config_fd_lpd.txt

1.3 deepstream-app 의 Config  

deepstream-app 에서만 사용되는 Config File 이며, 이 구조도 상위 구조와 동일하며, 다만 다른 점은 Gst-nvinfer Properties 의  Gst-nvinfer File Configuration 값을 덮어쓰는 것이 가능하다.

이 파일의 구조는 이전에 분석한 부분의 Parser에서 각각 값을 얻고 값을 별도로 저장을 한다.(여기서 부터는 소스로 확인가능)
이전의 Config File은 Primary-GIE (TensorRT) 설정이며, 아래의 Config에서 중복설정을 하여, 덮어쓰는 것이 가능하다.


  • Manual의 Configuration Groups (Manual 참조)
Group
Configuration
application
Configuration settings that are not related to a specific component.
tiled-display
Settings that configure tiled display in the application.
source
Settings that specify source properties. There can be multiple sources, with one configuration group for each source. The groups must be named [source0][source1], and so on.
streammux
Settings that specify the properties and modify the behavior of the streammux component.
primary-gie
Settings that specify the properties and modify the behavior of the primary GIE.
secondary-gie
Settings that specify the properties and modify the behavior of the secondary GIE. There may be multiple secondary GIEs, with one configuration group for each GIE. These groups must be named [secondary-gie0][secondary-gie1], etc.
tracker
Settings that specify the properties and modify the behavior of the object tracker.
osd
Settings that specify the properties and modify the behavior of the on-screen display (OSD) component which overlays text and rectangles on the frame.
sink
Settings that specify the properties and modify the behavior of the sink components, which represent outputs such as displays or files for rendering, encoding, and file saving. The pipeline may contain multiple sinks, with one configuration group for each sink. The groups must be named [sink0][sink1], etc.
tests
Settings for diagnostics and debugging. This configuration group is experimental.



  • 이외의 group 설정 
이외 source/gst-plugins의 모든 소스는 현재 공식 제공이 아니며, 개발중인 소스인 것 같다. 예를들면 [ds-example] 도  옵션이 존재하지만, 이부분은 테스트 중 같다.
이외에 [messsage-broker] [message-conv]도 지원할것 같으나, 현재 소스는 미지원이다.

(deepstrem_config_file_parser.c/h 소스참조)


  • 4Ch Deepstream의 전체설정 
각각은 [] 표시는 Group으로 표현되고, 이 Group은 Gstreamer의 1개의 PlugIn의  Properties 값들을 표시하며, 이 값은 상위의 Gst-nvinfer의 File Config 값을 덮어쓸수가 있다.

1st GIE(Gst-nvinfer)의 설정을 보면, [primary-gie] 를 보면 이 설정은 config_infer_primary.txt와 중복이 되며, 재정의 하는 것이 가능하므로, 이 값으로 설정가능.

$ cd ~/deepstream_sdk_on_jetson/samples/configs/deepstream-app
$ cat source4_720p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt 
[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5
#gie-kitti-output-dir=streamscl

[tiled-display]
enable=1
rows=2
columns=2
width=1280
height=720

[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI
type=3
uri=file://../../streams/sample_720p.mp4
num-sources=4

[sink0]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=2
sync=1
display-id=0
offset-x=0
offset-y=0
width=0
height=0
overlay-id=1
source-id=0

[sink1]
enable=0
type=3
#1=mp4 2=mkv
container=1
#1=h264 2=h265 3=mpeg4
codec=1
sync=0
bitrate=2000000
output-file=out.mp4
source-id=0

[sink2]
enable=0
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=4
#1=h264 2=h265 3=mpeg4
## only h264 is supported right now.
codec=1
sync=0
bitrate=4000000
# set below properties in case of RTSPStreaming
rtsp-port=8554
udp-port=5400


[osd]
enable=1
border-width=1
text-size=15
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Arial
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0

[streammux]
##Boolean property to inform muxer that sources are live
live-source=0
batch-size=4
##time out in usec, to wait after the first buffer is available
##to push the batch even if the complete batch is not formed
batched-push-timeout=40000
## Set muxer output width and height
width=1280
height=720

# config-file property is mandatory for any gie section.
# Other properties are optional and if set will override the properties set in
# the infer config file.
[primary-gie]
enable=1
model-engine-file=../../models/Primary_Detector/resnet10.caffemodel_b4_int8.engine
labelfile-path=../../models/Primary_Detector/labels.txt
batch-size=4
#Required by the app for OSD, not a plugin property
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
interval=0
gie-unique-id=1
config-file=config_infer_primary.txt

[tracker]
enable=1
tracker-width=640
tracker-height=368
#1 - KLT, 2 - IOU, other values are invalid
tracker-algorithm=1
iou-threshold=0.1

[secondary-gie0]
enable=1
model-engine-file=../../models/Secondary_VehicleTypes/resnet18.caffemodel_b16_int8.engine
labelfile-path=../../models/Secondary_VehicleTypes/labels.txt
batch-size=16
gie-unique-id=4
operate-on-gie-id=1
operate-on-class-ids=0;
config-file=config_infer_secondary_vehicletypes.txt

[secondary-gie1]
enable=1
model-engine-file=../../models/Secondary_CarColor/resnet18.caffemodel_b16_int8.engine
labelfile-path=../../models/Secondary_CarColor/labels.txt
batch-size=16
gie-unique-id=5
operate-on-gie-id=1
operate-on-class-ids=0;
config-file=config_infer_secondary_carcolor.txt

[secondary-gie2]
enable=1
model-engine-file=../../models/Secondary_CarMake/resnet18.caffemodel_b16_int8.engine
labelfile-path=../../models/Secondary_CarMake/labels.txt
batch-size=16
gie-unique-id=6
operate-on-gie-id=1
operate-on-class-ids=0;
config-file=config_infer_secondary_carmake.txt

[tests]
file-loop=0


재미있는 것은 Gstreamer 처럼 상위 정보들이 순서대로 동작될 것이라고는 생각하지 말아야하며, 소스를 분석해서 동작방식을 알아야한다.
상위정보들은 오직 config만 해당하므로, 전체 Pipeline 구조는 소스에서 확인을 해야한다.

  • 기본으로 숙지해야할 정보들 정리  
  1. [plug-in ]
  2. enable  : 사용여부 
  3. batch-size : data 갯수 


  • [tiled-display]
화면에 표시되는 window의 설정
  1. row:    2  ,  columns:  2   일 경우  4 Channel 로 표시 
  2. width, height : 본인이 설정하기 나름 

  • [source0)
1st Input srouce 설정
  1. type=3   //MultiURI  RTSP/FILE 동시 설정가능 
  2. uri=rtsp://10.0.0.196:554/h264
  3. uri=file://../../streams/sample_720p.mp4
  4. num-sources: 4    # 4channel 


  • [sink0]
1st PlugIn의 output , RTSP 설정시 아래의 sync설정도 중요
  1. sync: Indicates how the stream is to be rendered  ( 0 = As fast as possible ,1 = Synchronously)


Deepstream SDK Manual 참조

2. DeepStream 기본소스분석

상위에서 설명한 각각의 GStreamer 구조와 DeepStream의 Properties 부분을 파악해보자.

  • Deepstream의 SDK Source 전체구조 파악 
$ cd ~/deepstream_sdk_on_jetson/sources

$ tree -t -L 2 .
.
├── apps                                //Deepstream Sample Application 
│   ├── apps-common             
│   └── sample_apps             // DeepStream Samples App
├── gst-plugins                        // DeepStream PlugIn  
│   ├── gst-dsexample
│   ├── gst-nvmsgbroker
│   └── gst-nvmsgconv
├── libs                                  // Deepstream Plugin Lib      
│   ├── kafka_protocol_adaptor
│   ├── nvdsparsebbox        //nvinfer의 IPlugIn (Gst-nvinfer 의 config file에서 Load가능)
│   ├── nvmsgconv
│   └── nvds_logger
├── objectDetector_FasterRCNN      // nvInfer의 IPlugIn  FasterRCNN 
│   ├── config_infer_primary_fasterRCNN.txt
│   ├── deepstream_app_config_fasterRCNN.txt
│   ├── labels.txt
│   ├── README
│   └── nvdsinfer_custom_impl_fasterRCNN
├── objectDetector_SSD              // nvInfer의 IPlugIn  SSD  
│   ├── config_infer_primary_ssd.txt
│   ├── deepstream_app_config_ssd.txt
│   ├── nvdsinfer_custom_impl_ssd
│   └── README
└── includes
    ├── gstnvdsinfer.h
    ├── gstnvdsmeta.h
    ├── gst-nvquery.h
    ├── gstnvstreammeta.h
    ├── nvbuffer.h
    ├── nvbuf_utils.h
    ├── nvdsinfer_custom_impl.h
    ├── nvdsinfer.h
    ├── nvds_logger.h
    ├── nvdsmeta.h
    ├── nvds_msgapi.h
    └── nvosd.h


  • Deepstream의 Sampeapp의  Gstreamer PlugIn 구조파악
apps  Gstreamer의 PlugIn 구조 파악, gst_element_factory_make 함수를 찾아, gst_bin_add or gst_bin_add_many로 추가하고 gst_element_link하는지 파악

  1. deepstream-app :   create_pipeline  분석가능하며, config file갯수/설정에따라 변경
  2. deepstream-test1-app : 나머지 3개는 이해하기가 쉬움 
  3. deepstream-test2-app
  4. deepstream-test3-app


$ vi app/apps-common/includes/deepstream_config.h   // 전체 Gstreamer (DeepStream의 구조파악)
...... 
#define NVDS_ELEM_SRC_CAMERA_CSI "nvarguscamerasrc"
#define NVDS_ELEM_SRC_CAMERA_V4L2 "v4l2src"
#define NVDS_ELEM_SRC_URI "uridecodebin"

#define NVDS_ELEM_QUEUE "queue"
#define NVDS_ELEM_CAPS_FILTER "capsfilter"
#define NVDS_ELEM_TEE "tee"

#define NVDS_ELEM_PGIE "nvinfer"
#define NVDS_ELEM_SGIE "nvinfer"
#define NVDS_ELEM_TRACKER "nvtracker"

#define NVDS_ELEM_VIDEO_CONV "nvvidconv"
#define NVDS_ELEM_STREAM_MUX "nvstreammux"
#define NVDS_ELEM_STREAM_DEMUX "nvstreamdemux"
#define NVDS_ELEM_TILER "nvmultistreamtiler"
#define NVDS_ELEM_OSD "nvosd"
#define NVDS_ELEM_DSEXAMPLE_ELEMENT "dsexample"

#define NVDS_ELEM_MSG_CONV "nvmsgconv"
#define NVDS_ELEM_MSG_BROKER "nvmsgbroker"
........

$ grep -r gst_element_factory_make .   // Gstreamer 구조 파악 
./apps/apps-common/src/deepstream_primary_gie_bin.c:      gst_element_factory_make (NVDS_ELEM_VIDEO_CONV, "primary_gie_conv");
./apps/apps-common/src/deepstream_primary_gie_bin.c:  bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, "primary_gie_queue");
./apps/apps-common/src/deepstream_primary_gie_bin.c:      gst_element_factory_make (NVDS_ELEM_CAPS_FILTER, "primary_gie_caps");
./apps/apps-common/src/deepstream_primary_gie_bin.c:      gst_element_factory_make (NVDS_ELEM_PGIE, "primary_gie_classifier");
./apps/apps-common/src/deepstream_tracker_bin.c:      gst_element_factory_make (NVDS_ELEM_TRACKER, "tracking_tracker");
./apps/apps-common/src/deepstream_sink_bin.c:      bin->sink = gst_element_factory_make (NVDS_ELEM_SINK_EGL, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      bin->sink = gst_element_factory_make (NVDS_ELEM_SINK_OVERLAY, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:          gst_element_factory_make (NVDS_ELEM_SINK_FAKESINK, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:        gst_element_factory_make (NVDS_ELEM_EGLTRANSFORM, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->transform = gst_element_factory_make (NVDS_ELEM_VIDEO_CONV, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_MPEG4, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      bin->mux = gst_element_factory_make (NVDS_ELEM_MUX_MP4, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      bin->mux = gst_element_factory_make (NVDS_ELEM_MKV, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->sink = gst_element_factory_make (NVDS_ELEM_SINK_FILE, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->transform = gst_element_factory_make (NVDS_ELEM_VIDEO_CONV, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:      gst_element_factory_make (NVDS_ELEM_CAPS_FILTER, elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->rtph264pay = gst_element_factory_make ("rtph264pay", elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->sink = gst_element_factory_make ("udpsink", elem_name);
./apps/apps-common/src/deepstream_sink_bin.c:  bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, "sink_bin_queue");
./apps/apps-common/src/deepstream_sink_bin.c:  bin->tee = gst_element_factory_make (NVDS_ELEM_TEE, "sink_bin_tee");
./apps/apps-common/src/deepstream_dsexample.c:      gst_element_factory_make (NVDS_ELEM_QUEUE, "dsexample_queue");
./apps/apps-common/src/deepstream_dsexample.c:      gst_element_factory_make (NVDS_ELEM_DSEXAMPLE_ELEMENT, "dsexample0");
..............


  • Deepstream 의 상위의 1.3 deepstream-app Config 구조파악 
deepstream-app 의 config 파일의 Parser 관련된 부분 파악하기

$ tree -t apps/apps-common
apps/apps-common
├── includes
│   ├── deepstream_app.h
│   ├── deepstream_colors.h
│   ├── deepstream_common.h
│   ├── deepstream_config_file_parser.h         // 상위 1.3  deepstream-app config 의 GROUP 
│   ├── deepstream_config.h                           // gstream plugin  (app-common *.c 참조 )
│   ├── deepstream_dsexample.h
│   ├── deepstream_gie.h
│   ├── deepstream_metadata_pool.h
│   ├── deepstream_osd.h
│   ├── deepstream_perf.h
│   ├── deepstream_primary_gie.h
│   ├── deepstream_secondary_gie.h
│   ├── deepstream_sinks.h
│   ├── deepstream_sources.h
│   ├── deepstream_streammux.h
│   ├── deepstream_tiled_display.h
│   └── deepstream_tracker.h
└── src
    ├── deepstream_common.c
    ├── deepstream_config_file_parser.c                 // 상위 1.3  deepstream-app config의 GROUP 
    ├── deepstream_dsexample.c
    ├── deepstream_metadata_pool.c
    ├── deepstream_osd_bin.c
    ├── deepstream_perf.c
    ├── deepstream_primary_gie_bin.c            
    ├── deepstream_secondary_gie_bin.c       
    ├── deepstream_sink_bin.c                      // Gstreamer output 
    ├── deepstream_source_bin.c                 // Gstreamer Input
    ├── deepstream_streammux.c                 // Video 영상 Mux 기능 
    ├── deepstream_tiled_display_bin.c
    ├── deepstream_tracker_bin.c                  //  Tracker 관련 기능,  KLT or IOU
    ├── deepstream_primary_gie_bin.o
    ├── deepstream_tracker_bin.o
    ├── deepstream_config_file_parser.o
    ├── deepstream_metadata_pool.o
    ├── deepstream_source_bin.o
    ├── deepstream_common.o
    ├── deepstream_perf.o
    ├── deepstream_sink_bin.o
    ├── deepstream_dsexample.o
    ├── deepstream_osd_bin.o
    ├── deepstream_secondary_gie_bin.o
    ├── deepstream_tiled_display_bin.o
    └── deepstream_streammux.o

$ cat apps/apps-common/includes/deepstream_config_file_parser.h   // 1.3 참조, 이 곳에 선언된 GROUP가준으로 Gst Properies의 Config를 작성가능 
......
#define CONFIG_GROUP_SOURCE "source"
#define CONFIG_GROUP_OSD "osd"
#define CONFIG_GROUP_PRIMARY_GIE "primary-gie"
#define CONFIG_GROUP_SECONDARY_GIE "secondary-gie"
#define CONFIG_GROUP_TRACKER "tracker"
#define CONFIG_GROUP_SINK "sink"
#define CONFIG_GROUP_TILED_DISPLAY "tiled-display"
#define CONFIG_GROUP_DSEXAMPLE "ds-example"
#define CONFIG_GROUP_STREAMMUX "streammux"
......

$ cat apps/apps-common/src/deepstream_config_file_parser.c   // 1.3 참조,  이 곳에 선언된 GROUP의 각각의 Properies 설정부터 관련기능 확인가능  
......
#define CONFIG_GROUP_ENABLE "enable"

#define CONFIG_GROUP_APP "application"
#define CONFIG_GROUP_APP_ENABLE_PERF_MEASUREMENT "enable-perf-measurement"
#define CONFIG_GROUP_APP_PERF_MEASUREMENT_INTERVAL "perf-measurement-interval-sec"
#define CONFIG_GROUP_APP_GIE_OUTPUT_DIR "gie-kitti-output-dir"

#define CONFIG_GROUP_TESTS "tests"
#define CONFIG_GROUP_TESTS_FILE_LOOP "file-loop"

#define CONFIG_GROUP_SOURCE_ENABLE "enable"
#define CONFIG_GROUP_SOURCE_TYPE "type"
#define CONFIG_GROUP_SOURCE_CAMERA_WIDTH "camera-width"
#define CONFIG_GROUP_SOURCE_CAMERA_HEIGHT "camera-height"
#define CONFIG_GROUP_SOURCE_CAMERA_FPS_N "camera-fps-n"
#define CONFIG_GROUP_SOURCE_CAMERA_FPS_D "camera-fps-d"
#define CONFIG_GROUP_SOURCE_CAMERA_CSI_SID "camera-csi-sensor-id"
#define CONFIG_GROUP_SOURCE_CAMERA_V4L2_DEVNODE "camera-v4l2-dev-node"
#define CONFIG_GROUP_SOURCE_URI "uri"
#define CONFIG_GROUP_SOURCE_LATENCY "latency"
#define CONFIG_GROUP_SOURCE_NUM_SOURCES "num-sources"
#define CONFIG_GROUP_SOURCE_INTRA_DECODE "intra-decode-enable"

#define CONFIG_GROUP_STREAMMUX_WIDTH "width"
#define CONFIG_GROUP_STREAMMUX_HEIGHT "height"
#define CONFIG_GROUP_STREAMMUX_BATCH_SIZE "batch-size"
#define CONFIG_GROUP_STREAMMUX_BATCHED_PUSH_TIMEOUT "batched-push-timeout"
#define CONFIG_GROUP_STREAMMUX_LIVE_SOURCE "live-source"

#define CONFIG_GROUP_OSD_MODE "osd-mode"
#define CONFIG_GROUP_OSD_BORDER_WIDTH "border-width"
#define CONFIG_GROUP_OSD_BORDER_COLOR "border-color"
#define CONFIG_GROUP_OSD_TEXT_SIZE "text-size"
#define CONFIG_GROUP_OSD_TEXT_COLOR "text-color"
#define CONFIG_GROUP_OSD_TEXT_BG_COLOR "text-bg-color"
#define CONFIG_GROUP_OSD_FONT "font"
#define CONFIG_GROUP_OSD_CLOCK_ENABLE "show-clock"
#define CONFIG_GROUP_OSD_CLOCK_X_OFFSET "clock-x-offset"
#define CONFIG_GROUP_OSD_CLOCK_Y_OFFSET "clock-y-offset"
#define CONFIG_GROUP_OSD_CLOCK_TEXT_SIZE "clock-text-size"
#define CONFIG_GROUP_OSD_CLOCK_COLOR "clock-color"

//현재 GIE에서 설정가능한 Properties 들이며, 세부사용법은 Manual 
#define CONFIG_GROUP_GIE_BATCH_SIZE "batch-size"
#define CONFIG_GROUP_GIE_MODEL_ENGINE "model-engine-file"
#define CONFIG_GROUP_GIE_CONFIG_FILE "config-file"
#define CONFIG_GROUP_GIE_LABEL "labelfile-path"
#define CONFIG_GROUP_GIE_UNIQUE_ID "gie-unique-id"
#define CONFIG_GROUP_GIE_ID_FOR_OPERATION "operate-on-gie-id"
#define CONFIG_GROUP_GIE_BBOX_BORDER_COLOR "bbox-border-color"
#define CONFIG_GROUP_GIE_BBOX_BG_COLOR "bbox-bg-color"
#define CONFIG_GROUP_GIE_CLASS_IDS_FOR_OPERATION "operate-on-class-ids"
#define CONFIG_GROUP_GIE_INTERVAL "interval"
#define CONFIG_GROUP_GIE_RAW_OUTPUT_DIR "infer-raw-output-dir"
.............

이 기능들은 각각의 GROUP인 parse_xxx 함수에 의해 호출되며, GIE인 경우 parse_gie가 된다. 
그리고, 상위의 Gst Properites의 Config 파일로 읽어 각 Group의 Config 변수에 저장되어지며, GIE의 경우 NvDsGieConfig 저장 



3. Gst-nvinfer(TensorRT)의 IPlugin 확장기능 

TensorRT의 Custom layer를 위한 확장기능으로 동작하는 방식은 IPlugin Interface를 연결하여 만들고, 본인이 원하는 Layer를 공유라이브러리로 구현하면된다고한다.

이 기능을 테스트하기위해서는 각각의 Framwork의 Model과 관련 Label 정보가 필요하며, 이는 기존의 TensorRT 예제에서 가져오고 테스트를 진행한다.
그러므로, 기존에 사용했던 TensorRT 부분을 확인하고 가자.


  • 필요사항 
  1. Framework의 pre-trained Model (Caffe, UFF (Tensorflow) )
  2. lable or prototxt file ( Framework에 의존적임)


  • Deepstream 에서 제공되어지는 기본예제들 
  1. nvinfer의 IPlugIn FasterRCNN  (Caffe)
  2. nvinfer의 IPlugIn SSD (Tensorflow)



  • TensorRT Layer 특징과 Presion 정보 (PlugIn Layer)
TensorRT의 Layer의 특징과 제약사항들을 다시 알아보고, PlugIn의 Layer관련부분을 알아보자.

  https://docs.nvidia.com/deeplearning/sdk/tensorrt-support-matrix/index.html#layers-matrix
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-support-matrix/index.html#hardware-precision-matrix



  • TensorRT Plugin Layer 와  API 
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#pluginv2-layer
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#plugin-api-desc



3.1 IPlugin 관련 소스 확인 및 기본적인 이해 와 분석 

Deepstream 3.0 SDK에서  Gst-nvinfer(TensorRT)IPluginV2 and IPluginCreator interface를 지원하며 DeepStream SDK Manual의 5장참조하자.

상위 2장의 전체 Deepstream SDK 3.0 Source에서 IPlugin 부분들을 보면될 것 같다.
Gst-nvinfer에서 config file에서 key로 설정하여 본인이 만든 공유 library loading 방식이며, bbox(boundbox)를 다 독자적으로 구현을 했다.

현재 주 사용하는 목적은 현재로는 bbox 구현으로만 보이지만, 본인이 원하면, 다른것으로도 구현이 가능할 것 같다.
Output layer를 기반으로 본인이 얻고자하는 Data를 가공하여 이를 만들면 되겠지만, 역시 등록해야하는 함수 Key가 필요하기때문에 제한적일 것 같다.


  • TensorRT의 IPlugInV2 예제 소스 
  1. libs/nvdsparsebox: bound box 구현 
  2. ObjectDetector_FasterRCNN: bound box 구현 
  3. ObjectDetector_SSD: bound box 구현 

TensorRT는 C++기반의 Library Engine이며, 아래와 같이 Class를 제공하더라도 어디에 속했는지가 중요하므로, 각각의 Manual을 볼때 주의하도록하자.

  • TensorRT의 Main Class List
  1. nvcaffeparser1
  2. nvinfer1
  3. nvonnxparser
  4. nvuffparser

Class List
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/annotated.html

  • nvdsinfer_custom_impl.h
  1. NvDsInferPluginFactoryCaffeGet
  2. NvDsInferPluginFactoryCaffeDestroy
  3. NvDsInferPluginFactoryUffGet
  4. NvDsInferPluginFactoryUffDestroy

IPluginFactory  Class의 제공하는 Main Class들
  1. nvinfer1::IPluginFactory                      :  TensorRT 
  2. nvuffparser1::IPluginFactory              :  UFF Parser
  3. nvuffparser1::IPluginFactoryExt         :  UFF Parser
  4. nvcaffeparser1::IPluginFactory          :  Caffe Parser  
  5. nvcaffeparser1::IPluginFactoryExt    :  Caffe Parser  
  6. nvcaffeparser1::IPluginFactoryV2      :  Caffe Parser  

DeepStream SDK Manual 의 5.0 IPLUGIN INTERFACE 부분 참조

IPluginCreator or IPluginFactory Interface를 사용하기위해 반드시 독립적인 custom library(공유 Library)를 구현해야하며, 이 Library는 Gst-nvinfer 의  custom-lib-path  key로  설정이 가능하다.
이 예가 lib/nvdsparsebox 이며 Gst-nvinfer에 상위 설정을 적용하며, 이 Library를 Plugin가능하다.

  • 1stGIE Config File
Gst-nvinfer Config File들을 비교해보면, 아래와 같이 Custom Shared LibraryCustom Function 을 bbox를 위해 등록.(파란색참조)

$ cat deepstream_sdk_on_jetson/samples/configs/deepstream-app/config_infer_primary.txt
## 1st GIE는 오직 4개만 분류가능 
num-detected-classes=4
## Array of output layer  names , 세미콜론을 구분 
output-blob-names=conv2d_bbox;conv2d_cov/Sigmoid  
...
# 0:custom 1:GoogleNet 2:NVIDIA Type0 3:NVIDIA Type1 4: ResNet 
parse-func=4
##  //libs/nvsparsebox/nvdsparsebbox.cpp 에 함수가 구현됨
#parse-bbox-func-name=NvDsInferParseCustomResnet
##   IPlugin 연결 (Gst-nvinfer 이를 dlopen 연결)
#custom-lib-path=/home/nvidia/deepstream_sdk_on_jetson/sources/libs/nvdsparsebbox/libnvdsparsebbox.so   

$ cat deepstream_sdk_on_jetson/sources/objectDetector_FasterRCNN/config_infer_primary_fasterRCNN.txt 
..

# 1st GIE는 오직 21 개만 분류가능 
num-detected-classes=21
# Array of output layer  names , 세미콜론을 구분 
output-blob-names=bbox_pred;cls_prob;rois         

...
# 0:custom 1:GoogleNet 2:NVIDIA Type0 3:NVIDIA Type1 4: ResNet 
parse-func=0
parse-bbox-func-name=NvDsInferParseCustomFasterRCNN                                                           
custom-lib-path=nvdsinfer_custom_impl_fasterRCNN/libnvdsinfer_custom_impl_fasterRCNN.so

$ cat deepstream_sdk_on_jetson/sources/objectDetector_SSD/config_infer_primary_ssd.txt 

## 0=FP32, 1=INT8, 2=FP16 mode
network-mode=0       

##1st GIE는 오직 91 개만 분류가능 
num-detected-classes=91 

## Array of output layer  names , 세미콜론을 구분 
output-blob-names=MarkOutput_0    

...
## 0:custom 1:GoogleNet 2:NVIDIA Type0 3:NVIDIA Type1 4: ResNet 
parse-func=0        
## bbox 구현된 function              
parse-bbox-func-name=NvDsInferParseCustomSSD
custom-lib-path=nvdsinfer_custom_impl_ssd/libnvdsinfer_custom_impl_ssd.so


현재는 UFF와 Caffer만 지원가능한 것 같고, ONMX의 경우는 언급이 없으며, 예제도 아직없다.
지원을 한다고 하는데, 지금은 왠지 동작 안될 것 같다.


  • nvdsplugin_xxx.cpp :    ( IPluginV2 , IPluginCreator )
상위에 언급된 Class를 가지고, IPlugIn를 만들어 TensorRT에 등록하는 기능같다.

nvinfer1 

nvinfer1::IPluginV2 Class Reference
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/classnvinfer1_1_1_i_plugin_v2.html

nvinfer1::IPluginCreator Class Reference
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/classnvinfer1_1_1_i_plugin_creator.html

nvinfer1::IPluginFactory Class Reference
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/classnvinfer1_1_1_i_plugin_factory.html


  • nvdsparsebbox_xxx.cpp
이미 pre-trained Model에서 Layer의 이름을 가지고 찾아 그 Layer에서 나온 값을 기준으로  bbox(bounding box) 함수를 만들어 동작시키는 구조이다.
이때 사용되어지는 모듈들이 Layer를 찾기위해서 Parser를 사용하며,   상위 nvinfer도 같이 사용하는 것 같다.

nvuffparser and nvcaffeparser1 

nvuffparser::IPluginFactory Class Reference
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/classnvuffparser_1_1_i_plugin_factory.html

nvcaffeparser1::IPluginFactory Class Reference
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/classnvcaffeparser1_1_1_i_plugin_factory.html


세부내용은Deepstream SDK Manual참조

  • Deepstream SDK 3.0의 FasterRCNN 과 SSD 의 소스 
각각의 UFF, Caffe에 따라 구현되어지는 함수가 다른 것 같으며, UFF가 가장 쉽게 연결하여 구현할수 있을 것 같다.

$ cd ~/deepstream_sdk_on_jetson/sources/objectDetector_FasterRCNN/nvdsinfer_custom_impl_fasterRCNN
$ ls
factoryFasterRCNN.h        libnvdsinfer_custom_impl_fasterRCNN.so  nvdsinitinputlayers_fasterRCNN.cpp  nvdsparsebbox_fasterRCNN.cpp
factoryFasterRCNNLegacy.h  Makefile                                nvdsiplugin_fasterRCNN.cpp          nvdssample_fasterRCNN_common.h

$ cd ~/deepstream_sdk_on_jetson/sources/objectDetector_SSD/nvdsinfer_custom_impl_ssd
$ ls
libnvdsinfer_custom_impl_ssd.so  Makefile  nvdsiplugin_ssd.cpp  nvdsparsebbox_ssd.cpp


TensorRT의 IPlugIN의 C++ 기능
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/classnvinfer1_1_1_i_plugin.html

TensorRT의 IPlugIN Python API기능
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/python_api/infer/Plugin/pyPlugin.html

Extending TensorRT With Custom Layers
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#extending


3.2 IPlugIn FasterRCNN 기능확인 (Caffe 기반)

DeepStream SDK의 포함된 FasterRCNN(objectDetector_FasterRCNN)을 Build하여, 각각의 Sample 영상을 확인하자.


  • Deepstram FasterRCNN 준비작업  
README를 읽어보면, CafferModel과 기존의 TensorRT의 prototxt file이 필요하다.
CaffeModel은 인터넷에서 아래와 같이 사이트에서 찾고, config 파일 기준으로 환경을 설정해주자.
  https://docs.openvinotoolkit.org/2018_R5/_samples_object_detection_demo_README.html


$ cd ~/deepstream_sdk_on_jetson/sources/objectDetector_FasterRCNN

$ ls   //README 참고하고, 두개의 Config가 존재 
config_infer_primary_fasterRCNN.txt  deepstream_app_config_fasterRCNN.txt  labels.txt  nvdsinfer_custom_impl_fasterRCNN  README

$ cd nvdsinfer_custom_impl_fasterRCNN/
$ make    //  libnvdsinfer_custom_impl_fasterRCNN.so 생성확인 

$ cd ..

//download VGG16_faster_rcnn_final.caffemodel
$ wget https://dl.dropboxusercontent.com/s/o6ii098bu51d139/faster_rcnn_models.tgz?dl=0  

$ mv 'faster_rcnn_models.tgz?dl=0' faster_rcnn_models.tgz

$ tar zxvf faster_rcnn_models.tgz 
faster_rcnn_models/
faster_rcnn_models/ZF_faster_rcnn_final.caffemodel
faster_rcnn_models/VGG16_faster_rcnn_final.caffemodel

$ ln -s faster_rcnn_models/VGG16_faster_rcnn_final.caffemodel VGG16_faster_rcnn_final.caffemodel

$ cp /usr/src/tensorrt/data/faster-rcnn/faster_rcnn_test_iplugin.prototxt .


  • FastRCNN의 CMD Gstreamer 와 deepstream-app 비교 영상확인 

$ pwd
/home/nvidia/deepstream_sdk_on_jetson/sources/objectDetector_FasterRCNN

$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! \
        decodebin ! nvinfer config-file-path= config_infer_primary_fasterRCNN.txt ! \
        nvvidconv ! nvosd ! nvegltransform ! nveglglessink

$ deepstream-app -c deepstream_app_config_fasterRCNN.txt

두개의 영상 느리며, 실시간으로 사용하기가 힘들것으로 보이며, 현재 FP32엔진으로 사용

CMD-Gstreamer에 Gst-nvinfer 설정은 가능하지만 metadata 처리를 위한 Callback Function이 없기에 아래와 같이 OSD에 Class를 표시 못하고 Detection만 가능



deepstream-app 기존처럼 동작하지만, PERF의 7 ~8 FPS로 동작되어 느림 (실시간은 힘듦)




3.3  IPlugIn SSD 기능확인 (Tensorflow 기반) 

Deepstream SDK에 동일하게 UFFSSD(objectDetector_SSD)를 부분을 Build를 진행하고, Tensorflow에서 Training 된 *.PB파일을 받아 이를 UFF로 변경 후에
이를 상위 objectDetector_SSD를 이용하여 동영상을 확인하자.

  • Deepstream SSD 작업준비사항
동일하게 README를 읽어보면, 준비작업이 필요하며, 필요사항을 설치 및 준비해주자.
UFF Model: x86에서 Tensorflow PB파일을 받아 UFF로 변환을 하고 이를 가져와야한다
Label File: TensorRT Sampel에서 가져옴

$ cd ~/deepstream_sdk_on_jetson/sources/objectDetector_SSD

$ ls   //README 참고하고, 두개의 Config가 존재 
config_infer_primary_ssd.txt  deepstream_app_config_ssd.txt  nvdsinfer_custom_impl_ssd  README


$ cd nvdsinfer_custom_impl_ssd/
$ make    //  libnvdsinfer_custom_impl_ssd.so 생성확인 
$ cd  ..

//$ cat  /usr/src/tensorrt/samples/sampleUffSSD/README   
//download ssd_inception_v2_coco_2017_11_17.tar.gz
$ wget  http://download.tensorflow.org/models/object_detection/ssd_inception_v2_coco_2017_11_17.tar.gz 

$ tar zxvf ssd_inception_v2_coco_2017_11_17.tar.gz
ssd_inception_v2_coco_2017_11_17/
ssd_inception_v2_coco_2017_11_17/model.ckpt.index
ssd_inception_v2_coco_2017_11_17/model.ckpt.meta
ssd_inception_v2_coco_2017_11_17/frozen_inference_graph.pb
ssd_inception_v2_coco_2017_11_17/model.ckpt.data-00000-of-00001
ssd_inception_v2_coco_2017_11_17/saved_model/
ssd_inception_v2_coco_2017_11_17/saved_model/saved_model.pb
ssd_inception_v2_coco_2017_11_17/saved_model/variables/
ssd_inception_v2_coco_2017_11_17/checkpoint

//$ cp   /usr/src/tensorrt/samples/sampleUffSSD/config.py  .                    (config.py)
//$ convert-to-uff --input-file frozen_inference_graph.pb -O NMS -p config.py   (x86에서 변환) 

$ mv frozen_inference_graph.uff sample_ssd_relu6.uff

$ cp /usr/src/tensorrt/data/ssd/ssd_coco_labels.txt .


  • SSD CMD GStreamer와 deepstream-app 비교 영상확인  
동일한 기능을 Gstreamer를 이용하여 실행해보고, deepstream app를 이용해서 비교를 해보면, deepstream app 내부에는 callback function 에서
Stream의 metadata처리하여 OSD에 이를 적용하는부분 때문에 두 실행결과가 다르다.

결과적으로, metadata 처리를 위한 callback function들은 작성을 해야겠다.

$ pwd
/home/nvidia/deepstream_sdk_on_jetson/sources/objectDetector_SSD

$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! \
        decodebin ! nvinfer config-file-path= config_infer_primary_ssd.txt ! \
        nvvidconv ! nvosd ! nvegltransform ! nveglglessink

$ deepstream-app -c deepstream_app_config_ssd.txt


CMD-Gstreamer 실행 , 이전 Faster RCNN과 속도는 비교가 안되며, 실시간으로 가능
(상위와 동일하게 Callback Function이 동작하지 않으므로,  OSD Label 표시가 안됨)


deepstream-app 돌려서 OSD에서 각 Class가 구분되며, 실시간으로 FPS 30으로 동작가능확인 




  • RTSP (IP Camera 설정으로 변경)
만약  IP 카메라로 RTSP를 이용하여 실시간으로 테스트 하고 싶다면, Config File을 수정하여 손쉽게 동작가능하며 테스트도 상위와 동일 (수정방법 아래)

$ pwd
/home/nvidia/deepstream_sdk_on_jetson/sources/objectDetector_SSD

$ cp deepstream_app_config_ssd.txt  deepstream_app_rtsp.txt

$ vi deepstream_app_rtsp.txt

[source0]
...
#uri=file://../../samples/streams/sample_720p.mp4
uri=rtsp://10.0.0.196:554/h264

[sink0]
..
sync=0


[tracker]         //이부분 IOU 변경 
..
tracker-algorithm=2

다른 batch-size도 변경해도 됨 

$ deepstream-app -c  deepstream_app_rtsp.txt


3.4  TensorRT의 기능 재확인 

TensorRT의 기능 확인
  1. SampleFasterRCNN확인 (Caffe Model 사용)
  2. SampleUFFSSD 확인 (UFF Format 현재 거의 Tensorflow) 

이를 테스트 한지 오래되어 아래와 같이 TensorRT 부분을 재확인

$ ls /usr/src/tensorrt/samples  // TensorRT의 전체 Sample Source 확인 
common     Makefile         sampleCharRNN     sampleGoogleNet  sampleINT8API  sampleMNIST     sampleMovieLens  sampleOnnxMNIST  sampleSSD       sampleUffSSD
getDigits  Makefile.config  sampleFasterRCNN  sampleINT8       sampleMLP      sampleMNISTAPI  sampleNMT        samplePlugin     sampleUffMNIST  trtexec

$ ls /usr/src/tensorrt/samples/sampleFasterRCNN  //FasterRCNN Source 및 README 확인 
factoryFasterRCNN.h  Makefile  README.txt  sampleFasterRCNN.cpp

$ ls /usr/src/tensorrt/samples/sampleUffSSD  //sampleUffSSD Source 및 README 확인 
BatchStreamPPM.h  config.py  Makefile  README.txt  sampleUffSSD.cpp


$ ls /usr/src/tensorrt/bin/    // TensorRT의 Binary 확인 
chobj/                    sample_fasterRCNN         sample_int8_api_debug     sample_mnist_api_debug    sample_onnx_mnist         sample_uff_mnist          
dchobj/                   sample_fasterRCNN_debug   sample_int8_debug         sample_mnist_debug        sample_onnx_mnist_debug   sample_uff_mnist_debug    
download-digits-model.py  sample_googlenet          sample_mlp                sample_movielens          sample_plugin             sample_uff_ssd            
giexec                    sample_googlenet_debug    sample_mlp_debug          sample_movielens_debug    sample_plugin_debug       sample_uff_ssd_debug      
sample_char_rnn           sample_int8               sample_mnist              sample_nmt                sample_ssd                trtexec                   
sample_char_rnn_debug     sample_int8_api           sample_mnist_api          sample_nmt_debug          sample_ssd_debug          trtexec_debug   

$ ls /usr/src/tensorrt/data/faster-rcnn/
000456.ppm  000542.ppm  001150.ppm  001763.ppm  004545.ppm  faster_rcnn_test_iplugin.prototxt

$ ls /usr/src/tensorrt/data/ssd/
bus.ppm  dog.ppm  ssd_coco_labels.txt


TensorRT-UFF Convert Python API
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/python_api/uff/uff.html

TensorRT Python and Python API
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/python_api/index.html
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/#python

convert-to-uff  상위의 python API로 제공 혹은  tf_to_trt.py 제공하지만, x86기반만 가능
  https://devtalk.nvidia.com/default/topic/1025246/jetson-tx2/where-is-convert-to-uff/

TensorRT x86 Install Guide (convert-to-uff 설치확인)
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-install-guide/index.html

관련소스
  https://github.com/NVIDIA-AI-IOT/tf_to_trt_image_classification

Tensorflow 와 TensorRT Chatbot 예제
  https://github.com/AastaNV/ChatBot


6/25/2019

DeepStream SDK 3.0 기본자료 및 설치/실행 (Jetpack 4.2 와 4.1.1 )

1. DeepStream SDK 3.0 설치 및 기본자료수집  

  • Jetson TX2의 DeepStream 관련기능 및 세부내용 
Jetson TX2에서도 TensorRT의 확장성을 위해서 Multimedia 자료를 테스트 진행했고,  NVIDIA의 Manual을 읽는 도중에 DeepStream기능을
알게되었으며, 현재 Jetson TX2 의 DeepStream 관련자료를 정리한다.
아래의 자료를 보면 쉽게 이해를 할수 있다.

TensorRT 와 Deepstream 관련부분
  https://ahyuo79.blogspot.com/2019/06/tensorrt-50-deepstream.html

TensorRT 와 Multimedia Sample 의 기본이해
  https://ahyuo79.blogspot.com/2019/06/tensorrt-50-multimedia-sample.html

Deepstream SDK 1.5의 에러사항
  https://ahyuo79.blogspot.com/2019/06/deepstream-sdk-15-jetson-tx2-test.html


  • Jeston AGX Xavier 의 DeepStream SDK 3.0 
현재 Jetson AGX Xavier에서는 DeepStream 3.0 beta version 지원하며, Telsa 경우와는 다르지만 비교적 괜찮게 동작된다고 한다. ( 라이센스를 보면 정식버전이 아님)
물론 x86기반의 Tesla version 안정화되어있으며, NVIDIA에서 Docker까지 제공해주는 것으로 보인다.

DeepStream의 Version은 각각의 HW에 따라 지원사항이 다르며, 구성도 다르므로, 관련 HW에 따라서 반드시 확인을 하자.
(Tesla (x86) , Jetson-x 보드에 따라 다름)

Jetson AGX Xavier에 이미 설치된 JetPack 4.2에서 테스트를 진행 후 JetPack 4.1.1를 재설치 후 다시 진행예정

Jetpack 4.1.1
   https://developer.nvidia.com/embedded/jetpack-4-1-1

1.1  NVIDIA DeepStream SDK 관련자료수집 

DeepStream SDK
  https://developer.nvidia.com/deepstream-sdk

DeepStream  SDK for Jetson 과 Manual Download
  https://developer.nvidia.com/embedded/deepstream-on-jetson-downloads

DeepStream  (중국/일본) GTC 자료로추정
 http://on-demand.gputechconf.com/gtc-cn/2018/pdf/CH8307.pdf
 https://www.slideshare.net/NVIDIAJapan/1-jetson

DeepStream 2.0 Webinar 자료
 https://docplayer.net/98984804-Deepstream-sdk-2-0-webinar-james-jeun-july-2018.html

NVIDIA Deepstream Youtube 자료 ( GTC자료와 중복)
  https://www.youtube.com/watch?v=Hdew1P1nXBc
  https://www.youtube.com/watch?v=H2blB7MGnx4

NVIDIA AGX Xavier Deepstream 3.0 동작 (현재 동일하게 확인가능)
  https://www.youtube.com/watch?v=gbjUW_4l-hw

NVIDIA Webinar 자료 (무료)
  https://www.nvidia.com/en-us/about-nvidia/webinar-portal/

NVIDIA GTC Keynote
  https://on-demand-gtc.gputechconf.com/gtcnew/on-demand-gtc.php

NVIDIA GTC on Demand
- Using the Deepstream SDK for AI-Based Video Analytics
  http://on-demand-gtc.gputechconf.com/gtc-quicklink/hqGEv


1.2 DeepStream SDK 3.0  설치방법 

Jetson AGX Xavier에서 Deepstream 3.0을 각 Jetpack Version 마다 설치를 진행

  • DeepStream 3.0 SDK 설치방법 (Host)
Host에서 Key 중복 및 상위에서 download한 file target copy

$ ssh-keygen -R 192.168.55.1  // Key 재발행 후 재접속, 기존에 Jetson TX2사용  

$ scp ./DeepStreamSDK-Jetson-3.0_EA_beta5.0.tbz2 nvidia@192.168.55.1:~

$ ssh -X nvidia@192.168.55.1   // Jetson USB로 연결됨  ( Target 접속)


  • DeepStream 3.0 SDK 설치방법 (Target)
아래와 같이 직접 Deepstream Binary File을 설치하여 기본적인 테스트를 진행하자.
$ cd ~  // Jetson TX2 

$ tar xpvf DeepStreamSDK-Jetson-3.0_EA_beta5.0.tbz2

$ cd deepstream_sdk_on_jetson                   //deepstream app 설치된 장소 

$ sudo tar -xvf binaries.tbz2 -C /       //deepstream binary package 설치 
usr/
usr/lib/
usr/lib/aarch64-linux-gnu/
usr/lib/aarch64-linux-gnu/tegra/
usr/lib/aarch64-linux-gnu/tegra/libnvds_msgconv.so.1.0.0  //sources/libs/nvmsgconv 참고
usr/lib/aarch64-linux-gnu/tegra/libnvll_infer.so.1.0.0
usr/lib/aarch64-linux-gnu/tegra/libnvds_logger.so                  //sources/libs/nvds_logger 참고 
usr/lib/aarch64-linux-gnu/tegra/libgstnvquery.so
usr/lib/aarch64-linux-gnu/tegra/libnvds_kafka_proto.so           //sources/libs/kafka_protocol_adaptor 참고 (config에서 [message-broker]  설정가능)
usr/lib/aarch64-linux-gnu/tegra/libnvtracker.so.1.0.0
usr/lib/aarch64-linux-gnu/libgstnvdsmeta.so
usr/lib/aarch64-linux-gnu/gstreamer-1.0/
usr/lib/aarch64-linux-gnu/gstreamer-1.0/libnvdsgst_msgbroker.so       //sources/gst-plugins/gst-nvmsgbroker  
usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvtracker.so
usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvmultistream.so
usr/lib/aarch64-linux-gnu/gstreamer-1.0/libnvdsgst_msgconv.so             //sources/gst-plugins/gst-nvmsgconv
usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvinfer.so
usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvdsexample.so             //sources/gst-plugins/gst-dsexample
usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvosd.so
usr/bin/
usr/bin/deepstream-test2-app  // source 의 deepstream-app 4 종류 
usr/bin/deepstream-test1-app
usr/bin/deepstream-test3-app
usr/bin/deepstream-app

$ tree -L 3               //Deepstream SDK 3.0 전체 구조 파악 
.
├── binaries.tbz2         // DeepStream Binary Package , 아래의 Source 부분의 app들  관련 Library 들 
├── LicenseAgreement.pdf
├── README                // 설치전 Deepstream 설치참고 Manual   
├── samples                // DeepStream Model/Sample/Config File 구성 
│   ├── configs
│   │   └── deepstream-app   // Config File 상위 README 에서 확인
│   ├── models    //GIE의 Primary 와 Secondary 설정옵션이 다름                                 
│   │   ├── Primary_Detector            // Caffe Model 및 label 과   1st GIE(TensorRT Engine) 생성
│   │   ├── Secondary_CarColor        // Caffe Model 및 label 과  2nd GIE(TensorRT Engine) 생성
│   │   ├── Secondary_CarMake        // Caffe Model 및 label 과  3th GIE(TensorRT Engine) 생성
│   │   └── Secondary_VehicleTypes  // Caffe Model 및 label 과  4th GIE(TensorRT Engine) 생성
│   └── streams
│       ├── sample_720p.h264
│       └── sample_720p.mp4
└── sources                 // DeepStream 관련 전체소스 
    ├── apps
    │   ├── apps-common
    │   └── sample_apps
    ├── gst-plugins          // 상위 binaries.tbz2 에서 이미설치되고, 아래의 Libs와 연결 
    │   ├── gst-dsexample       // openCV로 ROI형식으로 지정하는 예제이며, 이기반으로 PlugIn을 만들수 있다.
    │   ├── gst-nvmsgbroker    // Source code for a plugin to send data to the server using the Kafka protocol adapter 
    │   └── gst-nvmsgconv      //Source code for a plugin to convert metadata to schema format
    ├── includes
    │   ├── gstnvdsinfer.h
    │   ├── gstnvdsmeta.h
    │   ├── gst-nvquery.h
    │   ├── gstnvstreammeta.h
    │   ├── nvbuffer.h
    │   ├── nvbuf_utils.h
    │   ├── nvdsinfer_custom_impl.h
    │   ├── nvdsinfer.h
    │   ├── nvds_logger.h
    │   ├── nvdsmeta.h
    │   ├── nvds_msgapi.h
    │   └── nvosd.h
    ├── libs     // library와 별도의 test program 존재  (Kafka 추후에 사용예정)
    │   ├── kafka_protocol_adaptor  // (상위binaries.tbz2 설치)  test_kafka_proto_async, test_kafka_proto_sync Test Program 가능 
    │   ├── nvds_logger           // (상위binaries.tbz2 설치)  Test Program 별도 존재 
    │   ├── nvdsparsebbox         // 미설치된 library , 추가설치가능 
    │   └── nvmsgconv             // (상위binaries.tbz2 설치) 
    ├── objectDetector_FasterRCNN              // FasterRCNN IPlugIn 관련부분 연결 (공유 Library 연결필요) 
    │   ├── config_infer_primary_fasterRCNN.txt
    │   ├── deepstream_app_config_fasterRCNN.txt
    │   ├── labels.txt
    │   ├── nvdsinfer_custom_impl_fasterRCNN
    │   └── README
    └── objectDetector_SSD                 // SSD IPlugIn 관련부분 연결  (공유 Library 연결필요) 
        ├── config_infer_primary_ssd.txt
        ├── deepstream_app_config_ssd.txt
        ├── nvdsinfer_custom_impl_ssd
        └── README                              // check README , 상위에서 요약



  • Manual 참조 (상위 SDK Download 와 별도로 Manual 로 Download가능)
(NVIDIA_DeepStream_SDK_on_Jetson_References.tar)

Sample
Path inside sources directory
Description
DsExample plugin
gst-plugins/gst-dsexample
Template plugin for integrating custom algorithms in DeepStream SDK graph.
NvMsgConv plugin
gst-plugins/gst-nvmsgconv
Source code for the NvMsgConv plugin for converting metadata to schema format.
NvMsgBroker plugin
gst-plugins/gst-nvmsgbroker
Source code for the NvMsgBroker plugin for sending data to the server.
NvMsgConv library
libs/nvmsgconv
NvMsgConv library required by the NvMsgConv plugin.
Kafka protocol adapter
libs/kafka_protocol_adapter
Protocol adapter for Kafka.
nvdsparsebbox
libs/nvdsparsebbox
Custom model bounding box parsing library example.
Simple test application 1
apps/sample_apps/deepstream-test1
Simple demonstration of how to use DeepStream SDK elements in the pipeline and extract meaningful insights from a video stream. Uses a single primary detector.
Simple test application 2
apps/sample_apps/deepstream-test2
This example builds on test application 1 to add more elements in the pipeline and extract even more information from the stream.
Simple test application 3
apps/sample_apps/deepstream-test3
Builds on test application 1 to demonstrate how to:
Use multiple sources in the pipeline
Use a uridecodebin to accept any type of input (e.g. RTSP/File), any supported container format, and any codec
Configure stream-muxer to generate a batch of frames and infer on it for better resource utilization
Extract the stream metadata, which contains useful information about the frames in the batched buffer
Simple test application 4
apps/sample_apps/deepstream-test4
Demonstrates how to generate metadata payload and transmit it to the Cloud.
DeepStream reference application
apps/sample_apps/deepstream-app
Source code for the DeepStream reference application.
UFF SSD detector
objectDetector_SSD
Configuration files and custom library implementation for the SSD detector model.
Faster RCNN detector
objectDetector_FasterRCNN
Configuration files and custom library implementation for the FasterRCNN model.

  • README 체크 (요약)
 $ vi README  // 필요사항 및 설치사항 확인  (반드시 JetPack 4.1.1, 기반)
README 관련사항 요약 
=======================================================================
Installing prerequisites on Jetson development board:
=======================================================================
Packages to be installed:
$ sudo apt-get install \
    libssl1.0.0 \
    libgstreamer1.0-0 \
    gstreamer1.0-tools \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav \
    libgstrtspserver-1.0-0 \
    libjansson4

=======================================================================
Installing librdkafka to use kafka protocol adaptor with message broker
=======================================================================
Use one of the following steps.

  sudo apt-get install librdkafka1=0.11.3-1build1

=======================================================================
Running the samples
=======================================================================
1. Go to samples directory and run:
   deepstream-app -c 
2. Application config files included in `configs/deepstream-app/`:
   a. source30_720p_dec_infer-resnet_tiled_display_int8.txt (30 Decode + Infer)
   b. source4_720p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt
      (4 Decode + Infer + SGIE + Tracker)
3. Configuration files for "nvinfer" element in `configs/deepstream-app/`:
   a. config_infer_primary.txt (Primary Object Detector)
   b. config_infer_secondary_carcolor.txt (Secondary Car Color Classifier)
   c. config_infer_secondary_carmake.txt (Secondary Car Make Classifier)
   d. config_infer_secondary_vehicletypes.txt (Secondary Vehicle Type Classifier)


$ dpkg -l  xxxx  // 확인해보면, 이미 아래의 것이 설치되었지만, 재설치 



  • 상위 README 와 같이 설치 진행 
 $ sudo apt-get install \
    libssl1.0.0 \
    libgstreamer1.0-0 \
    gstreamer1.0-tools \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav \
    libgstrtspserver-1.0-0 \
    libjansson4

$ sudo apt-get install librdkafka1=0.11.3-1build1

$ sudo ldconfig 


  • Jetson의 성능 최상으로 변경 후 테스트 진행 
$ sudo nvpmodel -m 0 
$ sudo ~/jetson_clocks.sh

처음에는 nvpmodel의 현재 상태를 확인하고, 최상으로 테스트 진행하지 말고 진행하고 두번째 최상으로 변경하고 테스트 진행하자.

1.3 deepstream-app 의 config의 구성과 이해  

실제 구동 가능한  config파일은 1/2번의 config이며, 두개의 gstreamer의 구성이 다르다.


  • deepstream-app -c   config.txt 아래 둘 중 선택 
  1. source30_720p_dec_infer-resnet_tiled_display_int8.txt (30 streams processed with Decode + Primary Infer)
  2. source4_720p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt (four streams processed with Decode + Primary Infer + Tracker + 3 Secondary GIE)

  • gst-nvinfer config file ( GIE 의 primary 와 secondary 구성)
  1. config_infer_primary.txt (sample configuration file to configure an nvinfer element as primary detector)
  2. config_infer_secondary_carcolor.txt
  3. config_infer_secondary_carmake.txt
  4. config_infer_secondary_vehicletypes.txt (sample configuration files to configure an nvinfer element as secondary classifier)


  • 상세내용은 Manual 참조
(NVIDIA_DeepStream_SDK_on_Jetson_References.tar)


2. deepstream-app 실행 비교 

현재 Deepstream SDK 3.0에서는 deepstream-app이라는 program이 기본으로 지원이 되고 있으며, 이는 상위에서 언급한 Config에 따라 동작방식이 달라진다.
Jetpack 4.2 와 4.1.1에서 각각 설치 한 후 이를 테스트를 진행을 해보며, 에러가 발생한다면, 각각의 상황을 비교해본다.
( 이외에도 다른 Deepstream-test program을 제공)


2.1 deepstream-app 실행  (JetPack 4.2)

TensorRT Engine까지 생성이 되고, 마지막 OpenMAX 진행 후에
buf_convert: Wrong src surface count in Convert Buffer 와 함께 미동작됨

$ deepstream-app -c  samples/configs/deepstream-app/source30_720p_dec_infer-resnet_tiled_display_int8.txt  // 실행과 같이 TRT Model engine을 생성한다.
config_infer_primary.txt             config_infer_secondary_carmake.txt       source30_720p_dec_infer-resnet_tiled_display_int8.txt
config_infer_secondary_carcolor.txt  config_infer_secondary_vehicletypes.txt  source4_720p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt


$ rm ~/.cache/gstreamer-1.0/registry.aarch64.bin  // ERROR 발생한 경우 , 이 파일을 지우고 다시 실행


  • JetPack4.2의 에러 
아래의 글을 읽어보면, DeepStream 3.0 Beta는 현재 JetPack 4.1.1에서만 돌아간다고 하며, 현재 아래와 동일한 에러 발생

  https://devtalk.nvidia.com/default/topic/1048737/deepstream-sdk-on-jetson/failed-to-run-samples-jetpack-4-2-on-xavier/


2.2 deepstream-app 실행  (JetPack 4.1.1 )

상위와 동일하게 설정하며, 다만 JetPack Version만 변경하고 실행

  • 처음 실행시 문제사항
  1. 공유메모리 못잡는 문제발생 ( 두번 실행하면, 문제 해결) 
  2. TensorRT Engine 생성하는 문제  (시간이 많이 걸림)
두 세번 실행시 상위 문제가 없어지며, 아래의 Cache 정보를 삭제하면, 공유메모리를 못찾는문제가 다시 발생


  • 확인사항 
  1. Perf 측정 FPS 
  2. configs 파일의 구성 및 다른 옵션 

$ rm ~/.cache/gstreamer-1.0/registry.aarch64.bin  // ERROR 발생한 경우 , 이 파일을 지우고 다시 실행 

  • 30 Channel 720 P deepstream-app ( Config 파일 구성 및 옵션체크) 

$ deepstream-app -c  samples/configs/deepstream-app/source30_720p_dec_infer-resnet_tiled_display_int8.txt                         // 실행과 같이 TRT Model engine을 생성하며, 30 Channel  720P로 보여줌 
..........
*PERF: FPS 0 (Avg) FPS 1 (Avg) FPS 2 (Avg) FPS 3 (Avg) FPS 4 (Avg) FPS 5 (Avg)FPS 6 (Avg) FPS 7 (Avg) FPS 8 (Avg) FPS 9 (Avg) FPS 10 (Avg) FPS 11 (Avg) FPS 12 (Avg) FPS 13 (Avg) FPS 14 (Avg) FPS 15 (Avg) FPS 16 (Avg) FPS 17 (Avg) FPS 18 (Avg) FPS 19 (Avg) FPS 20 (Avg) FPS 21 (Avg) FPS 22 (Avg) FPS 23 (Avg) FPS 24 (Avg) FPS 25 (Avg) FPS 26 (Avg) FPS 27 (Avg) FPS 28 (Avg) FPS 29 (Avg) 
**PERF: 35.19 (35.19) 35.19 (35.19) 33.82 (33.82) 35.19 (35.19) 33.82 (33.82) 35.19 (35.19) 33.82 (33.82) 35.19 (35.19) 33.82 (33.82) 35.19 (35.19) 35.19 (35.19) 35.19 (35.19) 35.19 (35.19) 33.82 (33.82) 33.82 (33.82) 35.19 (35.19) 35.19 (35.19) 35.19 (35.19) 33.82 (33.82) 35.19 (35.19) 35.19 (35.19) 35.19 (35.19) 35.19 (35.19) 33.82 (33.82) 33.82 (33.82) 35.19 (35.19) 33.82 (33.82) 35.19 (35.19) 33.82 (33.82) 35.19 (35.19) 
**PERF: 33.18 (33.29) 33.18 (33.29) 33.18 (33.22) 33.18 (33.29) 33.18 (33.22) 33.18 (33.29) 33.18 (33.22) 33.18 (33.29) 33.18 (33.22) 33.18 (33.29) 33.18 (33.29) 33.18 (33.29) 33.18 (33.29) 33.18 (33.22) 33.18 (33.22) 33.18 (33.29) 33.18 (33.29) 33.18 (33.29) 33.18 (33.22) 33.38 (33.48) 33.18 (33.29) 33.18 (33.29) 33.18 (33.29) 33.18 (33.22) 33.18 (33.22) 33.18 (33.29) 33.18 (33.22) 33.18 (33.29) 33.18 (33.22) 33.18 (33.29) 
**PERF: 29.98 (31.68) 29.98 (31.68) 29.98 (31.65) 29.98 (31.68) 29.98 (31.65) 29.98 (31.68) 29.98 (31.65) 29.98 (31.68) 29.98 (31.65) 29.98 (31.68) 29.98 (31.68) 29.98 (31.68) 29.98 (31.68) 29.98 (31.65) 29.98 (31.65) 29.98 (31.68) 29.98 (31.68) 29.98 (31.68) 29.98 (31.65) 29.98 (31.78) 29.98 (31.68) 29.98 (31.68) 29.98 (31.68) 29.98 (31.65) 29.98 (31.65) 29.98 (31.68) 29.98 (31.65) 29.98 (31.68) 29.98 (31.65) 29.98 (31.68) 
**PERF: 30.01 (31.13) 30.01 (31.13) 30.01 (31.11) 30.01 (31.13) 30.01 (31.11) 30.01 (31.13) 30.01 (31.11) 30.01 (31.13) 30.01 (31.11) 30.01 (31.13) 30.01 (31.13) 30.01 (31.13) 30.01 (31.13) 30.01 (31.11) 30.01 (31.11) 30.01 (31.13) 30.01 (31.13) 30.01 (31.13) 30.01 (31.11) 30.01 (31.20) 30.01 (31.13) 30.01 (31.13) 30.01 (31.13) 30.01 (31.11) 30.01 (31.11) 30.01 (31.13) 30.01 (31.11) 30.01 (31.13) 30.01 (31.11) 30.01 (31.13) 
**PERF: 30.01 (30.86) 30.01 (30.86) 30.01 (30.84) 30.01 (30.86) 30.01 (30.84) 30.01 (30.86) 30.01 (30.84) 30.01 (30.86) 30.01 (30.84) 30.01 (30.86) 30.01 (30.86) 30.01 (30.86) 30.01 (30.86) 30.01 (30.84) 30.01 (30.84) 30.01 (30.86) 30.01 (30.86) 30.01 (30.86) 30.01 (30.84) 30.01 (30.91) 30.01 (30.86) 30.01 (30.86) 30.01 (30.86) 30.01 (30.84) 30.01 (30.84) 30.01 (30.86) 30.01 (30.84) 30.01 (30.86) 30.01 (30.84) 30.01 (30.86) 
**PERF: 29.99 (30.69) 29.99 (30.69) 29.99 (30.68) 29.99 (30.69) 29.99 (30.68) 29.99 (30.69) 29.99 (30.68) 29.99 (30.69) 29.99 (30.68) 29.99 (30.69) 29.99 (30.69) 29.99 (30.69) 29.99 (30.69) 29.99 (30.68) 29.99 (30.68) 29.99 (30.69) 29.99 (30.69) 29.99 (30.69) 29.99 (30.68) 29.99 (30.73) 29.99 (30.69) 29.99 (30.69) 29.99 (30.69) 29.99 (30.68) 29.99 (30.68) 29.99 (30.69) 29.99 (30.68) 29.99 (30.69) 29.99 (30.68) 29.99 (30.69) 
**PERF: 29.99 (30.57) 29.99 (30.57) 29.99 (30.56) 29.99 (30.57) 29.99 (30.56) 29.99 (30.57) 29.99 (30.56) 29.99 (30.57) 29.99 (30.56) 29.99 (30.57) 29.99 (30.57) 29.99 (30.57) 29.99 (30.57) 29.99 (30.56) 29.99 (30.56) 29.99 (30.57) 29.99 (30.57) 29.99 (30.57) 29.99 (30.56) 29.99 (30.60) 29.99 (30.57) 29.99 (30.57) 29.99 (30.57) 29.99 (30.56) 29.99 (30.56) 29.99 (30.57) 29.99 (30.56) 29.99 (30.57) 29.99 (30.56) 29.99 (30.57) 
**PERF: 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.52) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 29.81 (30.46) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 30.01 (30.49) 
**PERF: 29.99 (30.43) 29.99 (30.43) 29.99 (30.42) 29.99 (30.43) 29.99 (30.42) 29.99 (30.43) 29.99 (30.42) 29.99 (30.43) 29.99 (30.42) 29.99 (30.43) 29.99 (30.43) 29.99 (30.43) 29.99 (30.43) 29.99 (30.42) 29.99 (30.42) 29.99 (30.43) 29.99 (30.43) 29.99 (30.43) 29.99 (30.42) 29.99 (30.45) 29.99 (30.43) 29.99 (30.43) 29.99 (30.43) 29.99 (30.42) 29.99 (30.42) 29.99 (30.40) 29.99 (30.42) 29.99 (30.43) 29.99 (30.42) 29.99 (30.43) 
**PERF: 30.07 (30.39) 30.07 (30.39) 30.07 (30.38) 30.07 (30.39) 30.07 (30.38) 30.07 (30.39) 30.07 (30.38) 30.07 (30.39) 30.07 (30.38) 30.07 (30.39) 30.07 (30.39) 30.07 (30.39) 30.07 (30.39) 30.07 (30.38) 30.07 (30.38) 29.87 (30.37) 30.07 (30.39) 30.07 (30.39) 30.07 (30.38) 30.07 (30.41) 30.07 (30.39) 30.07 (30.39) 30.07 (30.39) 30.07 (30.38) 30.07 (30.38) 30.07 (30.37) 30.07 (30.38) 30.07 (30.39) 30.07 (30.38) 30.07 (30.39) 
** INFO: : Received EOS. Exiting ...

30 (5x6 ) Channel 의 720p의 H.264영상을 처리


상위 채널중에 더블 클릭시 확대가능

상위 로그에서 Perf의 각 Frame을 확인해야한다.


  • 4 Channel 720P deepstreem-app ( Config 파일의 구성 및 옵션부분 체크)
$ deepstream-app -c  samples/configs/deepstream-app/source4_720p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt        // 실행과 같이 TRT Model engine을 생성하며,  4 Channel  720P로 보여줌 
....
**PERF: FPS 0 (Avg) FPS 1 (Avg) FPS 2 (Avg) FPS 3 (Avg)             // 왜 40 FPS가 나오는지 동영상을 봐야겠다. 
**PERF: 41.91 (41.91) 41.91 (41.91) 41.91 (41.91) 41.91 (41.91) 
**PERF: 30.01 (32.69) 30.01 (32.69) 30.01 (32.69) 30.01 (32.69) 
**PERF: 29.99 (31.52) 29.99 (31.52) 29.99 (31.52) 29.99 (31.52) 
**PERF: 30.01 (31.06) 30.01 (31.06) 30.01 (31.06) 30.01 (31.06) 
**PERF: 30.00 (30.81) 30.00 (30.81) 30.00 (30.81) 30.00 (30.81) 
**PERF: 30.00 (30.66) 30.00 (30.66) 30.00 (30.66) 30.00 (30.66) 
**PERF: 29.98 (30.55) 29.98 (30.55) 29.98 (30.55) 29.98 (30.55) 
**PERF: 30.02 (30.48) 30.02 (30.48) 30.02 (30.48) 30.02 (30.48) 
**PERF: 30.00 (30.42) 30.00 (30.42) 30.00 (30.42) 30.00 (30.42) 
**PERF: 30.00 (30.38) 30.00 (30.38) 30.00 (30.38) 30.00 (30.38) 
** INFO: : Received EOS. Exiting ...

Quitting


상위 채널중 더블 클릭할 경우




  • 사용되는 Model Network
  1. Primary GIE (1st GIE) : resnet10.caffemodel
  2. Secondary GIE(2nd GIE): resnet18.caffemodel ( 3개다 이 Model 사용)

resnet이 유명하기에 이에 관련되는 부분을 추후에 별도로 공부해야함

  • Deepstream 구조 (deepstream-app 의 경우)


  1. VIDEO DECODE:  부분은 FIle or RTSP 부터 Video Decoder 까지 지원하며, uridecodebin가 이를 둘다 지원
  2. STREAM MUX:  Decode 데이타를 Video MUX와 함께 Car-Detect 도 동작 
  3. PRIMARY DETECTOR:  1 Channel만 선택했을 경우 동작이 후는 다음 그대로 이해하면될 것 같다. 



  http://on-demand.gputechconf.com/gtc-cn/2018/pdf/CH8307.pdf


  • deepstream-app의 Callback 함수의 metadata 처리부분 
소스는 좀 복잡하지만 간단하게 deepstream-app의 metadata 처리하는 Callback 함수만 보고, 어떻게 동작하는지를 이해만 하자
  1. gie_processing_done_buf_prob Pad에 Callback Function 등록 
  2. gie_processing_done_buf_prob->process_buff  Call
  3. Buffer 처리마다 for_each_meta 하도록 Callback 등록 
  4. for_each_meta  실제적인 OSD에 표현할 데이타 구성 


$ cd ~/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-app
$ cat deepstream_app.c 
....

static gboolean
for_each_meta (GstBuffer *buffer, GstMeta **meta, gpointer user_data)            // NvDsInstanceData->NvDsFrameMeta 를 이용한 OSD 처리 
{
  //설정에따라, OSD Label  1st GIE Class 및 Track ID 표시 2nd GIE Class 표시 

}
...
static void
process_buffer (GstBuffer *buf, AppCtx *appCtx, guint index)
{
.....
  // call "for_each_meta" to process metadata.
  gst_buffer_foreach_meta (buf, for_each_meta,
                           &appCtx->pipeline.instance_bins[index]);

}

static GstPadProbeReturn
gie_processing_done_buf_prob (GstPad *pad, GstPadProbeInfo *info,
    gpointer u_data)
{
  GstBuffer *buf = (GstBuffer *) info->data;
  NvDsInstanceBin *bin = (NvDsInstanceBin *) u_data;
  guint index = bin->index;
  AppCtx *appCtx = bin->appCtx;

  if (gst_buffer_is_writable (buf))
    process_buffer (buf, appCtx, index);
  return GST_PAD_PROBE_OK;
}

..........
  if (config->osd_config.enable) {
    NVGSTDS_ELEM_ADD_PROBE (instance_bin->all_bbox_buffer_probe_id,
        instance_bin->osd_bin.nvosd, "sink",
        gie_processing_done_buf_prob, GST_PAD_PROBE_TYPE_BUFFER, instance_bin); //gie_processing_done_buf_prob Call Back 등록 
  } else {
    NVGSTDS_ELEM_ADD_PROBE (instance_bin->all_bbox_buffer_probe_id,
        instance_bin->sink_bin.bin, "sink",
        gie_processing_done_buf_prob, GST_PAD_PROBE_TYPE_BUFFER, instance_bin);   //gie_processing_done_buf_prob Call Back 등록 
  }


2.3  deepstream-app 의 config 파일 (RTSP지원으로변경)

주로 봐야할 Config는 아래의 Config인 것 같으며,  쉽게 설정을 통해서 RTSP변환도 가능하며,이를 통해 IP Camera와 연결가능해지며, 동작화인도 쉽다

  • source4_720p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt 
아래의 Config 파일에서 Gstreamer의 Plugin들을 설정변경하여, RTSP기반으로 동작가능.

$ vi source4_720p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt   //RTSP 설정 변경 

[source0]
..
##jhlee
#uri=file://../../streams/sample_720p.mp4        //기본설정 
uri=rtsp://10.0.0.211:554/h264

##jhlee 4->1  Input Chan
num-sources=1

[sink0]
...
type=2
##jhlee 1->0
sync=0
....

참고사항
  https://devtalk.nvidia.com/default/topic/1046315/deepstream-sdk-on-jetson/template-config-file-for-camera-and-rtsp/


  • Gst-nvinfer 용 Configs 설정
아래와 같이 실행하며, 에러가 발생하며, README를 보면,  Gstreamer의 Plugin의 nvinfer 세부설정이라고 한다. 
현재 상위 4Channel에만 해당 아래의 설정들을 Gst-nvinfer 에게 어떻게 전달하는지는 각 소스를 분석을 해봐야 할 것 같으며, 대체적으로 Callback Function으로 Metadata 처리 부분일 것 같다.

$ deepstream-app -c  samples/configs/deepstream-app/config_infer_primary.txt                                                      // 에러 발생 , 아래의 의 Cache를 제거해도 동일함 
$ deepstream-app -c  samples/configs/deepstream-app/config_infer_secondary_carmake.txt                                    // 에러 발생 
$ deepstream-app -c  samples/configs/deepstream-app/config_infer_secondary_carcolor.txt                                     // 에러 발생  
$ deepstream-app -c  samples/configs/deepstream-app/config_infer_secondary_vehicletypes.txt                               // 에러 발생 

** ERROR: : Failed to set pipeline to PAUSED
Quitting
ERROR from src_bin_muxer: Output width not set
Debug info: /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvmultistream/gstnvstreammux.c(1633): gst_nvstreammux_change_state (): /GstPipeline:pipeline/GstBin:multi_src_bin/GstNvStreamMux:src_bin_muxer
App run failed
   
$ rm ~/.cache/gstreamer-1.0/registry.aarch64.bin  // ERROR 발생한 경우 , 이 파일을 지우고 다시 실행



3. deepstream-testX-app  samples
Deepstream SDK 3.0에서 제공해주는 test-app은 총 4개이며, binary package에서 test app은 총 4개 중 3개만 제공하고 있다.

IP Camera or RTSP Server와  RTSP 테스트 할 경우는 아래의 Gstreamer로 기본동작을 확인 후 실행하자.

Binaray Package 이외에도 직접 Source에 가서 쉽게 Build가 가능하며, 이를 Build하여 손쉽게 소스수정해보면서 테스트도 가능하기에, 가능하면 Source에서 Build하면서 하자.

세부내용은 Deepstream SDK Manual 참조

3.1 deepstream-test1-app 

소스보면  단순하며 쉽게 Gstremer Command로 생성가능하며, 분석도 쉬운예제이기에 생략하며, 실행은 아래처럼 Binary Package를 이용하거나,
직접 Build해서 실행하자.

$ cd ~/deepstream_sdk_on_jetson
$ deepstream-test1-app 
Usage: deepstream-test1-app 

$ deepstream-test1-app samples/streams/sample_720p.h264    // Error 발생  
g_key_file_load_from_file failed
g_key_file_load_from_file failed
Now playing: samples/streams/sample_720p.h264
g_key_file_load_from_file failed
g_key_file_load_from_file failed
Running...
ERROR from element primary-nvinference-engine: Failed to parse config file:dstest1_pgie_config.txt
Error: Failed to parse config file:dstest1_pgie_config.txt
Returned, stopping playback
Deleting pipeline

$ cd sources/apps/sample_apps/deepstream-test1    // PATH 변경 ,
$ deepstream-test1-app ../../../../samples/streams/sample_720p.h264  // 실행확인 문제 없음 (상위 config 파일을 못찾아서 에러) 


처음실행시 상위와 같이 에러가 발생했으며, 원인은 각 config file을 못찾아 발생

3.2 deepstream-test2-app

이 예제의 기본구조는 File을 open 하여 1개의 Primary Gst-nvinfer 걸쳐 Gst-nvtracker를 걸쳐 Secondary Gst-nvinfer 3개를 사용하고, 이를 Gst-nvosd에 적용하는 예제이다.
중간에 OSD적용하기위해서  Video layout도 converting도 진행을 한다 (NV12->RGBA)

개인적으로 분석하기에 가장 좋은 예제인 것 같으며, CMD Gstreamer로도 복잡하게 실행도 가능하기에, 이를 분석하고 비교 테스트 한다.

  • make로 생성된 deepstream-test2-app를 실행 
전체화면으로 작동이되며, 이를 소스상에서도 RTSP지원으로 변경가능하며, 수정방법은 test3이 RTSP지원이므로, 이를 참고하여
uridecodebin 사용하면 ( rtspsrc/h264parse/omxh264dec) 의 PlugIn(Elelemnt)가 필요없어진다.

$ cd ~/deepstream_sdk_on_jetson
$ deepstream-test2-app 
Usage: deepstream-test2-app 


$ cd sources/apps/sample_apps/deepstream-test2
$ deepstream-test2-app ../../../../samples/streams/sample_720p.h264  //  실행확인 문제 없음 (상위 config 파일을 못찾아서 에러) 


  • Deepstream SDK 3.0의 Metadata 
Gstreamer와 Deepstream의 차이라면, 이 Metadata와 TensorRT일 것이며, C/C++를 이용하여 Gstreamer Program을 작성하여 Callback function에서 처리를 해야한다.
  1. NvDsObjectParams : Detect를 한 후 각 Object관련된 MetaData
  2. NvDsEventMsgMeta : Event를 위한 Msg MetaData로 현재 TEST4에서만 사용 


  • 소스 Callback Function 의 Metadata 분석 
중요 Callback Function osd_sink_pad_buffer_probe 이며, 이곳에서 Metadata를 처리하여 OSD에 적용한다.
  1. GstMeta  > NvDsMeta    //   구조체 Type 변경하여, Gstreamer 내부 MetaData이용 
  2. NvDsMeta->meta_data  > NvDsFrameMeta     
  3. NvDsFrameMetaNvDsObjectParams 의 정보이용 하여 기본정보를 OSD 표현 


Metadata 의 흐름 과  Kafka 관련사항
  https://devblogs.nvidia.com/intelligent-video-analytics-deepstream-sdk-3-0/


구조체 확인 (NvDsFrameMetaNvDsObjectParams ) 나머지는생략

$ cat  include/gstnvdsmeta.h  //상위참조

/** Holds parameters that describe meta data for one object. */
typedef struct _NvDsObjectParams {
  /** Structure containing the positional parameters of the object in the frame.
   *  Can also be used to overlay borders / semi-transparent boxes on top of objects
   *  Refer NvOSD_RectParams from nvosd.h
   */
  NvOSD_RectParams rect_params;       // Rectangle 위치 및 Size
  /** Text describing the object can be overlayed using this structure.
   *  @see NvOSD_TextParams from nvosd.h. */
  NvOSD_TextParams text_params;     // OSD 표현될 글자적용  
  /** Index of the object class infered by the primary detector/classifier */
  gint class_id;            // 1st GIE가 Detection 했을 때 Class ( Car , Person)
  /** Unique ID for tracking the object. This -1 indicates the object has not been
   * tracked. Custom elements adding new NvDsObjectParams should set this to
   * -1. */
  gint tracking_id;
  /** Secondary classifiers / custom elements update this structure with
   *  secondary classification labels. Each element will only update the
   *  attr_info structure at index specified by the element's unique id.
   */
  NvDsAttrInfo attr_info[NVDS_MAX_ATTRIBUTES];    // Object 의 2nd GIE의 Class 정보들  
  /** Boolean indicating whether attr_info contains new information. */
  gboolean has_new_info;
  /** Boolean indicating whether secondary classifiers should run inference on the object again. Used internally by components. */
  gboolean force_reinference;
  /** Used internally by components. */
  gint parent_class_id;
  /** Used internally by components. */
  struct _NvDsObjectParams *parent_roi;
  /** Used internally by components */
  NvOSD_LineParams line_params[4];
  /** Used internally by components */
  gint lines_present;
  /** Used internally by components */
  gint obj_status;
  /** Provision to add custom object metadata info */
  NvDsObjectParamsEx obj_params_ex;
} NvDsObjectParams;

typedef struct _NvDsFrameMeta {
  /** Array of NvDsObjectParams structure describing each object. */
  NvDsObjectParams *obj_params;           // Rectangle 개수만큼의 배열로 각 개체정보 
  /** Number of rectangles/objects i.e. length of @ref NvDsObjectParams */
  guint num_rects;              // Rectangle 갯수 
  /** Number of valid strings in @ref NvDsObjectParams. */
  guint num_strings;
  /** Index of the frame in the batched buffer to which this meta belongs to. */
  guint batch_id;
  /** NvOSD mode to be used. @see NvOSD_Mode in `nvosd.h`. */
  NvOSD_Mode nvosd_mode;
  /** 1 = Primary GIE, 2 = Secondary GIE, 3 = Custom Elements */
  gint gie_type;
  /** Batch size of the primary detector. */
  gint gie_batch_size;
  /** Unique ID of the primary detector that attached this metadata. */
  gint gie_unique_id;
  /** Frame number. */
  gint frame_num;                  // 동영상 Frame Number
  /** Index of the stream this params structure belongs to. */
  guint stream_id;
  /** Boolean indicating if these params are no longer valid. */
  gint is_invalid;
  /** Indicates Surface Type i.e. Spot or Aisle */
  NvDsSurfaceType surface_type;
  /** Indicates Surface Index for SurfaceType Spot or Aisle */
  gint camera_id;
  /** Indicates Surface Index for SurfaceType Spot or Aisle */
  gint surface_index;
} NvDsFrameMeta;


  • CMD Gstreamer 실행 및 Deepstream 비교 
상위 테스트 소스를 기반으로 command gstreamer로 변경하여 테스트 진행하며, OSD의 TEXT가 제대로 동작이 안됨 (metadata 처리부분이 동작이 안됨)

$ gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.h264 ! \
        decodebin ! nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        capsfilter caps=video/x-raw(memory:NVMM), format=NV12 !\        
        nvvidconv ! \
        capsfilter caps=video/x-raw(memory:NVMM), format=RGBA !\
        nvosd font-size=15 ! nvoverlaysink

//상위소스를 분석하면, 위와 같이 명령으로 실행이 가능하지만, osd_sink_pad_buffer_probe의 기능을 필요해서 제대로 표현을 못함 
// decodebin (h264parse/omxh264dec 를 호출할 필요 없음)


  • CMD Gstreamer RTSP Version으로 변경 
decodebin 에서 uridecodebin을 이용하여 다양한 uri을 접속가능하도록 변경

$ gst-launch-1.0 uridecodebin uri=rtsp://10.0.0.196:554/h264 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        capsfilter caps=video/x-raw(memory:NVMM), format=NV12 !\        
        nvvidconv ! \
        capsfilter caps=video/x-raw(memory:NVMM), format=RGBA !\
        nvosd font-size=15 ! nvoverlaysink

// RTSP 지원으로 변경하여 테스트 


  • 다른 version으로 테스트 진행 
상위소스를 보면, OSD에 overlay(전체화면)하기 위해서 하지만, OpenGL을 이용하여 X Window 창으로 재생

$ gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.mp4 ! \
        decodebin ! nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvidconv ! nvosd ! nvegltransform ! nveglglessink


3.3 Deepstream TEST3 (RTSP 지원)

RTSP 동작은 잘 동작되며, TEST1과 같이 간단한 구조가  구성되어 생략하지만, 소스참고용은 괜찮은 것 같다.

$ cd ~/deepstream_sdk_on_jetson
$ deepstream-test3-app 
Usage: deepstream-test3-app  [uri2] ... [uriN]

$ cd sources/apps/sample_apps/deepstream-test3
$ deepstream-test3-app ../../../../samples/streams/sample_720p.h264  // 에러 발생, uri를 4개로 늘려도 동일하게 에러발생 
$ deepstream-test3-app rtsp://10.0.0.211:554/h264  // RTSP만 성공 확인  (IP Camera 연결)


3.4 Deepstream TEST 4 (Kafka 예제)

Binary Package에 미포함 되어 있으며, 기존과 다르게,  msgconvmsgbroker를 사용하여 Kafka와 통신하는 구조이다.
Deepstream의 Metadata를 Message(Json)로 변경하여 외부Server로 전송하고 분석하는 구조로 구성이 되고 있음

기존에는 전부 GIE(Gst-nvinfer) config 만 존재했다면 이곳에는 msgconv의 config file도 존재하기 때문에 구조를 잘 살펴보자.


$ cd ~/deepstream_sdk_on_jetson
$ cd sources/apps/sample_apps/deepstream-test4
$ make 
$ ls
deepstream-test4-app  deepstream_test4_app.c  deepstream_test4_app.o  dstest4_msgconv_config.txt  dstest4_pgie_config.txt  Makefile  README

$ ./deepstream-test4-app ../../../../samples/streams/sample_720p.h264  // 에러발생, 


제대로 동작하려면, 소스의 CONNECTION_STRING 설정과 NVDS_META_EVENT_MSG 부분을 잘봐야 겠으며, 상위 설정 dstest4_msgconv_config.txt  의 이해도 필요할 것 같음

현재 이것와 같이 연결될 Server가 존재하지 않아 제대로 동작되지 않는 것 같으며, 이부분은  완벽히 동작될 경우 다시 언급하겠음

msgconv 및 msgbroker 관련내용
  https://devblogs.nvidia.com/intelligent-video-analytics-deepstream-sdk-3-0/

Deepstream 2.0
  https://devblogs.nvidia.com/accelerate-video-analytics-deepstream-2/

4. How To build deepstream Apps

상위 Program은  Binary File을 직접 설치하였기때문에 문제없이 동작했지만,  NVIDIA에서 무료로 제공해주는 Deepstream SDK 3.0 내부의 Source를 직접 빌드를 하여 동작하도록 해보자.

손쉽게 NVIDIA Site에서 무료로 SDK와 Manual을 Download했지만, 라이센스같은 것을 추후에 확인을 해야 할 것 같다.


4.1 빌드시 필요 Package 설치 

Build 전에 아래 Package 설치해야만, Build가 되며, 혹시 빠진 것이 있다면,  dkg -l  명령어로 확인하여 관련필요 Package 설치하자.

$ sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
   libgstrtspserver-1.0-dev libx11-dev


4.2  deepstream-app 빌드 진행 

상위 source/apps/sampe_apps 를 보면 총 5개의 app를 제공하고 있으며, main이 되는 deepstream-app를 먼저 분석
다른 deepstream-testx-app은 구조가 비교적 간단한 편임

  • deepstream-app 
Deepstream의 Main Program이며,  핵심소스
$ cd ~/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-app 
$ make


  • deepstream-app 구조 및 분석 
이 프로그램만 구성이 좀 복잡하지만, config를 이용하여 file 과 rtsp 테스트도 가능하다.
하지만, rtsp의 경우 처음만 동작하고, 제대로 동작되지 않는다.

$ vi ../../apps-common/includes/deepstream_config.h   //
$ tree -t .
.
├── deepstream_app.c               //apps-common 의 file들을 호출구조 (Gstreamer)
├── deepstream_app_main.c      // main X 구성 및 기본 동작 제어 
├── Makefile
├── README
├── deepstream_app.o
├── deepstream_app_main.o
└── deepstream-app

$ tree -t ../../apps-common
../../apps-common/
├── includes
│   ├── deepstream_app.h
│   ├── deepstream_colors.h
│   ├── deepstream_common.h
│   ├── deepstream_config_file_parser.h
│   ├── deepstream_config.h                           // gstream plugin  (app-common *.c 참조 )
│   ├── deepstream_dsexample.h
│   ├── deepstream_gie.h
│   ├── deepstream_metadata_pool.h
│   ├── deepstream_osd.h
│   ├── deepstream_perf.h
│   ├── deepstream_primary_gie.h
│   ├── deepstream_secondary_gie.h
│   ├── deepstream_sinks.h
│   ├── deepstream_sources.h
│   ├── deepstream_streammux.h
│   ├── deepstream_tiled_display.h
│   └── deepstream_tracker.h
└── src
    ├── deepstream_common.c
    ├── deepstream_config_file_parser.c         //deepstream-app 의 config parser 로  각 group 별로 설정 ( deepstream-app -c xxxx.txt )
    ├── deepstream_dsexample.c                   // 현재 미사용 
    ├── deepstream_metadata_pool.c             // Metadat 추후 Kafka를 통해 전송 
    ├── deepstream_osd_bin.c                       // OSD 관련 ( Text 설정)
    ├── deepstream_perf.c                            // FPS 측정 
    ├── deepstream_primary_gie_bin.c           // 1st TensorRT(GIE), Primary GIE와 Secondary GIE의 옵션이 다름  
    ├── deepstream_secondary_gie_bin.c      //  2nd TensorRT 
    ├── deepstream_sink_bin.c                     // Gstreamer 의 output 
    ├── deepstream_source_bin.c                 // Gstreamer 의 Input
    ├── deepstream_streammux.c                 // Video 영상 Mux 기능 
    ├── deepstream_tiled_display_bin.c         // 최종 Display Option 설정 (e.g 2x2 4Ch)
    ├── deepstream_tracker_bin.c                 //  Tracker 관련 기능,  KLT or IOU 알고리즘제공 
    ├── deepstream_primary_gie_bin.o
    ├── deepstream_tracker_bin.o
    ├── deepstream_config_file_parser.o
    ├── deepstream_metadata_pool.o
    ├── deepstream_source_bin.o
    ├── deepstream_common.o
    ├── deepstream_perf.o
    ├── deepstream_sink_bin.o
    ├── deepstream_dsexample.o
    ├── deepstream_osd_bin.o
    ├── deepstream_secondary_gie_bin.o
    ├── deepstream_tiled_display_bin.o
    └── deepstream_streammux.o

$ grep -r   gst_element_factory_make  .                                 // Gstreamer Plugin 설정함수 검색하여 구조파악
$ grep -r   gst_element_factory_make   ../../apps-common     // Gstreamer Plugin 설정함수 검색 하여 구조파악 


apps-common 파일에서 돌아가는 시스템의 전체적인 구조를 파악하자.
deepstream-app은 두 개의 config를 제공 (30Ch, 4Ch)에서 streammux기능을 사용하며, 여기서 Batch Size의 의미와 정확한 설정방법을 알아두고
이를 display하는 tiled_dispaly의 기능을 확인하자.





  • 다른 deepstream-testx-app 프로그램 
구성이 간단하며, 쉽게 빌드가 가능하며, gst-infer 설정도 별도로 존재하며, 이해하기가 쉽다.

$ cd ~/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-test1
$ make

$ cd ~/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-test2  // nvinfer의 구성이 기본프로그램과 거의 유사
$ make

$ cd ~/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-test3  //RTSP지원인데, 구성이 독특함
$ make

$ cd ~/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-test4  // Build 에러발생 
$ make


5. Jetson AGX Xavier 기반의 일반 Gstreamer 예제

IP Camera 와 아래와 같이 실행을 해보면 잘동작되는 것을 알수 있다. 세부 메뉴얼은 Gstreamer 관련메뉴얼을 읽자.


$ vi gstreamFake.sh   // Fakesink 
export GST_DEBUG=fpsdisplaysink:5
export RTSP_PATH=rtsp://10.0.0.211:554/h264
gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! video/x-raw ! fpsdisplaysink video-sink=fakesink

$ vi gstream1Ch.sh   // 1Channel Gstream , Fixed Size (not Full Screen)
export GST_DEBUG=fpsdisplaysink:5
export RTSP_PATH=rtsp://10.0.0.211:554/h264
gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! omxh264dec ! nveglglessink window-x=100 window-y=100 window-width=640 window-height=360 

$ vi gstream1Ch.sh   // 1Channel Gstream , Input Size Screen 
export GST_DEBUG=fpsdisplaysink:5
export RTSP_PATH=rtsp://10.0.0.211:554/h264
gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! omxh264dec ! nveglglessink -e

$ vi gstream1Ch.sh   // 1Channel Gstream  File Save 
export GST_DEBUG=fpsdisplaysink:5
export RTSP_PATH=rtsp://10.0.0.211:554/h264
gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! video/x-h264,stream-format=byte-stream ! filesink location=dump.h264

$ vi gstream4.sh     //4 Channel Gstream 
export GST_DEBUG=fpsdisplaysink:5
export RTSP_PATH=rtsp://10.0.0.211:554/h264
gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! omxh264dec ! nveglglessink window-x=100 window-y=100 window-width=640 window-height=360 & gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! omxh264dec ! nveglglessink window-x=800 window-y=100 window-width=640 window-height=360 & gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! omxh264dec ! nveglglessink window-x=100 window-y=500 window-width=640 window-height=360  & gst-launch-1.0 rtspsrc location="$RTSP_PATH" ! rtph264depay ! h264parse ! omxh264dec ! nveglglessink window-x=800 window-y=500 window-width=640 window-height=360


  https://devtalk.nvidia.com/default/topic/1043622/jetson-agx-xavier/problems-with-gstreamer-video-decoding-pipeline/
  https://developer.download.nvidia.com/embedded/L4T/r32_Release_v1.0/Docs/Accelerated_GStreamer_User_Guide.pdf?dv2A0QketFFyriluW9VlC-MWvKz47EdjjzfAk-IbvlxfI0h-gzfdPigIlLBki-7obko6HNlF2ffVOvIEypa0Nm446gahCIzqSWD29sNvZ82qQuAkdttYwAAjAkTESp9Rgn6maGtlhsKPIbT0UPC-duLydchWKUbyer3cEWv8ZoL1svospLA


6.  Jetson AGX  Xavier 기반의 TensoRT  관련사항 

AGX Xavier 의 Object Detection 과  Lane Segmatation의 예제인데, TensorRTDALI를 사용하여 최적화한다고 한다.

AGX 기반의 TensorRT 부분
  https://devblogs.nvidia.com/drive-agx-accelerators-object-detection/


7. Yolo 관련 테스트 

EVM-Jetson TX2와 Jetson AGX Xavier에서 각각 Yolo를 Porting하여 돌려 테스트한 사이트

  https://jkjung-avt.github.io/yolov3/
  https://goodtogreate.tistory.com/entry/YOLOv3-on-Jetson-AGX-Xavier-%EC%84%B1%EB%8A%A5-%ED%8F%89%EA%B0%80?category=701595