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

8/02/2019

Deepstream SDK 4.0 변화 및 PlugIn 구조 및 생성방법 ( Gstreamer 변화 )

1. DeepStream SDK 4.0 변화 (Gstreamer 변화) 

기존 DeepStream SDK 3.0과 호환되지 않는 부분이 많으며, 우선 빨리 파악하기 위해서 PlugIn Manual 과 소스를 분석하여 어떻게 변경되었는지 알아야겠다.

기존의 DeepStream SDK 3.0에서 동작되었던 , Gstreamer 명령어들이 동작되지 않는 것들이 많다.

  • DeepStream 관련전체문서 (필독)
  https://docs.nvidia.com/metropolis/index.html


상위 전체문서 중에 많이 보게될 문서는 아래 3 문서가 될 것 같다.

  • DeepStream Release Note 
이전버전과 변경사항 및 x86과 Jetson의 차이와 신기능들을 확인하자
  https://docs.nvidia.com/metropolis/deepstream/4.0/DeepStream_4.0_Release_Notes.pdf


  • DeepStream Quick Guide 기본사용법
설치는 sdkmanger로 쉽게 하면될 것이고, 개발 및 관련 설명을 쉽게 정리해서 보기 편하다
  https://docs.nvidia.com/metropolis/deepstream/4.0/dev-guide/index.html


  • DeepStream 개발시 PlugIn Manual 과 DeepStream API
DeepStream 관련부분을 개발할 경우, PlugIn의 정보와 기능을 비롯하여 내부에서 사용하는 API들을 알아야하는데 관련문서들이므로, 필수로 보자
  https://docs.nvidia.com/metropolis/deepstream/4.0/DeepStream_Plugin_Manual.pdf
  https://docs.nvidia.com/metropolis/deepstream/4.0/dev-guide/DeepStream_Development_Guide/baggage/index.html


1.1 Jetson AGX Xavier 의 INT8 특징 

다른 Jetson과 다른게 DLA라는 것이 존재하며, 이는 INT8 Inference기능을 제공을 하고 있다.
이외에도 OpenVX 기능도 존재하지만, 이부분이 OpenCV에도 적용이 되는지는 좀 더 알아봐야할 것 같다.
DeepStream 4.0부터 지원되는 기능은 아니며, 기존부터 존재했다고 하지만, Xavier를 처음 사용하기에 이 를 간단히 정리하며, Jetson Nano , TX2는 이 부분에서 제외

  • INT8 Inferece 관련문서 (Jetson AGX Xavier 지원)
  http://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf

INT8기능이 지원이 되려면 아래와 같이 GPU의 SM 61 Version 이상이어야 하며, 아래와 같은 연산이 지원되어야 가능하다

  • SM61 관련내용 
  https://devtalk.nvidia.com/default/topic/1026069/jetson-tx2/how-to-use-int8-inference-with-jetsontx2-tensorrt-2-1-2/


INT8 Inferece의 목적은 FP32/FP16에 비해 정확성 손실이 크게 없이 빠른계산을 위해 INT8로 변경하여 속도향상이 목적이다

  • Bias의 필요성 ( 절대값이 아닌 상대값으로 보면, 필요가 없어질것으로 추측 )
하지만 아래와 같이 2개의 곱에서 전체의 Bias가 필요가 없어지는데, 이 부분이 좀 혼동이 된다
이 부분은 좀 알아봐야 할 것 같다.


아래의 FP32 Bias가 불필요해서 제거한다고 함



  • 양자화(Quantization, 비율로 INT8에 맞게 양자화 진행 ) 



아래와 같이 양자화할 경우 Threshold를 설정하여 Saturation 을 조절


  • INT8 Inference의 정확성 비교 


상위 INT8의 문서를 간단히 정리하면, Weight는 그대로 두고, Bias를  제거후 일종의 Hash Table 같은 것을 만들어서
FP32를  INT8로 Table를 통해 Mapping하는 방식으로 구현한다 (양자화)
Bias의 불필요성은 값을 절대값이 아닌 상대값으로 보기 때문에 필요가 없어지는 것 같으며, 상위문서를 잘 봐도 크게 데이타 손실은 없을 것 같다.(추측)

재미있는 부분은 양자화할때의 정확성부분이며, 이때 Threshold를 설정하여 Saturation 을 조절도 가능하다는 점이다.
그리고,  불필요하다면, Threshold를 설정하여, 잘라 내어 제거한다
이 부분의 필요성이 언제 필요한지는 추후에 알아봐야할 것 같다


양자화(Quantization) 할때 Mapping시 Hash Table 사용했는지는 모르지만, 예전에 내가 비슷한 것을 구현했던 경험이 있어,
Hash Table을 이용했기때문에, 나라면 Hash Table을 이용했을 것 같다.

INT8의 Inference의 기능도 꽤 재미있는 기능이며, 이 부분에 관심이 많아졌다.
다만 상위문서를 설명을 듣고 싶은데 문서로만 봐서 안타까울 뿐이다.

  • Config File의 IN8 Inference 확인사항 
  1. model-engine-file : TensorRT model-engine (serialized 된 상태의 INT8)
  2. int8-calib-file : CalibrationTable File 이며 각 TensorRT의 Version 정보표시
  3. network-mode :  0=FP32, 1=INT8, 2=FP16 mode , 처음  model-engine이 없을 경우 이 기준으로 생성 

  • Config File의 Example for Jetson AGX Xavier 
  1. model-engine-file=model_b1_int8.engine
  2. int8-calib-file=yolov3-calibration.table.trt5.1
  3. int8-calib-file=../../models/Primary_Detector/cal_trt4.bin


1.2 DeepStream SDK 3.0 과 4.0 비교 

3.0에서 4.0으로 변경되면서 많은 기능이 추가되었지만 호환되지 않는 부분이 많이 생겨, 관련부분을 정리가 필요할 것 같다.
기존 DS3.0에서 이것저것 만들어보고 Porting해보고 했는데, DS4.0에서 많이 지원되는 것 같은데, 관련부분도 다 테스트를 해야한다.

NVIDIA의 문서를 보면 가장 큰 변화사항은 Jetson 과 dGPU Platform 기반의 단일화된 변화라고 하는데, 간단히 정리하면, 최적화를 통한 성능향상이 될 것 같다.
세부사항은 역시 PlugIn Manual로 다 봐야 알겠다.

더불어 이제 x86만 지원가능했던 NGC Docker도 ARM에서도 지원을 해주기 때문에 설치환경이 편하게 될 것 같다.

  • Gst-nvinfer 변화정리  
  1. UFF/ONNX/Caffe 이외의 Custom Model 위한 New Interface제공 (TensorRT IPlugin)
  2. Segmentation/Gray model 지원 
  3. FP16 / INT8 DLA (Jetson Xavier) 지원 (기존 INT8만 지원)
  4. Source Code 제공 (이 부분은 나중에 분석)

  • New PlugIns
  1. Gst-V4L2 기반의 H265+H264 encode 와 decode 지원 ( 기존과 변경됨)
  2. JPEG+MJPEG decoder 지원
  3. gst-nvvideoconver (기존 gst-nvconv 확장)
  4. gst-nvof  ( Optical flow )
  5. nvofvisual / nvsegvisul 지원을 해준다고 하는데, 설정으로 테스트 진행을 해봐야겠다.
  6. dewarper 도 제공해주며, gst-msgbroker도 많이 확장되었다. 
  7. 이외 기존 Plugin들의 이름이 호환되지 않는다. 

자세한 내용 아래의 Release Note를 참고해서 보자
  https://docs.nvidia.com/metropolis/deepstream/4.0/DeepStream_4.0_Release_Notes.pdf


1.3  DeepStream 4.0의 PlugIn 관련사항 


DS4.0 PlugIn Manual
  https://docs.nvidia.com/metropolis/deepstream/4.0/DeepStream_Plugin_Manual.pdf


기존처럼 gst-inspect를 이용하여 PlugIn 기능확인을 할 수 없기 때문에 오직 상위 Manual로 세부사항을 알아야겠다.

  • gst-inspect 명령어로 Element 기능확인 
Terminal에서 확인이 잘되지만, SSH로 연결시 문제가 발생하는 부분이 gst-inspect 부분이다.

$ ssh  nvidia@192.168.55.1  
$ echo $DISPLAY  // 설정이 없음 

$ gst-inspect-1.0 -a   // 모든 PlugIn 확인가능    
.......
$ gst-inspect-1.0 -a |  grep dsexample     
.....
$ gst-inspect-1.0 dsexample    
Factory Details:
  Rank                     primary (256)
  Long-name                DsExample plugin
  Klass                    DsExample Plugin
......
GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBaseTransform
                         +----GstDsExample


$ ssh -X  nvidia@192.168.55.1         // X Protocol 지원 

$ echo $DISPLAY   // 상위와 다르게 설정되었으며, 이로 인해 오작동됨  
localhost:10.0

$ export DISPLAY=:1   // 1 or 0 설정  반드시 =:를 사용  

$ gst-inspect-1.0 dsexample    
Factory Details:
  Rank                     primary (256)
  Long-name                DsExample plugin
  Klass                    DsExample Plugin
......
GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBaseTransform
                         +----GstDsExample

Gstreamer gst-inspect
  https://gstreamer.freedesktop.org/documentation/tools/gst-inspect.html?gi-language=c#


  • SSH에서 gst-inspect 사용시 주의 사항 
만약  SSH X Protocl 과 같이 접속시 상위의 DISPLAY를 미설정시에는 상위 Command 미동작

미동작원인을 몰랐는데, NVIDIA에서 정확히 알려줘서 해결
  https://devtalk.nvidia.com/default/topic/1058525/deepstream-sdk/gst-inspect-is-not-work-properly-in-ds4-0/post/5368380/#5368380

Ubuntu DISPLAY 관련설정
  https://help.ubuntu.com/community/EnvironmentVariables

  • 만약 문제생길 경우 아래와 같이 Cache 삭제 
$ rm ~/.cache/gstreamer-1.0/registry.aarch64.bin   //문제가 생기면, 아래와 같이 Gstreamer Cache를 지우고 다시 해보자. 
......



1.4 DeepStream PlugIn 구조 및 위치확인 

이전 DS SDK 3.0과 동일하며, 아래의 소스에서 Sample PlugIn을 선택해서 이름을 변경해서 Sample을 만들고 테스트를 진행하자.



  • DeepStream Gst-PlugIn 예제 구성 
아래와 같이 Gstreamer 의 PlugIN 구조를 파악을 하고 예제로 주어진 dsexample을 이름을 변경하여 만들어서 간단히 테스트를 진행하면된다.

