DeepStream 프레임워크의 기본 구조는 모두 GStreamer에 기반한 것들입니다. GStreamer Concepts 을 살펴보고 기본적인 구성 요소들과 각 구성 요소간의 상호작용에 대한 사항들을 숙지한다면, DeepStream 구조와 설정에 대해 이해하는 데에도 도움이 됩니다.

DeepStream GStreamer Concepts

GStreamer 와 NVIDIA DeepStream 의 명칭을 유심히 보시기 바랍니다. 두 가지 프레임워크는 공통적으로 Stream 이라는 단어로부터 생성된 명칭을 사용하고 있습니다. Stream 은 직역하면 ‘흐름’ 이라는 의미입니다. 즉, GStreamer 와 DeepStream 은 어떤 데이터의 흐름을 제어하고 관리하기 위한 프레임워크임을 짐작할 수 있습니다.

Elements

Element 는 GStreamer의 기본 구성 블록입니다. Source Element 에서 Sink Element 로 데이터 스트림이 흐르는 동안 Filter Element 를 통과하면서 데이터가 적절하게 변형됩니다. 이러한 Element 는 데이터의 처리 방식에 따라 3 가지 유형으로 구분합니다.

Source

Source Element 는 데이터의 생산자 역할을 합니다. 파이프라인상의 가장 앞단에 위치합니다. Source Element 는 데이터를 최초로 생성하고 파이프라인상 연결되어 있는 다음 element 에게 흘려 보냅니다.

Filter

Filter Element 는 데이터의 가공자 역할을 합니다. Pipeline 상의 중간 부분에 위치합니다. 하나의 data stream 에서 여러 단계의 filter element 를 거쳐 데이터가 가공될 수 있습니다. Filter Element 는 파이프라인상에 연결된 다른 element 로부터 데이터를 전달받아 가공하여 다음 element 에게 흘려 보냅니다.

Sink

Sink Element 는 데이터의 소비자 역할을 합니다. Pipeline 상의 끝 부분에 위치합니다. Sink Element 는 파이프라인상에 연결된 다른 element 로부터 데이터를 전달받아 소비합니다. Sink Element 에서 파이프라인상에 흐르는 데이터는 최종적으로 소멸하게 됩니다.

Pipeline

이렇게 데이터의 “생산” – “가공” – “소비” 를 담당하는 각 Elements 의 묶음 단위를 “파이프라인” 이라고 합니다. 요소의 이해를 위해 아래의 그림을 참고하시기 바랍니다.

GStreamer Pipeline
GStreamer Pipeline

DeepStream GStreamer Examples

GStreamer 에서 사전 정의된 Src, Filter, Sink Element 가 많이 있습니다. 관련 문서는 GStreamer Document (링크) 를 참고하시면 됩니다. 좌측 하단의 Plugins 메뉴를 참고하십시오.

파이프라인을 구성할 때는 반드시 데이터의 흐름을 위주로 생각해야 합니다. 예를 들어 다음과 같은 데이터 흐름을 생각해 볼 수 있습니다.

H.264 영상 파일을 VP9로 인코딩하여 mp4 파일로 저장한다.

이런 요구사항을 구현하기 위해 필요한 요소 중 필수적인 항목은 다음과 같은 것들이 있을 것입니다.

  • H.264 영상 파일로부터 데이터를 읽어 영상 데이터 스트림을 생성하는 Source Element
  • H.264 프레임을 VP9 프레임으로 Trans-coding 하기 위한 코덱 기능을 가진 Filter Element
  • VP9 프레임에 mp4 컨테이너를 씌워 파일로 저장해 주는 기능을 가진 Sink Element

멀티미디어 파이프라인을 구성해 본다면 다음과 같은 형태로 구성이 될 것입니다.

GStreamer 파이프라인 예제
GStreamer 파이프라인 예제

Jetson TX2 Transcoding Example

아래의 예제는 NVIDIA Jetson TX2 에서 구동할 수 있습니다. TX2 설치 방법(링크) 에 따라 설치하면 GStreamer 가 기본적으로 설치되어 있을 것입니다. 터미널을 열고 H.264 로 인코딩 되어 있는 영상 파일을 준비한 뒤 아래와 같이 인라인 파이프라인을 구동해 볼 수 있습니다.

$ gst-launch-1.0 \
> filesrc location=h264.mp4 ! \
> qtdemux name=demux demux.video_0 ! queue ! h264parse ! omxh264dec ! \
> omxvp9enc ! \
> matroskamux name=mux ! filesink location=vp9.mkv

살짝 복잡해 보이지만 어렵지.. 않다는 말이 잘 안나오네요. 어렵긴 합니다… 그렇지만 한 부분씩 살펴보겠습니다.

커맨드에 느낌표가 중간중간 들어 있는 것을 확인할 수 있습니다. gst-launch-1.0 은 인라인 파이프라인을 구동하기 위한 실행파일이고 이를 제외한 나머지 항목은 ! 를 기준으로 구분된 Element 의 묶음입니다.

Filesrc

Filesrc 는 GStreamer 에 기본탑재되어 있는 Source Plugin 입니다. GStreamer 에서는 Element를 구현한 단위 기능을 플러그인으로 부릅니다. Filesrc 는 특정 파일을 읽어서 데이터 스트림을 생성하는 기능을 합니다. Source 플러그인이기 때문에 파이프라인의 가장 앞단에 위치하고 있습니다.

Qtdemux

다른 포스트에서 잠깐 언급했었는데, demuxer는 single-input multi-output 신호 요소입니다. GStreamer에서도 유사한 기능을 합니다. Filesrc 로부터 데이터를 받아 트랙별로 분리하여 다음 플러그인에 데이터를 흘려보낼 수 있습니다. 예제에서는 video_0 트랙의 데이터만 추출해서 넘기고 있습니다.

H264parse / Omxh264dec

H.264 인코딩되어 있는 영상 스트림을 프레임으로 분리하고 디코딩합니다. Omxh264dec 는 NVIDIA H/W accelerated H.264 decoding 플러그인입니다.

Omxvp9enc

NVIDIA H/W accelerated VP9 encoding 플러그인입니다.

Filesink

Filesink 는 데이터 스트림을 파일로 저장하는 Sink 플러그인입니다. 데이터 스트림은 Filesink 에서 더 이상 흐르지 않고 소멸됩니다.

Conclusion

GStreamer 는 원래 멀티미디어를 처리하기 위하여 설계된 프레임워크입니다. NVIDIA 에서 DeepStream 을 디자인 할 때 GStreamer 의 파이프라인 및 플러그인 기반 구조를 차용하여 구현한 것은 매우 적절한 시도였다고 생각합니다. 딥러닝 추론 과정도 비교적 큰 멀티미디어 데이터의 흐름을 통해 실행되고 구체화되는 경우가 많기 때문입니다.

데이터의 흐름이라는 대전제 아래 필요한 부분에서는 플러그인을 통해 H/W 리소스를 사용할 수 있는 분리된 구조가 가지는 장점이 극대화될 수 있습니다. 그리고 사용자 개개인이나 개별 기업의 개발팀에서 니즈에 따른 기능을 구현하여 기존에 구축되어 있는 플러그인에 조합하여 사용할 수 있는 유연함, 확장성 등 장점이 많은 프레임워크인 것 같습니다.


Jay

Jay

S/W Engineer!!

0개의 댓글

답글 남기기

Avatar placeholder