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