$ cd ~/deepstream-4.0/sources/gst-plugins
$ tree .
.
├── gst-dsexample   // 이것 기준으로 동일하게 이름을 변경해서 테스트 진행 
│   ├── dsexample_lib
│   │   ├── dsexample_lib.c
│   │   ├── dsexample_lib.h
│   │   ├── dsexample_lib.o
│   │   ├── libdsexample.a
│   │   └── Makefile
│   ├── gstdsexample.cpp
│   ├── gstdsexample.h
│   ├── gstdsexample.o
│   ├── libnvdsgst_dsexample.so
│   ├── Makefile
│   └── README
├── gst-nvinfer                 // 새로 추가된 nvinfer 
│   ├── gstnvinfer_allocator.cpp
│   ├── gstnvinfer_allocator.h
│   ├── gstnvinfer_allocator.o
│   ├── gstnvinfer.cpp
│   ├── gstnvinfer.h
│   ├── gstnvinfer_meta_utils.cpp
│   ├── gstnvinfer_meta_utils.h
│   ├── gstnvinfer_meta_utils.o
│   ├── gstnvinfer.o
│   ├── gstnvinfer_property_parser.cpp
│   ├── gstnvinfer_property_parser.h
│   ├── gstnvinfer_property_parser.o
│   ├── libnvdsgst_infer.so
│   ├── Makefile
│   └── README
├── gst-nvmsgbroker
│   ├── gstnvmsgbroker.c
│   ├── gstnvmsgbroker.h
│   ├── gstnvmsgbroker.o
│   ├── libnvdsgst_msgbroker.so
│   ├── Makefile
│   └── README
└─── gst-nvmsgconv
      ├── gstnvmsgconv.c
      ├── gstnvmsgconv.h
      ├── gstnvmsgconv.o
      ├── libnvdsgst_msgconv.so
      ├── Makefile
      └── README


  • Gst PlugIn 및 DeepStream PlugIn 위치파악 
DeepStream Plugin 위치 및 Gstreamer PlugIn 위치를 알아보기 위해 아래와 같이 찾아보았다.

$ ls /opt/nvidia/deepstream/deepstream-4.0/lib/gst-plugins/    //DeepStream PlugIn만 설치위치확인  
libnvdsgst_dewarper.so   libnvdsgst_msgbroker.so    libnvdsgst_multistreamtiler.so  libnvdsgst_osd.so        libnvdsgst_tracker.so
libnvdsgst_dsexample.so  libnvdsgst_msgconv.so      libnvdsgst_of.so          libnvdsgst_infer.so      libnvdsgst_multistream.so  libnvdsgst_ofvisual.so       
libnvdsgst_segvisual.so

$ cat /etc/ld.so.conf.d/deepstream.conf              //DeepStream 동적 Library 연결확인 
/opt/nvidia/deepstream/deepstream-4.0/lib

$ echo $PATH   // PATH는 아시다시피, BIN파일을 어느위치에서 실행가능한 환경변수 
/usr/local/cuda-10.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

$ echo $LD_LIBRARY_PATH   // LD의 동적 LIBRARY_PATH로 상위 ld.so.conf 설정도 참조 
/usr/local/cuda-10.0/lib64:

/*
상위 Gstreamer 환경변수 참조하여 관련설정 전부확인했으나 파악실패 
*/
 
$ echo $GST_PLUGIN_PATH  // 설정없음   ,
$ echo $GST_PLUGIN_PATH_1_0 //설정없음 
$ echo $GST_PLUGIN_SYSTEM_PATH  // 설정없음 
$ echo $GST_PLUGIN_SYSTEM_PATH_1_0  // 설정없음
$ ls ~/.local/share/gstreamer-1.0/presets/    // 아무것도 없음 

/*
 Gstreamer PlugIn을 위치를 직접 찾겠다. 
*/

$ find / -name gstreamer-1.0 2> /dev/null    // 관련 Directory 파악완료 
/usr/share/gstreamer-1.0
/usr/include/gstreamer-1.0
/usr/lib/aarch64-linux-gnu/gstreamer1.0/gstreamer-1.0
/usr/lib/aarch64-linux-gnu/gstreamer-1.0
/home/nvidia/.cache/gstreamer-1.0
/home/nvidia/.local/share/gstreamer-1.0

$ cat /home/nvidia/.cache/gstreamer-1.0/registry.aarch64.bin   // 이 안에 파일을 분석하면, directory 구조 파악가능 

$ ls /usr/lib/aarch64-linux-gnu/gstreamer-1.0  // 다른 Gstreamer PlugIn 부분과 DeepStream Plugin 연결 확인완료 (DeepStream로 심볼링크됨)
deepstream                 libgstcurl.so                libgstisomp4.so            libgstomx.so              libgsttaglib.so
include                    libgstcutter.so              libgstivfparse.so          libgstopenal.so           libgsttcp.so
libcluttergst3.so          libgstdashdemux.so           libgstivtc.so              libgstopenexr.so          libgstteletext.so
libgst1394.so              libgstdc1394.so              libgstjack.so              libgstopenglmixers.so     libgsttheora.so
..............


1.5 DeepStream의 PlugIn 개발

상위와 같이 기본동작구성을 알았으니, 기본으로 Gstreamer PlugIn 관련 개발 Manual을 숙지해두고 알아두자

  • Gstreamer PlugIn 개발 (필독)
  https://gstreamer.freedesktop.org/documentation/plugin-development/basics/boiler.html?gi-language=c

  • Gstreamer PlugIn 개발시 Pad 부분 (필독)
  https://gstreamer.freedesktop.org/documentation/plugin-development/basics/pads.html?gi-language=c

  • Gstreamer 의 Properites 설정 (필독)
  https://gstreamer.freedesktop.org/documentation/plugin-development/basics/args.html?gi-language=c

  • 이외 Callback 함수들 연결 
  1. Chain function: chain 함수를 만들어서 Callback 으로 호출하는데, 내부 Data 처리할때 사용
  2. Event Function:  Pad에게 Callback Function 넣고 State에 따라 pad에게 event 생성가능 
  3. Query Function: Query를 받았을 때 Callback 

  • Gstreamer Write Guide
PlugIn 구조를 세부적으로 알기위해서 아래의 Write Guide를 좀 자세히 보자
  https://gstreamer.freedesktop.org/documentation/plugin-development/index.html?gi-language=c


  • SAMPLE의 Gstreamer 구성의 예 
Gstreamer PlugIn의 함수는SAMPLE이라는 이름으로 생성하고자 한다면 아래와 같이 만들면 된다.
함수이름 역시 gst_sample_xxx으로 구성을 하면된다.

 vi sample.h 
G_BEGIN_DECLS
....
#define GST_TYPE_SAMPLE (gst_sample_get_type())
#define GST_SAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ROI,GstSAMPLE))
#define GST_SAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ROI,GstSAMPLEClass))
#define GST_SAMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_SAMPLE, GstSAMPLEClass))
#define GST_IS_SAMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SAMPLE))
#define GST_IS_SAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SAMPLE))
#define GST_SAMPLE_CAST(obj)  ((GstSAMPLE *)(obj))

..
G_END_DECLS

  • dsexample로  본인이 원하는 PlugIn 생성 
dsexmple을 복사하여 이름만 변경해서 그 구성을 만들어서 일단 테스트를 진행을 해보면 쉽게 동작되는 것을 확인가능하다.
설치가 되면, gst-inspect 로도 쉽게 관련설명을 확인 할수 있다.
자세한 세부설명은 생략 (Gstreamer Manual 참조)

  • dsexample 과 nvmsgbroker 비교분석  
두개의 PlugIn의 구성 동작방식이 다르며, 이는 아래와 같이 간단히 비교가능하다.
gst_xxxxx_class_init 함수에서 사용되는 구조체와 이와 관련된 함수들을 비교 분석할 필요가 있다.

//msgbroker 
//GstBaseSinkClass  , Sink Pad의 중점으로 동작되도록 구성

  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS (klass);
.....
  base_sink_class->set_caps = GST_DEBUG_FUNCPTR (gst_nvmsgbroker_set_caps);
  base_sink_class->start = GST_DEBUG_FUNCPTR (gst_nvmsgbroker_start);
  base_sink_class->stop = GST_DEBUG_FUNCPTR (gst_nvmsgbroker_stop);
  base_sink_class->render = GST_DEBUG_FUNCPTR (gst_nvmsgbroker_render);

// dsexmple 
//GstBaseTransformClass  , PlugIn 내부에서 Data 변경중심으로 동작 (이때 Data를 어떻게 trasform 시키는지 확인) 

  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseTransformClass *gstbasetransform_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasetransform_class = (GstBaseTransformClass *) klass;

  /* Overide base class functions */
  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_dsexample_set_property);
  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_dsexample_get_property);

  gstbasetransform_class->set_caps = GST_DEBUG_FUNCPTR (gst_dsexample_set_caps);
  gstbasetransform_class->start = GST_DEBUG_FUNCPTR (gst_dsexample_start);
  gstbasetransform_class->stop = GST_DEBUG_FUNCPTR (gst_dsexample_stop);

상위와 같이 각각의 Class에 Callback Function을 넣고 동작을 하는데, 언제 호출이되는지를 파악하자.

  • GstBaseSink 와 GstBaseTransform 관련구조 파악 
둘 다 구조를 보면 GstElement 가 부모 Class 이므로 GstElement 하위 클래스 특징을 알아두자
각각의 method들을 파악하자
  https://gstreamer.freedesktop.org/documentation/base/gstbasetransform.html?gi-language=c#GstBaseTransform
  https://gstreamer.freedesktop.org/documentation/base/gstbasesink.html?gi-language=c#GstBaseSink

  • DeepStream Program 과 PlugIn을 작성중에 NVIDIA에게 직접질문사항 
dsexample의 properties 중 full-frame의 설정에따라 openCV 와 crop기능이 동작이 되는데, 이 부분을 내 소스에 적용하여 동작되는 것은 확인했다.
이를 정확하게 이해하고자 하면,  반드시 DeepStream SDK API 문서를 보고 각각의 동작을 이해해야한다.
  https://devtalk.nvidia.com/default/topic/1061422/deepstream-sdk/how-to-crop-the-image-and-save/

ROI를 PlugIn을 이용하여 이미 개발을 했는데, Line으로 가능하다고하는데 추후 테스트진행
  https://devtalk.nvidia.com/default/topic/1061791/deepstream-sdk/about-roi-in-ds4-0-on-xavier-/post/5378191/#5378191


1.6  각 모델의 성능비교 (TensorRT)

이전에 TensorRT를 하면서 trtexec 제대로 사용할 줄을 몰랐는데, 이제 사용법을 제대로 알겠다.
이 Tool은 UFF/Caffe/ONNX Model, TensorRT Engine의 성능측정을 위해서 사용되어진다고 한다.

//각 모델의 성능을 측정을 해보기 위해서 trtexec 사용을 해보자 
$ /usr/src/tensorrt/bin/trtexec --help
&&&& RUNNING TensorRT.trtexec # /usr/src/tensorrt/bin/trtexec --help
[I] help

Mandatory params:
  --deploy=          Caffe deploy file
  OR --uff=          UFF file
  OR --onnx=         ONNX Model file
  OR --loadEngine=   Load a saved engine

Mandatory params for UFF:
  --uffInput=,C,H,W Input blob name and its dimensions for UFF parser (can be specified multiple times)
  --output=      Output blob name (can be specified multiple times)

Mandatory params for Caffe:
  --output=      Output blob name (can be specified multiple times)

Optional params:
  --model=          Caffe model file (default = no model, random weights used)
  --batch=N               Set batch size (default = 1)
  --device=N              Set cuda device to N (default = 0)
  --iterations=N          Run N iterations (default = 10)
  --avgRuns=N             Set avgRuns to N - perf is measured as an average of avgRuns (default=10)
  --percentile=P          For each iteration, report the percentile time at P percentage (0<=P<=100, with 0 representing min, and 100 representing max; default = 99.0%)
  --workspace=N           Set workspace size in megabytes (default = 16)
  --safe                  Only test the functionality available in safety restricted flows.
  --fp16                  Run in fp16 mode (default = false). Permits 16-bit kernels
  --int8                  Run in int8 mode (default = false). Currently no support for ONNX model.
  --verbose               Use verbose logging (default = false)
  --saveEngine=     Save a serialized engine to file.
  --loadEngine=     Load a serialized engine from file.
  --calib=          Read INT8 calibration cache file.  Currently no support for ONNX model.
  --useDLACore=N          Specify a DLA engine for layers that support DLA. Value can range from 0 to n-1, where n is the number of DLA engines on the platform.
  --allowGPUFallback      If --useDLACore flag is present and if a layer can't run on DLA, then run on GPU. 
  --useSpinWait           Actively wait for work completion. This option may decrease multi-process synchronization time at the cost of additional CPU usage. (default = false)
  --dumpOutput            Dump outputs at end of test. 
  -h, --help              Print usage

//trtexec의 정보를 얻기위해서 각 config 파일 파악 
$ cd ~/deepstream-4.0/sources/apps/sample_apps/deepstream-test2
$ cat dstest2_pgie_config.txt

# Following properties are mandatory when engine files are not specified:
#   int8-calib-file(Only in INT8)
#   Caffemodel mandatory properties: model-file, proto-file, output-blob-names            // Caffe Model 은 3가지 정보가 필수 , model-file / proto-file , out-blob-names
#   UFF: uff-file, input-dims, uff-input-blob-name, output-blob-names                            // UFF , uff-file, input-dims, uff-input-blob-name, output-blob-names 
#   ONNX: onnx-file                                                                                                 //  ONNX: onnx-file 

model-file=../../../../samples/models/Primary_Detector/resnet10.caffemodel
proto-file=../../../../samples/models/Primary_Detector/resnet10.prototxt
...
output-blob-names=conv2d_bbox;conv2d_cov/Sigmoid

//TensorRT Engine 
$ /usr/src/tensorrt/bin/trtexec   --loadEngine=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel_b4_int8.engine 
&&&& RUNNING TensorRT.trtexec # /usr/src/tensorrt/bin/trtexec --loadEngine=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel_b4_int8.engine
[I] loadEngine: /home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel_b4_int8.engine
[I] /home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel_b4_int8.engine has been successfully loaded.
[I] Average over 10 runs is 1.01944 ms (host walltime is 1.10421 ms, 99% percentile time is 1.06387).
[I] Average over 10 runs is 1.00943 ms (host walltime is 1.06669 ms, 99% percentile time is 1.02454).
[I] Average over 10 runs is 1.00519 ms (host walltime is 1.06144 ms, 99% percentile time is 1.01184).
[I] Average over 10 runs is 1.00898 ms (host walltime is 1.07056 ms, 99% percentile time is 1.02982).
[I] Average over 10 runs is 1.00417 ms (host walltime is 1.06018 ms, 99% percentile time is 1.02707).
[I] Average over 10 runs is 1.00541 ms (host walltime is 1.06557 ms, 99% percentile time is 1.02682).
[I] Average over 10 runs is 1.00323 ms (host walltime is 1.0602 ms, 99% percentile time is 1.03834).
[I] Average over 10 runs is 1.00476 ms (host walltime is 1.06061 ms, 99% percentile time is 1.02954).
[I] Average over 10 runs is 1.00358 ms (host walltime is 1.05957 ms, 99% percentile time is 1.00902).
[I] Average over 10 runs is 1.00232 ms (host walltime is 1.05585 ms, 99% percentile time is 1.00704).

//Caffe Model 과 TensorRT 상위비교가능 (소요시간은 알겠지만, percentile time 은 무슨의미인지 퍼센트?)
$ /usr/src/tensorrt/bin/trtexec --deploy=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.prototxt \
  --model=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel \
  --output=conv2d_bbox

&&&& RUNNING TensorRT.trtexec # /usr/src/tensorrt/bin/trtexec --deploy=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.prototxt --model=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel --output=conv2d_bbox
[I] deploy: /home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.prototxt
[I] model: /home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel
[I] output: conv2d_bbox
[I] Input "input_1": 3x368x640
[I] Output "conv2d_bbox": 16x23x40
[I] Average over 10 runs is 4.64663 ms (host walltime is 4.72585 ms, 99% percentile time is 4.7319).
[I] Average over 10 runs is 4.62393 ms (host walltime is 4.69601 ms, 99% percentile time is 4.64422).
[I] Average over 10 runs is 4.6295 ms (host walltime is 4.69154 ms, 99% percentile time is 4.64858).
[I] Average over 10 runs is 4.62978 ms (host walltime is 4.68834 ms, 99% percentile time is 4.64538).
[I] Average over 10 runs is 4.62103 ms (host walltime is 4.68236 ms, 99% percentile time is 4.63843).
[I] Average over 10 runs is 4.62193 ms (host walltime is 4.68143 ms, 99% percentile time is 4.64042).
[I] Average over 10 runs is 4.61595 ms (host walltime is 4.67465 ms, 99% percentile time is 4.62768).
[I] Average over 10 runs is 4.61807 ms (host walltime is 4.67505 ms, 99% percentile time is 4.63514).
[I] Average over 10 runs is 4.61827 ms (host walltime is 4.68276 ms, 99% percentile time is 4.62362).
[I] Average over 10 runs is 4.62702 ms (host walltime is 4.69345 ms, 99% percentile time is 4.64864).
&&&& PASSED TensorRT.trtexec # /usr/src/tensorrt/bin/trtexec --deploy=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.prototxt --model=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel --output=conv2d_bbox

$ /usr/src/tensorrt/bin/trtexec --deploy=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.prototxt \
  --model=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel \
  --output=conv2d_cov/Sigmoid
&&&& RUNNING TensorRT.trtexec # /usr/src/tensorrt/bin/trtexec --deploy=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.prototxt --model=/home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel --output=conv2d_cov/Sigmoid
[I] deploy: /home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.prototxt
[I] model: /home/nvidia/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel
[I] output: conv2d_cov/Sigmoid
[I] Input "input_1": 3x368x640
[I] Output "conv2d_cov/Sigmoid": 4x23x40
[I] Average over 10 runs is 4.6327 ms (host walltime is 4.70868 ms, 99% percentile time is 4.6904).
[I] Average over 10 runs is 4.62576 ms (host walltime is 4.69326 ms, 99% percentile time is 4.66947).
[I] Average over 10 runs is 4.62769 ms (host walltime is 4.68794 ms, 99% percentile time is 4.65818).
[I] Average over 10 runs is 4.62516 ms (host walltime is 4.69319 ms, 99% percentile time is 4.66173).
[I] Average over 10 runs is 4.62184 ms (host walltime is 4.68396 ms, 99% percentile time is 4.64534).
[I] Average over 10 runs is 4.62518 ms (host walltime is 4.67966 ms, 99% percentile time is 4.64067).
[I] Average over 10 runs is 4.62082 ms (host walltime is 4.68281 ms, 99% percentile time is 4.64358).
[I] Average over 10 runs is 4.62256 ms (host walltime is 4.68476 ms, 99% percentile time is 4.65318).
[I] Average over 10 runs is 4.62129 ms (host walltime is 4.68117 ms, 99% percentile time is 4.64125).
[I] Average over 10 runs is 4.62561 ms (host walltime is 4.6864 ms, 99% percentile time is 4.64435).

//UFF Model 
$ cd ~/deepstream-4.0/sources/objectDetector_SSD
$ cat config_infer_primary_ssd.txt
.......
uff-file=sample_ssd_relu6.uff
uff-input-dims=3;300;300;0
uff-input-blob-name=Input
...
output-blob-names=MarkOutput_0
parse-bbox-func-name=NvDsInferParseCustomSSD
custom-lib-path=nvdsinfer_custom_impl_ssd/libnvdsinfer_custom_impl_ssd.so

//UFF 모델은 Custom Layer를 사용해서 동작이 제대로 안될 것 같다 ( uffinput 부분도 상위 값과 어떤의미를 정확하게 알아야하는데, 모름)
$ /usr/src/tensorrt/bin/trtexec --uff=/home/nvidia/deepstream-4.0/sources/objectDetector_SSD/sample_ssd_relu6.uff \
  --uffInput=Input,3,300,300 \
  --output=MarkOutput_0
[I] uff: /home/nvidia/deepstream-4.0/sources/objectDetector_SSD/sample_ssd_relu6.uff
[I] uffInput: Input,3,300,300
[I] output: MarkOutput_0
[E] [TRT] UffParser: Validator error: concat_box_loc: Unsupported operation _FlattenConcat_TRT
[E] Engine could not be created
[E] Engine could not be created
&&&& FAILED TensorRT.trtexec # /usr/src/tensorrt/bin/trtexec --uff=/home/nvidia/deepstream-4.0/sources/objectDetector_SSD/sample_ssd_relu6.uff --uffInput=Input,3,300,300 --output=MarkOutput_0


Best Practices For TensorRT Performance (trtexec 및 다른 Tool)
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-best-practices/index.html

Caffe Model trtexec 실제사용
  https://devtalk.nvidia.com/default/topic/1061845/deepstream-sdk/resnet50-classification-as-primary-gie/

Model Parser Error 사항
  https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#error-messaging

yais Tool 은 추후에 사용해보자
  https://github.com/NVIDIA/tensorrt-laboratory/tree/master/examples/00_TensorRT



2. DeepStream 의 Gstream 테스트 

DeepStream SDK 3.0 및 Gstreamer 관련정리
  https://ahyuo79.blogspot.com/2019/07/deepstream-sdk-30-gstreamer.html


2.1 Gstreamer Debugging 방법 

GST_DEBUG 의 환경변수를 이용하며, 이곳에 원하는 값을 넣고 설정하면 관련 Debug Message 볼수가 있다.
1~9까지 선택이 가능하다
( 1 - ERROR ,2 - WARNING ,3 - FIXME  ,4 - INFO  )
( 5 - DEBUG, 6 - LOG,  7 - TRACE, 9 - MEMDUMP )

Gstreamer 관련 환경변수들 (GST_DEBUG 이외 다양한 환경변수)
  https://gstreamer.freedesktop.org/documentation/gstreamer/running.html?gi-language=c

GST_DEBUG 관련사용방법
  https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html?gi-language=c


  • 전체설정 Debug
Gstreamer 를 전체 Debug 하고자 하면 아래와 같이 하면 되지만 별로 추천하지는 않는다.

$ export GST_DEBUG="*:2" //  전체 WARN,  설정이 가능,  가장 적절    
$ export GST_DEBUG="*:4" //  전체 INFO,설정    
$ export GST_DEBUG=""   // 설정제거


  • 원하는 PlugIn 만 Debug 
모든 PlugIn을 Debug 하지말고 특정 PlugIN만 Debug하여 관련부분의 문제점을 찾아보자.

 // 모든 PlugIN Debug  , 내부 PlugIN을 구조를 모르면 이렇게 확인하고 PlugIN 구조를 파악 
$ GST_DEBUG="*:5" deepstream-app -c deepstream_app_config_yoloV3.txt 

//특정 PlugIn만 Debug 
$ GST_DEBUG="dsexample:5" ./deepstream-rtsp-app rtsp://10.0.0.199:554/h264    // 특정 PlugIN만 세부 Debug 
$ GST_DEBUG="qtdemux:5" deepstream-app -c deepstream_app_config_yoloV3.txt  // qtdemux 만 세부 Debug 

//동시에 여러개 PlugIn Debug 
$ GST_DEBUG="qtdemux:5,dsexample:4 " deepstream-app -c deepstream_app_config_yoloV3.txt  // qtdemux 만 세부 Debug 


  • 이외 PlugIn의 카테고리 설정 Debug
본인이 직접 특정 Category를 선언하고 그에 관련된 부분을 직접 Debug도 가능하다, 상위 PlugIn도 다 들어가보면, Category로 선언하여 사용한다

// 소스에서 직접 원하는 Category 설정 (my_category)
GST_DEBUG_CATEGORY_STATIC (my_category);  // define category (statically)
#define GST_CAT_DEFAULT my_category       // set as default

  if (!my_category) {
   GST_DEBUG_CATEGORY_INIT (my_category, "MY_CAT", 0, NULL);
  }

  GST_CAT_INFO (my_category, "TEST Info %s", "Category TEST");
  GST_CAT_DEBUG (my_category, "TEST Debug %s", "Category TEST");
  GST_CAT_ERROR (my_category, "TEST error %s", "Category TEST");

//실제 테스트 
$ GST_DEBUG="MY_CAT:5" deepstream-app -c deepstream_app_config_yoloV3.txt 
$ GST_DEBUG="MY_CAT:9" deepstream-app -c deepstream_app_config_yoloV3.txt 


  https://gstreamer.freedesktop.org/documentation/gstreamer/gstinfo.html?gi-language=c


2.2  Gstreamer 관련부분 SDK3.0 관련부분 재확인

Gstreamer 관련 Test는 이미 SDK 3.0에서 많이 했기때문에 간단히 서술하며, SDK 4.0과 SDK 3.0은 호환성 Gstreamer 명령어가 동일하게 동작되지 않는 부분이 많다.
PlugIn 이름과 설정 변경이 되었기때문에 상위의 gst-inspect로 확인하고 실행하자

  • DeepStream SDK 3.0의 TEST2 예제 
아래와 같이  decodebin or uridecodebin 사용해서 테스트 진행했으며, 세부내용은 아래참조

$ pwd
/home/nvidia/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-test2

//Sample 영상로 1stGIE,2ndGIE ,nvtracker 사용하여 화면전체 재생 ( X-Window 재생은 상위 참조)

$ 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

// RTSP를 이용하여  1stGIE,2ndGIE ,nvtracker 사용하여 화면전체 재생 

$ gst-launch-1.0 uridecodebin uri=rtsp://10.0.0.199: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 ! \
        nvvideoconvert ! \
        capsfilter caps=video/x-raw(memory:NVMM), format=RGBA ! \
        nvdsosd ! nvoverlaysink

//Sample 영상로 1stGIE,2ndGIE ,nvtracker 사용하여 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

  • DeepStream SDK 3.0 관련문서 
아래 링크와 비교를 해보면, 이전의 DeepStream SDK 3.0과는 많이 변했으며, Gstreamer도 호환이 되지 않는다.
  https://ahyuo79.blogspot.com/2019/07/deepstream-sdk-30-gstreamer.html


2.3 Gstreamer 관련부분 SDK 4.0 관련부분확인 

DeepStream SDK 4.0으로 오면서 우선 가장 큰 차이는 1Channel을 사용해도 streammux는 반드시 사용이 되어야한다.
더불어 nvvidconv 대신 nvvideoconvert을 사용해야하며, 이전 처럼 필터설정은 필요없어 진것 같다.
nvvidconv의 경우 nvosd가 없어져서 동작이 안되는 것로 생각된다.
SDK 4.0으로 오면서 PlugIn(Element)의 Properties가 다양해졌으며, 변경되었기 때문에 조심하자.

  • DeepStream SDK 4.0의 TEST2  기본설정 
우선 아래와 같이 TensorRT (1st, 2nd) 엔진설정을 해두자
상위에서 설명했듯이 Jetson AGX Xavier는 INT8모드 지원하며 이를 설정시 Table도 같이 설정해야함 (상위참조)
- model-engine-file
- int8-calib-file
- network-mode=1     # 0=FP32, 1=INT8, 2=FP16 mode

DeepStream SDK4.0 TEST4 와 iPlugIn 관련사항 (이전부분참조)
  https://ahyuo79.blogspot.com/2019/08/ds-sdk-40-test4-iplugin-sample.html


$cd ~/deepstream-4.0/sources/apps/sample_apps/deepstream-test2
$ pwd
/home/nvidia/deepstream-4.0/sources/apps/sample_apps/deepstream-test2

$ vi dstest2_pgie_config.txt 
model-engine-file=../../../../samples/models/Primary_Detector/resnet10.caffemodel_b1_int8.engine

$ vi dstest2_sgie1_config.txt 
model-engine-file=../../../../samples/models/Secondary_CarColor/resnet18.caffemodel_b16_int8.engine

$ vi dstest2_sgie2_config.txt
model-engine-file=../../../../samples/models/Secondary_CarMake/resnet18.caffemodel_b16_int8.engine

$ vi dstest2_sgie3_config.txt
model-engine-file=../../../../samples/models/Secondary_VehicleTypes/resnet18.caffemodel_b16_int8.engine


  • nvstreammux 기본 사용법 
필수설정이므로 관련 각 기능을 알아두도록하자 (nvinfer 전에 설정)
아래와 같이 m.sink_0 을 두어 앞에 sink를 설정하여 여러채널을 받을 수 있다.
뒤의 설정을 보면 batch-size는 Channel (Frame) 과 Resolution을 설정 할수 있어 Scale도 가능하다
만약 nvinfer를 사용하지 않는다면, 아래의 테스트와 같이 사용을 안해도 상관은 없는것 같다.

m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720

관련질문사항( 궁금해서 직접 알아봄)
  https://devtalk.nvidia.com/default/topic/1061785/deepstream-sdk/about-streammux-in-ds-on-xavier/

PlugIn Manual ( 아직 미지원사항이 있으므로 주의 , Jetson과 Tesla 와 별도)
  https://docs.nvidia.com/metropolis/deepstream/4.0/DeepStream_Plugin_Manual.pdf

  • DeepStream SDK 4.0의 TEST2의 기본 테스트 진행 
우선  h264parse 와 nvv4l2decoder(nvv4l2decoder 새로 생김)을 이용하여 동작해보고, 출력은 X-Window창으로 출력을 하도록하자 (OpenGL사용)
아래와 같이 nvosd 가 사라져서 두번째 것은 동작이 안된다.

//Sample TEST 2 동작확인 
$ gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.h264 ! \
        h264parse !  nvv4l2decoder ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! nvegltransform ! nveglglessink

//Sample nvvidconv 와 nvosd 변경 (nvosd 미지원으로 에러발생)   4.0부터는 nvvideoconvert 와 nvdsosd 를 이용권장 
 gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.h264 ! \
        h264parse !  nvv4l2decoder ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        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


  • DeepStream SDK 4.0 의 TEST2  decode 테스트 실행 
기존처럼 편하게 deepstrem-test2 에 decodebin 과 uridecodebin을 사용이 가능하다.

 
// 주의 해야할 것은 처음 실행시, TensorRT Engine이 없으므로, 생성시간이 많이 걸림
// 각각의 model-engine-file을 설정을 해줘서 이를 해결하지만, Jetson AGX Xavier (INT8 지원가능)

//Sample TEST 2  decodebin 변경 (동작확인) 
$ gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.h264 ! \
        decodebin ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! nvegltransform ! nveglglessink

//Sample TEST 2  uridecodebin 변경 (RTSP지원) 동작확인 
$ gst-launch-1.0 uridecodebin uri=rtsp://10.0.0.199:554/h264 ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! nvegltransform ! nveglglessink

//Sample TEST 2  uridecodebin 변경 (FILE지원) 동작확인 
$ gst-launch-1.0 uridecodebin uri=file:///home/nvidia/deepstream-4.0/samples/streams/sample_720p.h264  ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! nvegltransform ! nveglglessink

//Sample TEST 2  uridecodebin 변경 (RTSP지원) 미동작확인 (nvstreamux 삭제) 
$ gst-launch-1.0 uridecodebin uri=rtsp://10.0.0.199:554/h264 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! nvegltransform ! nveglglessink

//Sample TEST 2  uridecodebin 변경 (RTSP지원) 동작확인 (nvstreamux 삭제 및 nvinfer/nvtracker 삭제 ) 
$ gst-launch-1.0 uridecodebin uri=rtsp://10.0.0.199:554/h264 ! \
        nvvideoconvert ! nvdsosd ! nvegltransform ! nveglglessink

nvinfer 때문에 nvstreamux 필요한 것 같음 (추측)

  • DeepStream SDK 4.0 의 TEST2  출력부분을 변경하여 각각 테스트
  1. nvegltransform ! nveglglessink 은 X-Window 창으로 출력 
  2. nvoverlaysink 설정하면, 전체 화면출력  

//Sample TEST 2  nvoverlaysink 변경 (전체화면) 동작확인 
$ gst-launch-1.0 uridecodebin uri=file:///home/nvidia/deepstream-4.0/samples/streams/sample_720p.h264  ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! nvoverlaysink

  • MPEG4->H.264 Transcoding 테스트 
기존과 동일하게 동작되며, 재생이 아닌이상 streammux가 설정안해도 됨

 $  gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.mp4 ! decodebin ! omxh264enc !  h264parse ! qtmux ! filesink location=test.h264 


  • tee를 사용하여 2개의 채널을 분리하여, 재생과 Transcoding 동시진행
기존 SDK 3.0 처럼 tee를 사용하여 재생과 Transcoding을 동시진행하려고 했으나 동작 안되는데, PlugIn(Element) 단위로 보면 미동작 원인이 이해가 안간다.

// 기본영상재생시 동작확인 ( Streammux 권고)
$  gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.mp4 ! decodebin ! m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! nvegltransform ! nveglglessink

// RTSP를 위해 uridecodebin으로 변경 후  nvstreammux 를 제거해서 실행 
$ gst-launch-1.0 uridecodebin uri=rtsp://10.0.0.201:554/h264 ! nvvideoconvert ! nvegltransform ! nveglglessink

// tee를 사용하여 1 Channel 재생  (동작확인) 
$  gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.mp4 ! decodebin ! tee name=t ! queue ! m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! nvegltransform ! nveglglessink 

//tee를 사용하여 2 채널 사용 (문제발생)
$  gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.mp4 ! decodebin ! tee name=t ! queue ! m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! nvegltransform ! nveglglessink t. ! queue ! omxh264enc !  h264parse ! qtmux  ! filesink location=test.mp4 

//tee를 사용하여 2 채널 사용 (NVIDIA 권고사항) 동작은되지만, 가끔 에러발생
$ gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.mp4 ! decodebin ! tee name=t ! queue ! m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! nvegltransform ! nveglglessink t. ! queue ! nvvideoconvert ! nvv4l2h264enc !  h264parse ! qtmux  ! filesink location=test.mp4

//tee를 사용하여 2 채널 사용 fakesink (동작확인)  , 4.0 부터는 NVIDIA에서는 omxh264enc를 권장하는 않는 것 같음 
$  gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.mp4 ! decodebin ! tee name=t ! queue ! fakesink t. ! queue ! omxh264enc !  h264parse ! qtmux  ! filesink location=test.mp4 

NVIDIA에게 직접물어보니 omxh264enc 대신 nvv4l2h264enc로 변경
  https://devtalk.nvidia.com/default/topic/1061803/deepstream-sdk/tee-in-ds-4-0-on-xavier-/


  • nvinfer 와 nvosd를 적용 후 화면재생과 H.264 Encoding 동시작업 
DS3.0 과 다르게 상위와 같이 omxh264enc 대신 nvv4l2h264enc을 사용해야 제대로 동작된다

//Sample TEST 2  nvoverlaysink 변경 (전체화면) 동작확인 

$ gst-launch-1.0 uridecodebin uri=file:///home/nvidia/deepstream-4.0/samples/streams/sample_720p.h264  ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! nvoverlaysink

// 기본동작은 상위와 동일하지만, 2 Channel로 nvosd를 걸쳐 화면재생과 H.264 Encoding 동시작업
$ gst-launch-1.0 uridecodebin uri=file:///home/nvidia/deepstream-4.0/samples/streams/sample_720p.h264  ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! \
        tee name=t ! queue ! nvegltransform ! nveglglessink \
        t. ! queue ! nvvideoconvert ! nvv4l2h264enc !  h264parse ! qtmux  ! filesink location=test.mp4

//NVIDIA가 추후 nvvideoconvert로 변경해보라고 해서 재테스트  
$ gst-launch-1.0 uridecodebin uri=file:///home/nvidia/deepstream-4.0/samples/streams/sample_720p.h264  ! \
        m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=720 ! \
        nvinfer config-file-path= dstest2_pgie_config.txt ! \
        nvtracker tracker-width=640 tracker-height=368  gpu-id=0  \
        ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so \
        ll-config-file=tracker_config.yml enable-batch-process=1 ! \
        nvinfer config-file-path= dstest2_sgie1_config.txt ! \
        nvinfer config-file-path= dstest2_sgie2_config.txt ! \
        nvinfer config-file-path= dstest2_sgie3_config.txt ! \
        nvvideoconvert ! nvdsosd ! \
        tee name=t ! queue ! nvvideoconvert ! nveglglessink \
        t. ! queue ! nvvideoconvert ! nvv4l2h264enc !  h264parse ! qtmux  ! filesink location=test.mp4



7/24/2019

Gstreamer 의 RTSP Server 구축

1. Gstreamer 기반의 RTSP Server 구축 

  • 우선 Gstreamer 관련 Package 및 관련 Package 설치 진행 
$ sudo apt-get install \ 
     libgstreamer0.10-dev  \ 
     libgstreamer-plugins-base0.10-dev 

$ sudo apt-get install \ 
     libfontconfig1-dev \ 
     libfreetype6-dev \ 
     libpng-dev 

$ sudo apt-get install \
       libcairo2-dev \
       libjpeg-dev \
       libgif-dev 

$ sudo apt-get install libgstreamer-plugins-base1.0-dev

  • Gstreamer 와 RTSP Server library 설치 진행 (Python용도 설치)
$ 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 python-gst-1.0 python3-gst-1.0

$ sudo apt-get install gir1.2-gst-rtsp-server-1.0

1.1 Gstreamer 기반으로 RTSP Server 동작 

  • 간단하게 아래와 같이 Gstreamer 기반으로 RTSP Server를 구축 
$ gst-launch-1.0 filesrc location=./test.mp4 ! qtdemux name=demux demux.video_0 ! queue ! rtph264pay pt=96 name=pay0 demux.audio_0 ! queue ! rtpmp4apay pt=97 name=pay1 demux.subtitle_0 ! queue ! rtpgstpay pt=98 name=pay2

  • Gstreamer Plugin 관련부분 확인 
  https://gstreamer.freedesktop.org/documentation/plugins_doc.html?gi-language=c






1.2 Python 기반의 RTSP Server 구축 

7/22/2019

DeepStream SDK 3.0 와 OpenALPR

1. DeepStream SDK에 OpenALPR 기본설치 

OpenALPR (Automatic License Plate Recognition)으로 자동차 번호판 인식하는 소스이며, 내부에는 tesseract OCR을 이용하여 이를 작동한다고 한다.

  • NVIDIA Deepstream SDK 4.0 API
SDK 4.0 API Manual이 존재하며, 아직 Jetson AGX Xavier에는 해당사항은 없지만, 참고사항으로 알아두자.

  https://docs.nvidia.com/metropolis/deepstream/4.0/dev-guide/DeepStream_Development_Guide/baggage/modules.html

  • NVIDIA L4T Multimedia API
소스를 수정하다보면,  Mulimedia 부분의 관련된 API와 구조체를 많이 보게되어 이 부분을 참고하자.

  https://docs.nvidia.com/jetson/l4t-multimedia/group__l4t__mm__nvbuffer__group.html

  • Tesseract OCR 설치
OpenALPR은 Tesseract 기반으로 하기때문에, 기본적인 Tesseract 설치와 사용법을 알아두자

  https://ahyuo79.blogspot.com/2019/05/tesseract-ocr.html

  • OpenALPR을 이용하여 만든 시스템 
Rekorsystems 회사에서 만든 시스템인 것 같은데, 인터넷에서 있기에 관련부분

  https://www.rekorsystems.com/
  https://youtu.be/ofpxX49vdXY

-다른 동영상
  https://www.youtube.com/watch?v=w6gs10P2e1k


1.1   OpenALPR 관련소스 와 사용법  

OpenALPR (Automatic License Plate Recognition)
  https://www.openalpr.com/

OpenALPR Source
  https://github.com/openalpr/openalpr

OpenALPR 관련 Project 전부
  https://github.com/openalpr


1.2  Jetson 에 OpenALPR 설치 

Jetson AGX Xavier 에서 OpenALPR 설치하고 이를 간단하게 테스트를 진행해보자. 

$ sudo apt-get update && sudo apt-get install -y openalpr openalpr-daemon openalpr-utils libopenalpr-dev

$ sudo apt list | grep tesseract  //   현재 4.0 지원 설치확인 
libtesseract-dev/bionic 4.00~git2288-10f4998a-2 arm64
libtesseract4/bionic,now 4.00~git2288-10f4998a-2 arm64 [installed,automatic]
tesseract-ocr/bionic 4.00~git2288-10f4998a-2 arm64
tesseract-ocr-afr/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-all/bionic 4.00~git2288-10f4998a-2 all
tesseract-ocr-amh/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-ara/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-asm/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-aze/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-aze-cyrl/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-bel/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-ben/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-bod/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-bos/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-bre/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-bul/bionic 4.00~git24-0e00fe6-1.2 all
tesseract-ocr-cat/bionic 4.00~git24-0e00fe6-1.2 all
....

$ sudo apt install tesseract-ocr
$ sudo apt install libtesseract-dev
$ sudo apt install tesseract-ocr-eng   // 영어 모델
$ sudo apt install tesseract-ocr-kor   // 한글 모델

$ alpr ./test.JPG 
Error opening data file /usr/share/openalpr/runtime_data/ocr/lus.traineddata
Please make sure the TESSDATA_PREFIX environment variable is set to your "tessdata" directory.
Failed loading language 'lus'
Tesseract couldn't load any languages!
Image file not found: test.JPG

$ sudo ln -s /usr/share/openalpr/runtime_data/ocr/tessdata/lus.traineddata /usr/share/openalpr/runtime_data/ocr/lus.traineddata

$ alpr ./test.JPG 
plate0: 10 results
    - GS00  confidence: 79.1004
    - GSH00  confidence: 78.1927
    - NGS00  confidence: 77.5058
    - NGSH00  confidence: 76.5981
    - GSD0  confidence: 76.2403
    - GSHD0  confidence: 75.3326
    - HGS00  confidence: 75.3263
    - GSO0  confidence: 75.1033
    - NGSD0  confidence: 74.6456
    - HGSH00  confidence: 74.4186

# Test US plates
$ wget http://plates.openalpr.com/ea7the.jpg
$ alpr -c us ea7the.jpg

# Test European plates
$ wget http://plates.openalpr.com/h786poj.jpg
$ alpr -c eu h786poj.jpg

$ ls /etc/openalpr/
alprd.conf  openalpr.conf

$ ls  /usr/share/openalpr/config/
alprd.defaults.conf  openalpr.defaults.conf

$ vi  /usr/share/openalpr/config/openalpr.defaults.conf         // debug 옵션 및 기타 설정가능
.....
debug_general         = 0
debug_timing          = 0
debug_detector        = 1
debug_prewarp         = 0
debug_state_id        = 0
debug_plate_lines     = 1
debug_plate_corners   = 0
debug_char_segment    = 0
debug_char_analysis   = 0
debug_color_filter    = 0
debug_ocr             = 1
debug_postprocess     = 0
debug_show_images     = 0
debug_pause_on_frame  = 0



OpenALPR 설치 및 기본사용법
  http://doc.openalpr.com/compiling.html
  http://doc.openalpr.com/on_premises.html


2. Deepstream SDK 3.0 과 OpenALPR  테스트 

OpenALPR을 가지고, Deepstream의 Gst-Plugin을 추가하여 사용되는 소스가 존재하며, 이를 간단하게 진행해보면, 빌드가 되지 않는데, 이 소스가 DeepStream SDK 1.0 기준으로
작성되어 동작되지 않는 것 같다.

Deepstream SDK의  Gstreamer OpenALPR PlugIn
  https://github.com/openalpr/deepstream_jetson


$ cd ~ 
$ git clone https://github.com/openalpr/deepstream_jetson
$ cd deepstream_jetson

$ make   //
gstdsexample.h:21:10: fatal error: nvbuf_utils.h: No such file or directory

$ vi Makefile   // Deepstream SDK의 Version이 다르며, 1.0과 호환되는 것 같다. 

#CFLAGS+= \
#  -I../nvgstiva-app_sources/nvgstiva-app/includes 
CFLAGS+= \
  -I../deepstream_sdk_on_jetson/sources/includes

$ make   //  Deepstream SDK Version이 맞지 않아 빌드가 되지 않는다.
gstdsexample.h:22:10: fatal error: gstnvivameta_api.h: No such file or directory


DeepSream SDK 1.0 관련내용
  https://tech-blog.abeja.asia/entry/deepstream-sdk-jetson


2.1 Commerical OpenALPR Porting (유료버전) 

DeepStream SDK 3.0에서도 동일하게 gst-dsexample을 제공하고 있으며, 이 소스를 변경하여 테스트를 진행해보자.
간단히 소스를 분석하면, Commercial OpenALPR의 소스를 사용하고 있어, 이에 관련된 SDK도 필요하며, 사용하고 싶다면 상용버전을 사야할 것 같지만, 일단 무료로 다운받아보고 설치해보자.

  • Commercial OpenALPR SDK 설치 
$ sudo apt install curl
$ bash <(curl -s https://deb.openalpr.com/install)


아래와 같이 선택해서 설치하자.


  1. install _webserver :  현재설치시 에러 발생 
  2. install_agent : 설치완료 
  3. install_sdk : 설치완료
  4. install_nvidia: 설치완료
Commercial Vesion
  http://doc.openalpr.com/sdk.html#linux

  • gst-dsopenaplr 기본구성 
dsopenalpr_lib만  복사하여 gst-dsexample에 넣고 유사하게 Makefile과 다른 소스도 수정하여 빌드를 진행을 하자
소스을 두 소스를 비교를 해서 수정을 많이 해야한다.

$ cp -a ../deepstream_sdk_on_jetson/sources/gst-plugins/gst-dsexample ../deepstream_sdk_on_jetson/sources/gst-plugins/gst-openaplr
$ cp -a dsopenalpr_lib ../deepstream_sdk_on_jetson/sources/gst-plugins/gst-openaplr/
$ cd ~/deepstream_sdk_on_jetson/sources/gst-plugins/gst-openaplr
$ rm -rf dsexample_lib 

소스를 수정하여 구성해도, 내부함수가 라이센스 키가 없으면, 아무런 동작하지 않기때문에 다른방법을 찾아봐야겠다. 유료버전을 사용한다면 이렇게 구성해서 사용하도록하자.


OpenALPR 의 Commercial Version의 장점
  http://doc.openalpr.com/opensource.html#commercial-enhancements

2.2  OpenALPR을 gst-dsexample 연결 ( 무료 )

상위와 같이 DeepStream SDK 3.0의 gst-dsexample을 이용하여 비슷하게 구성하고, 소스를 전부 분석하여 본인이 직접 만들어나가는 수 밖에 없을 것 같다.

상위 OpenALPR의 소스분석하면 실행파일관련 파일들을  찾을 수 있지만, 이것들을 전부 빌드하여 넣어 동작시키기가 쉽지않다.
그래서 이 방법보다는 이를 분석해서 내가 만든것이 왠지 더 나을 것 같다.

  https://github.com/openalpr/openalpr/tree/master/src/openalpr
  https://github.com/openalpr/openalpr/blob/master/src/openalpr/alpr.cpp

아래의 구성으로 이 함수를 참조하여 오픈소스로 다시 해보자.
  http://doc.openalpr.com/opensource.html#developers-guide



2.3  OpenALPR Cloud API 연결방법 (무료/유료)

OpenALPR의 Cloud가 제공하고 있으며, 간단하게 Cloud API로 연결하여 그림파일을 전송하면되는 방식이다.

  • OpenALPR Cloud API 테스트 진행 
아래의 사이트에서 자동차 사진을 가지고 있다면, OpenALPR을 Cloud API을 이용하여 테스트 가능하며, 월 1000개까지 무료인 것 같다.
  http://www.openalpr.com/cloud-api.html


  • OpenALPR Cloud API 사용방법 
각 Shell / Python / C#을 이용하여 Cloud API 예제를 제공하고 있으므로, 이부분을 참조하자.
  http://doc.openalpr.com/cloud_api.html

7/19/2019

DeepStream SDK 3.0 Kafka 연결

1. DeepStream SDK 3.0 Msg 관련부분 설정 및 테스트


  • 기본설치방법

아래링크의-DeepStream SDK 3.0 설치 참조
  https://ahyuo79.blogspot.com/2019/06/deepstream-sdk-30-jetpack-42-411.html


NVIDIA msgbroker 관련부분
  https://devtalk.nvidia.com/default/topic/1048534/deepstream-for-tesla/deepstream-test4-app-stalled-after-the-first-few-frames/
 https://devtalk.nvidia.com/default/topic/1044365/deepstream-for-tesla/using-kafka-protocol-for-retrieving-data-from-a-deepstream-pipeline-/

NVIDIA Analytic Server ( Smart PArking Sytstem)
  https://github.com/NVIDIA-AI-IOT/deepstream_360_d_smart_parking_application/

Kafka Site
  https://kafka.apache.org/intro.html

Apach Kafka 구조 파악
  https://epicdevs.com/17
  https://www.joinc.co.kr/w/man/12/Kafka/chatting

1.1 DeepStream SDK 3.0 TEST 4 부분 

아래 링크의 3.4 Deepstream TEST 4 (Kafka) 부분 다시 참조
  https://ahyuo79.blogspot.com/2019/06/deepstream-sdk-30-jetpack-42-411.html



$ vi deepstream_test4.app.c 
#define PROTOCOL_ADAPTOR_LIB  "/usr/lib/aarch64-linux-gnu/tegra/libnvds_kafka_proto.so"
#define CONNECTION_STRING "127.0.0.1;9092;dsapp2"

  1. 우선 아래의 Kafka를 설치
  2. 설치완료 후 dsapp2의 topic 생성
  3. 상위 수정된 소스 make 후 deepstream-test4-app 실행 
  4. 상위 topic으로 받은 메시지를 bin/kafka-console-consumer.sh 이용하여 확인 


이 소스는 Gst-msgconv 와 Gst-msgbroker 를 같이 사용하는 예제이다.
Gst-msgconv는 현재 config file을 별도로 지정하여 dstest4_msgconv_config.txt 설정하고 이 설정에 해당하는 소스부분이 상위 소스에 있다.
Gst-msgbroker 는 받은 metadata를 Kafka에게 전송하는 역할이며, 현재 모두 JSON Format이다.

$ cd /usr/local/kafka
$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic dsapp2 --from-beginning            //deepstream-test4-app 이 보낸 metadata 를 json으로 보냄 
{
  "messageid" : "220a8cea-9dc5-448c-8da6-cc9998a5fefe",
  "mdsversion" : "1.0",
  "@timestamp" : "2019-07-22T02:01:54.067Z",
  "place" : {
    "id" : "1",
    "name" : "XYZ",
    "type" : "garage",
    "location" : {
      "lat" : 30.32,
      "lon" : -40.549999999999997,
      "alt" : 100.0
    },
    "aisle" : {
      "id" : "walsh",
      "name" : "lane1",
      "level" : "P2",
      "coordinate" : {
        "x" : 1.0,
        "y" : 2.0,
        "z" : 3.0
      }
    }
  },
  "sensor" : {
    "id" : "CAMERA_ID",
    "type" : "Camera",
    "description" : "\"Entrance of Garage Right Lane\"",
    "location" : {
      "lat" : 45.293701446999997,
      "lon" : -75.830391449900006,
      "alt" : 48.155747933800001
    },
    "coordinate" : {
      "x" : 5.2000000000000002,
      "y" : 10.1,
      "z" : 11.199999999999999
    }
  },
  "analyticsModule" : {
    "id" : "XYZ",
    "description" : "\"Vehicle Detection and License Plate Recognition\"",
    "source" : "OpenALR",
    "version" : "1.0",
    "confidence" : 0.0
  },
  "object" : {
    "id" : "db521849-00f8-44f6-b20c-daf3111b6ccd",
    "speed" : 0.0,
    "direction" : 0.0,
    "orientation" : 0.0,
    "vehicle" : {
      "type" : "sedan",
      "make" : "Bugatti",
      "model" : "M",
      "color" : "blue",
      "licenseState" : "CA",
      "license" : "XX1234",
      "confidence" : 0.0
    },
    "bbox" : {
      "topleftx" : 0,
      "toplefty" : 0,
      "bottomrightx" : 0,
      "bottomrighty" : 0
    },
    "location" : {
      "lat" : 0.0,
      "lon" : 0.0,
      "alt" : 0.0
    },
    "coordinate" : {
      "x" : 0.0,
      "y" : 0.0,
      "z" : 0.0
    }
  },
  "event" : {
    "id" : "b63d0d65-eaf8-44c5-be51-979a009f8a33",
    "type" : "moving"
  },
  "videoPath" : ""
}
....   // Ctrl+C 로 정지 



2.  Apache Kafka 설치 작업 및 테스트 

Apache Kafka를 설치를 위해서 Apache Zookeeper가 필요하기에 아래와 같이 설치하다.

  • apt update 와 Java JDK or default-jre 설치 
Kafka 설치를 위해 JDK or JRE설치

$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk


2.1 Apache zookeeper  기본설치


zookeeper site
  https://zookeeper.apache.org/releases.html

package download
  https://www-eu.apache.org/dist/zookeeper/
  http://www-us.apache.org/dist/zookeeper
  http://apache.mirror.globo.tech/zookeeper


  • zookeeper 설치 (apt 이용)
$ sudo apt-get install zookeeperd

$ find / -name zkServer.sh 2> /dev/null 
/usr/share/zookeeper/bin/zkServer.sh


  • package download 설치 
package로 설치하면 /usr/share 에 존재하는 것 같아  /usr/local/변경

$ wget https://www-eu.apache.org/dist/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz
$ tar zxvf zookeeper-3.4.14.tar.gz
$ sudo mv zookeeper-3.4.14/ /usr/local/zookeeper
$ sudo chown -R root:root /usr/local/zookeeper

$ find / -name zkServer.sh 2> /dev/null      // 좀더 최신 version이라 좀 다르다.
/usr/local/zookeeper/zookeeper-contrib/zookeeper-contrib-rest/src/test/zkServer.sh
/usr/local/zookeeper/zookeeper-contrib/zookeeper-contrib-zkpython/src/test/zkServer.sh
/usr/local/zookeeper/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
/usr/local/zookeeper/bin/zkServer.sh
/usr/local/zookeeper/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/tests/zkServer.sh
/usr/local/zookeeper/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/tests/zkServer.sh


2.2 Apache Zookeeper  Service 등록 

사용하기 편하기 위해서 아래와 같이 systemd에 Service로 등록을 한다.

  • systemd 에 zookeeper.service 등록 

$ sudo vi /etc/systemd/system/zookeeper.service
[Unit]
Description=zookeeper-server
After=network.target

[Service]
Type=forking
User=root
Group=root
SyslogIdentifier=zookeeper-server
WorkingDirectory=/usr/share/zookeeper
Restart=on-failure
RestartSec=0s
ExecStart=/usr/share/zookeeper/bin/zkServer.sh start
ExecStop=/usr/share/zookeeper/bin/zkServer.sh stop


  • system service 등록 및 확인 

$ sudo systemctl daemon-reload
$ sudo systemctl enable zookeeper.service
$ sudo systemctl start zookeeper.service
$ sudo systemctl status zookeeper.service


  • zookeeper 상태체크

$ netstat -nlp|grep 2181
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp6       0      0 :::2181                 :::*                    LISTEN      -  

$ sudo /usr/share/zookeeper/bin/zkServer.sh status     
ZooKeeper JMX enabled by default
Using config: /etc/zookeeper/conf/zoo.cfg
Error contacting service. It is probably not running.

or 

$ echo status | nc 127.0.0.1 2181
Zookeeper version: 3.4.10-3--1, built on Sat, 03 Feb 2018 14:58:02 -0800
Clients:
 /127.0.0.1:45894[0](queued=0,recved=1,sent=0)

Latency min/avg/max: 0/0/0
Received: 3
Sent: 2
Connections: 1
Outstanding: 0
Zxid: 0x0
Mode: standalone
Node count: 4


2.3  Apache Kafka 관련 설치 및 서비스 등록 


Apache Kafka
  https://kafka.apache.org/

Package download (지원되는 Version확인)
  https://www-eu.apache.org/dist/kafka
  http://www-us.apache.org/dist/kafka
  http://apache.mirror.globo.tech/kafka


Download하면서 Version이 혼동이 되었는데, 아래 사이트에서 정확하게 알게되었다.
Kafka가 Scala 언어로 개발되었는데,  호환성문제로 Java로 이식되었다고 한다.
Version 은  File에서 두개로 표시를 한다

e.g kafka/2.2.1/kafka_2.12-2.2.1.tgz  (Scala:2.12 , Kafka:2.2.1)

현재 Download 하는 사이트들을 보니 현재는 Kafka 2.x.x 만 지원을 하고 있어서 이 기준으로 변경


  • Kafka Download 및 기본 테스트 진행 

$ wget http://www-us.apache.org/dist/kafka/2.2.1/kafka_2.12-2.2.1.tgz  //download 가능 

$ tar zxvf kafka_2.12-2.2.1.tgz
$ sudo mv kafka_2.12-2.2.1 /usr/local/kafka

$ cd /usr/local/kafka

$ vi config/server.properties     // Log Data 설정된 장소확인 및 변경 
log.dirs=/tmp/kafka-logs/

상위 log.dirs 은 만약 topic를 생성하면 이곳에서 관련 data를 확인이 가능하다.


  • Kafka Service 등록 

$ sudo vi  /etc/systemd/system/kafka.service          // 새로운 File 생성 
[Unit]
Description=kafka-server
After=network.target

[Service]
Type=simple
User=root
Group=root
SyslogIdentifier=kafka-server
WorkingDirectory=/usr/local/kafka
Restart=no
RestartSec=0s
ExecStart=/usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/server.properties
ExecStop=/usr/local/kafka/bin/kafka-server-stop.sh

$ systemctl daemon-reload
$ systemctl enable kafka.service
$ systemctl start kafka.service
$ systemctl status kafka.service



  • Kafka 동작확인

$ sudo apt install lsof 
$ sudo lsof -i :2181                       //Zookeeper 만 동작될 때 
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    18819 zookeeper   43u  IPv6 759187      0t0  TCP *:2181 (LISTEN)

$  sudo lsof -i :2181      //Zookeeper 와 Kafka 동작될 때 
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    22350 nvidia  109u  IPv6 767085      0t0  TCP *:2181 (LISTEN)
java    22350 nvidia  110u  IPv6 761679      0t0  TCP localhost:2181->localhost:46018 (ESTABLISHED)
java    22675 nvidia  109u  IPv6 766151      0t0  TCP localhost:46018->localhost:2181 (ESTABLISHED)



2.4  Kafka TEST 방법 

Kafka는 File기반으로 Topic을 만들고,  이를 통신하는 구조라고 한다.
아래과 같이 새로운 testTopic을 만들고 이를 MSG를 전송해보고 받아보자.

  • Kafka에서 testTopic 생성 및 확인

$ cd /usr/local/kafka
$ bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic testTopic
Created topic "testTopic".

$ bin/kafka-topics.sh --list --zookeeper localhost:2181     // 생성된 list
testTopic

$ ls //tmp/kafka-logs/     // testTopic 확인 
..
testTopic-0/               


  • Kafka로 MSG 전송 (testTopic)

$ cd /usr/local/kafka
$ bin/kafka-console-producer.sh --broker-list localhost:9092 --topic testTopic    
>Welcome to kafka
>This is my first topic      // Ctrol+c 


  • Kafka에서 받은 메시지 확인  (testTopic)

$ cd /usr/local/kafka
$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic testTopic --from-beginning
Welcome to kafka
This is my first topic


Kafka 설치방법들
  https://zzsza.github.io/data/2018/07/24/apache-kafka-install/
  https://tecadmin.net/install-apache-kafka-ubuntu/
  https://linuxhint.com/install-apache-kafka-ubuntu/
  https://jwon.org/install-kafka-on-ubuntu/
  https://www.digitalocean.com/community/tutorials/how-to-install-apache-kafka-on-ubuntu-18-04


2.5  systemctl 사용법 

  • systemd default target 확인

$ systemctl get-default
multi-user.target

$ sudo systemctl set-default graphical.target  // X-Windows Log In 변경 

$ systemctl get-default
graphical.target


  • systemd target list 확인

$ systemctl list-units --type target
UNIT                  LOAD   ACTIVE SUB    DESCRIPTION              
basic.target          loaded active active Basic System             
bluetooth.target      loaded active active Bluetooth                
cryptsetup.target     loaded active active Encrypted Volumes        
getty.target          loaded active active Login Prompts            
graphical.target      loaded active active Graphical Interface      
local-fs-pre.target   loaded active active Local File Systems (Pre) 
local-fs.target       loaded active active Local File Systems       
multi-user.target     loaded active active Multi-User System        
network-online.target loaded active active Network is Online        
network.target        loaded active active Network                  
nfs-client.target     loaded active active NFS client services      
paths.target          loaded active active Paths                    
remote-fs-pre.target  loaded active active Remote File Systems (Pre)
remote-fs.target      loaded active active Remote File Systems      
slices.target         loaded active active Slices                   
sockets.target        loaded active active Sockets                  
sound.target          loaded active active Sound Card               
swap.target           loaded active active Swap                     
sysinit.target        loaded active active System Initialization    
time-sync.target      loaded active active System Time Synchronized 
timers.target         loaded active active Timers                   

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.


  • systemd default target 확인

$ systemctl get-default
multi-user.target

$ systemctl get-default
graphical.target

systemctl 사용법
  https://www.lesstif.com/pages/viewpage.action?pageId=24445064


System Service 등록방법
  https://fmd1225.tistory.com/93
  https://pinedance.github.io/blog/2017/09/12/Ubuntu-16.04-system-service-%EB%93%B1%EB%A1%9D%ED%95%98%EA%B8%B0



7/11/2019

Deepstream SDK 3.0 자료정리 와 Gstreamer 관련부분정리

1. Deepstream SDK 3.0 자료정리 


DeepStream 과 Could or Server  연결되어 구성이 되며, Server/Cloud는 Deepstream 정보를 분석하는 기능으로 이를 반영하여 통계를 낸다.




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

Accelerate Video Analytics Development with DeepStream 2.0
  https://devblogs.nvidia.com/accelerate-video-analytics-deepstream-2/?ncid=so-int-dmsk20ntllh-43648

Multi-Camera Large-Scale Intelligent Video Analytics with DeepStream SDK
  https://devblogs.nvidia.com/multi-camera-large-scale-iva-deepstream-sdk/
  https://devblogs.nvidia.com/intelligent-video-analytics-deepstream-sdk-3-0/

NVIDIA Smart Parking System 관련소스
  https://github.com/NVIDIA-AI-IOT/deepstream_360_d_smart_parking_application/tree/master/analytics_server_docker
  https://github.com/NVIDIA-AI-IOT/deepstream_360_d_smart_parking_application/tree/master/ui


NVIDIA DeepStream FAQ
  최근에 만들어졌으며, 궁금한것들이 잘 정리되어있다.
  https://developer.nvidia.com/deepstream-faq


2. Jetson Xavier 의 Gstreamer 정리  

NVIDIA 에서제공하는 Gstreamer 관련기능 확인

NVIDIA Gstreamer 관련 Manual
  https://developer.download.nvidia.com/embedded/L4T/r24_Release_v2.1/Docs/Accelerated_GStreamer_User_Guide_Release_24.2.1.pdf?Dsg5YTViV_i5SxRbavlm3R7FqNVkipeBaAerYDWgbrzpG_PGcUsOBUFf-tRmfM8oTzP1cVkFoKWd377iX2XFDoch9j9QcTG5-81dXNzyHAmEsyNn9mSbUsHK3tztpzwhFhQ7NLkzLPyHeb8k6vKxNg1pNLdk_XXK5x-BxvKNf2oh3M8C7LuMBT1-ZA5mwJPcdOvuJLA


2.1 get-inspect 사용방법 

NVIDIA에서 제공하는 Gstreamer의 PlugIn들을 확인을 해보자

  • Gstreamer PlugIn 모든기능확인 
Gstreamer에서 제공하는 모든 PlugIn 와 그의 기능을 확인가능하다.

$ gst-inspect-1.0 -a   // 모든 PlugIn 확인가능    
.......
$ gst-inspect-1.0 -a |  grep dsexample
......


  • Gstreamer 특정 PlugIn 분석 

Gstreamer의 특정 PlugIn 정보를 넣고 아래와 같이 확인하자.

$ gst-inspect-1.0 dsexample    // PlugIn 기능확인 
nvbuf_utils: Could not get EGL display connection
Factory Details:
  Rank                     primary (256)
  Long-name                DsExample plugin
  Klass                    DsExample Plugin
  Description              Process a 3rdparty example algorithm on objects / full frame
  Author                   Shaunak Gupte 

Plugin Details:
  Name                     nvdsexample
  Description              NVIDIA example plugin for integration with DeepStream on Jetson
  Filename                 /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvdsexample.so
  Version                  1.0
  License                  Proprietary
  Source module            dsexample
  Binary package           NVIDIA DeepStream 3rdparty IP integration example plugin
  Origin URL               http://nvidia.com/

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBaseTransform
                         +----GstDsExample

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      video/x-raw(memory:NVMM)
                 format: { (string)NV12, (string)RGBA }
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]
  
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw(memory:NVMM)
                 format: { (string)NV12, (string)RGBA }
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]

Element has no clocking capabilities.
Element has no URI handling capabilities.

Pads:
  SINK: 'sink'
    Pad Template: 'sink'
  SRC: 'src'
    Pad Template: 'src'

Element Properties:
  name                : The name of the object
                        flags: readable, writable
                        String. Default: "dsexample0"
  parent              : The parent of the object
                        flags: readable, writable
                        Object of type "GstObject"
  qos                 : Handle Quality-of-Service events
                        flags: readable, writable
                        Boolean. Default: false
  unique-id           : Unique ID for the element. Can be used to identify output of the element
                        flags: readable, writable
                        Unsigned Integer. Range: 0 - 4294967295 Default: 15 
  processing-width    : Width of the input buffer to algorithm
                        flags: readable, writable
                        Integer. Range: 1 - 2147483647 Default: 640 
  processing-height   : Height of the input buffer to algorithm
                        flags: readable, writable
                        Integer. Range: 1 - 2147483647 Default: 480 
  full-frame          : Enable to process full frame or disable to process objects detected by primary detector
                        flags: readable, writable
                        Boolean. Default: true

상위기능을 간단히 분석해보면 다음과 같다.

  1. FilenameGstreamer의 이 PlugIn 위치확인
  2. Pad Templates :  PAD의 특성을 확인가능
  3. Availability :  PAD의 사용가능여부 (Always)
  4. Capabilities : PAD의 속성으로 보통 영상에서는 filter라고 생각하면됨 ( 설정이 다양함)
  5. Pads:  일반적으로는 두개의 PAD (src/sink)를 가지지만, 그 이상을 가질수도 있다. 
  6. Element Properties : 외부에서 줄수 있는 옵션으로 Command에서  이 옵션을 설정가능(name, parent,qos는 거의 동일하므로, 이를 제외하고 설정)  

GST-Inspect  Manual
  https://gstreamer.freedesktop.org/documentation/tools/gst-inspect.html?gi-language=c

2.2 Gstreamer  기본 영상재생  

Gstreamer의 command tool 인 gst-launch를 이용하여 NVIDIA에서 제공하는 PlugIn들을 테스트 진행을 해보자.

gst-launch 사용법
  https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html?gi-language=c


  • 각  PlugIn 간략설명 
  1. decodebin :  h264/mpeg4 를 decode 해주는 plugin  (omxh264dec 및 다른것으로 대체가능)
  2. uridecodebin:  decodebin기능을 포함하며, multiuri를 지원 ( RTSP:// , FILE://
  3. nvoverlaysink : 화면전체로 출력하며, Window창 기준이 아님 
  4. nveglglessink: X Window 창 기준으로 출력하지만, nvegltransform 이 필요함
  5. nvosd : RGBA기준으로 동작이 되며, 기본이 NV12이므로 이전에 nvvidconv 로 변환필요 


  • MP4/ H.264  decoding 후 기본영상재생  
// X Window 창으로 Play (OPENGL사용)
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! decodebin ! nvegltransform  ! nveglglessink

//전체화면 Play 
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! decodebin ! nvoverlaysink

  • MP4/ H.264  decoding 후 OSD를 걸쳐 기본영상재생  
OSD를 사용하는 이유는 NV12->RGBA로 변환하여 이를 적용할 것들을 적용하기위함이다.

//  OSD를 걸쳐 X Window 창으로 Play (OPENGL사용)
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! decodebin !  nvvidconv ! nvosd ! nvegltransform  ! nveglglessink

//  OSD를 걸쳐 전체화면 Play 
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! decodebin !  nvvidconv ! nvosd ! nvoverlaysink


2.3 Gstreamer  Deconding 후 Encoding 방법 

말이 좀 어려운데, 한마디로 Transcoding or  본인이 본 영상을 Recording 하는 방법이 될 것이다
Encoding된 영상의 품질은 아래의 omxh264enc에서 설정으로 다양하게 변경가능하다.

  • H.264로 Transcoding 
 화면재생은 안되며, H.264로 Transcoding 함

$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! decodebin ! omxh264enc !  h264parse ! qtmux ! filesink location=test.mp4  


  • 화면재생 과 H.264 Encoding 동시작업
이 작업을 하기위해서는 tee라는 stream을 분기하는 plugin을 사용하여 아래와 같이 두개로 나눠 재생과 H.264 Encoding 작업을 하자

decodebin 이후 tee로 2개로 분기하여 화면재생 과 H.264 Encoding 동시 진행

$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! decodebin !  tee name=t ! queue ! nvegltransform ! nveglglessink t. !  omxh264enc !  h264parse ! qtmux  ! filesink location=test.mp4

qtmux 관련사항( audio/video를 merge하여 QuickTime Format *.mov)
  https://gstreamer.freedesktop.org/documentation/isomp4/qtmux.html?gi-language=c

tee 를 이용한 2 Channel 사용
  https://gstreamer.freedesktop.org/documentation/coreelements/tee.html?gi-language=c

  • nvinfer 와 nvosd를 적용 후 화면재생과 H.264 Encoding 동시작업 
상위와 동일한 기능이라 동일할거라고 생각하지만 다소 복잡하다.

nvosd 이후로 tee로 2개로 분기하며  화면재생과 H.264 Encoding 진행해서 Encoding을 한다
또 다른점은 nvosd를 걸쳐서, nvvidconv를 다시 한번 사용해줘야 framerate 조절이 되며, 이부분을 삭제하며 동영상이 빨리 재생되는 문제가 발생한다.

// nvosd 이후로 tee로 2개로 분기하여 화면재생 과 H.264 Encoding 동시진행   
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 !  decodebin ! nvinfer config-file-path= config_infer_primary_ssd.txt ! nvvidconv ! nvosd ! tee name=t ! queue ! nvegltransform ! nveglglessink t. ! queue ! nvvidconv ! 'video/x-raw(memory:NVMM), format=(string)I420'  ! omxh264enc !  h264parse ! qtmux  ! filesink location=test.mp4

// nvosd 이후로 tee로 2개로 분기하여 화면재생 과 H.264 Encoding 동시진행  ( 상위와 동일하지만, capsfileter 부분제거) 
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 ! decodebin ! nvinfer config-file-path= config_infer_primary_ssd.txt ! nvvidconv ! nvosd ! tee name=t ! queue ! nvegltransform ! nveglglessink t. ! queue ! nvvidconv ! omxh264enc !  h264parse ! qtmux  ! filesink location=test.mp4

상위와 비슷하게 구성을 했지만, 오작동되는 부분을 간략정리

//nvosd에서 직접 tee로 나누어 이를 저장했더니 gstreamer 재생시는 문제가 없으나, 다른 Player에서 재생속도가 너무빠르다.
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 !  decodebin ! nvinfer config-file-path= config_infer_primary_ssd.txt ! nvvidconv ! nvosd ! tee name=t ! queue ! nvegltransform ! nveglglessink t. ! queue ! omxh264enc control-rate=1 ! 'video/x-h264,stream-format=(string)byte-stream' ! filesink location=test.mp4

//nvosd 를 걸치지 않아, bbox 표시가 되지 않는다.
$ gst-launch-1.0 filesrc location=../../samples/streams/sample_720p.mp4 !  decodebin ! nvinfer config-file-path= config_infer_primary_ssd.txt ! nvvidconv ! 'video/x-raw(memory:NVMM), format=(string)I420' ! omxh264enc ! h264parse ! qtmux ! filesink location=test.mp4


  • PlugIn 의 capsfilter 의 역할
PAD에 상위에 보면 Capabilities 보면 두개의 Format을 지원하고 있으며, 이때 강제적으로 Format 혹은 video의 종류를 변경해줘야 할 경우 사용하는 것이 이 PlugIn의 역할될 것이다.
정의를 하여 오작동을 방지하는 것이 맞고, 강제로 변경도 가능하므로, 이 부분을 알아두자.

사용방법
  1. capsfilter caps=video/x-raw,format=GRAY8     :  다 정의하고 사용 
  2. video/x-raw,format=GRAY8                                      :  필요부분만 정의
  3. 'video/x-raw(memory:NVMM), format=NV12'  :  필요부분만 정의 ''는 ()때문에 필요 
  4. 'video/x-raw(memory:NVMM), format=RGBA'
이 기능은 연결된 PlugIn을 상위에서 처럼 gst-inspec로 반드시 확인하고 사용하며, 만약 지원되지 않는 것이라면, 무시되니 걱정말자.

  https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-capsfilter.html
  https://gstreamer.freedesktop.org/documentation/videoconvert/index.html?gi-language=c


2.4  Gstreamer의 nvinfer를 적용 (Deepstream) 
X-Window 화면 창으로 구성하기위해서 아래와 같이 nveglglessink만 사용하겠으며, 본인이 좀 더 세부적인 설정을 원하면, 위치와 크기도 조절가능하다.

nvinfer를 적용하기위해서는 config-file-path가 필요하므로, 위치와 본인이 실행하고자하는 gstreamer를 실행해보자.

Command로만 실행을 하면 Deepstream이 제대로 동작이 되지 않으며, 이유는 이전에도 설명했듯이 Callback Function 의 Metadata 처리 부분이 동작이 안되기 때문이다
더불어 다른 것도 마찬가지이다.

  • SSD 와 FasterRCNN 실행 
SSD 와 FasterRCNN 설정을 가지고 테스트 해보자
config는 custom-lib-path, parse-bbox-func-name 설정하고, 구현된 C++과 연결하여 사용하므로 이부분 설정은 까먹지 말자.

$ 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

$ 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

  • SSD 와 FasterRCNN 실행 ( dsexample 적용)
상위와 다른점은 dsexample이  opencv를 이용하여 사각형을 만들어 제공해주고 있으며, 관련소스는 Deepstream SDK의 소스를 참고
dsexample을 nvosd 이후로 넣으면 작동이 안됨 

$ 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 ! \
        dsexample ! nvvidconv ! nvosd ! nvegltransform ! nveglglessink

  • nvinfer (1stGIE, 2ndGIE로 구분하여 사용)
상위 nvinfer는 Object Detection만 사용했다면, 이제 Classfication 기능도 같이 사용해서 테스트를 진행하자

$ pwd
/home/nvidia/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-test2

//Sample 영상로 1stGIE,2ndGIE ,nvtracker 사용하여 화면전체 재생 ( X-Window 재생은 상위 참조)

$ 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

// RTSP를 이용하여  1stGIE,2ndGIE ,nvtracker 사용하여 화면전체 재생 ( X-Window 재생은 아래 참조)

$ 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

//Sample 영상로 1stGIE,2ndGIE ,nvtracker 사용하여 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


  • nvmsgconv 와 nvmsgbroker 기능 (Kafka와 작동안됨)
test4가 이전에도 설명했듯이 아래의 구조를 가지고 있지만, Command로 실행시 동작자체가 되지 않는다. 역시 Callback Function 의 처리가 필요하다.
이전의 test4를 참조하자

$ pwd
/home/nvidia/deepstream_sdk_on_jetson/sources/apps/sample_apps/deepstream-test4

$  gst-launch-1.0 filesrc location=../../../../samples/streams/sample_720p.h264 ! \
        h264parse ! omxh264dec ! \
        nvinfer config-file-path= dstest4_pgie_config.txt ! \
        nvvidconv ! \
        nvosd font-size=15 ! tee name=t ! \
        queue ! nvegltransform ! nveglglessink t. ! \
        queue ! nvmsgconv config=dstest4_msgconv_config.txt ! \
        nvmsgbroker proto-lib=/usr/lib/aarch64-linux-gnu/tegra/libnvds_kafka_proto.so conn-str=127.0.0.1;1280;dsapp2


2.5 기타 Debug와 다른 기본 Gstreamer Command 

참조용으로 다시 기록

$ 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


Gstreamer DEBUG
  https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html?gi-language=c



NVIDIA  Gstreamer 관련자료

  https://devtalk.nvidia.com/default/topic/1032597/how-to-capture-video-using-gst-launch-1-0-/
  https://developer.ridgerun.com/wiki/index.php?title=Gstreamer_pipelines_for_Jetson_TX2#v4l2src
  https://devtalk.nvidia.com/default/topic/1048481/jetson-agx-xavier/h264-streaming-issues/
  https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good/html/gst-plugins-good-plugins-v4l2src.html