Graphics And Media/GStreamer

Getting started GStreamer : Hello wolrd

kahuz 2021. 5. 28. 19:23

 

Getting started GStremaer 는 freedesktop의 gstreamer 예제에 대해 번역 및 참고하여 개발해보았을때 필요하다고 느꼈던 내용 들을 아주 살짝 추가/제거하여 작성했습니다.  https://gstreamer.freedesktop.org/documentation/tutorials/basic

GStreamer

개념

스트리밍 미디어 어플리케이션을 만들기 위한 프레임워크 디비오 파이프라인 개념과 다이렉트쇼의 몇가지 아이디어로 시작됨

MP3, Ogg/Vorbis, MPEG-1/2, AVI, Quicktime, mod 등과 같은 다양한 포맷을 지원하는 미디어 플레이어를 만들 수 있는 컴포넌트를 포함하고 있다.

GStreamer는 다양한 코덱과 기능을 제공하는 플러그인을 기반으로한다. 플러그인은 파이프라인으로 연결/배열되며 데이터의 흐름을 정의한다.

GStreamer의 플러그인

  • 프로토콜 핸들링
  • 오디오 비디오를 위한 소스
  • 파서, 포매터, 먹서, 디먹서, 메타데이터, 자막과 같은 포맷들
  • 코덱과 디코더
  • 컨버터, 믹서, 효과 등의 필터
  • 오디오와 비디오를 위한 싱크

GStreamer 패키지

  • gstreamer : 핵심 패키지
  • gst-plugins-base : 핵심적인 본보기 엘리먼트의 집합
  • gst-plugins-good : LGPL을 따르는 양질의 플러그인 집합
  • gst-plugins-ugly : 배포 문제를 야기할 수 있는 양질의 플러그인 집합
  • gst-plugins-bad : 질이 부족한 플러그인의 집합
  • gst-libav : 디코딩과 인코딩을 위해 libav로 포장된 플러그인의 집합
  • 그 외 등등

Getting started GStreamer

본 글의 예제는 freedesktop에서 제공하는 GStreamer 튜토리얼을 바탕으로 진행됩니다. 전반적인 내용은 튜토리얼을 따랐으며, 약간의 첨언 및 번역만을 제공할 뿐입니다. 예제 코드는 다음 깃 명령어를 통해 얻을 수 있습니다.

git clone https://gitlab.freedesktop.org/gstreamer/gst-docs

1) Hello world!

목표

소프트웨어 라이브러리를 시작하면서 Hello Wolrd를 출력하는 예제들을 많이 보았을 겁니다. 하지만 우리가 다루는 라이브러리는 멀티미디어 프레임워크이기에 비디오를 재생하는 것으로 대신할 생각입니다.

예제에 앞서 코드의 양에 겁먹을 필요가 없다는 것을 당부 드립니다. 실제 작업을 수행하는 줄은 4줄 밖에 되지 않는다. 나머지는 정리 코드이며 C를 기반으로 하여 장황하게 나열 됐을 뿐입니다.

이 튜토리얼은 윈도우를 생성하고 오디오와 함께 영화를 표시합니다. 미디어는 인터넷에서 가져오게 되어있으므로, 연결 속도에 따라 창이 나타나는데 수 초가 걸릴 수 있습니다. 또한 대기 시간 관리( 버퍼링 ) 이 없으므로 연결이 느린 경우 몇 초 후에 영화가 중지될 수 있습니다. 12) 스트리밍 에서 문제해결 방법을 찾을 수 있습니다.

예제

gst_init( int *argc, char*** argv) GStreamer 라이브러리를 초기화하고 내부 경로 목록을 설정, 내장 엘레멘트를 등록하고 표준 플로그인을 로드하는 함수.

프로그램 명령 인자 argv를 이용해 GStreamer 표준 커맨드 옵션을 사용할 수 있습니다. ( 10) GStreamer 도구 를 참고 )

GstElement * gst_parse_launch (const gchar * pipeline_description, GError ** error) GStreamer 표준 커맨드라인을 기반으로 파이프라인을 생성하는 함수. 만약 파이프라인을 생성할 수 없는 경우 NULL을 반환합니다.

GStreamer는 멀티미디어 흐름을 처리하도록 설계된 프레임 워크입니다. 미디어는 src 엘레멘트 (생산자)에서 sink엘레멘트(소비자)로 이동하여 모든 종류의 작업을 수행하는 일련의 중간 엘레멘트를 통과합니다. 상호 연결된 모든 엘레멘트의 집합을 pipeline이라고 합니다.

GStreamer에서는 일반적으로 개별 엘레멘트를 수동으로 어셈블하여 파이프라인을 빌드하지만 파이프라인이 충분히 쉽고 고급 기능을 필요로하지 않는 경우 gst_parse_launch()를 사용할 수 있습니다.

이 함수는 파이프라인의 텍스트 표현을 가져 와서 실제 파이프라인으로 변환하므로 매우 편리합니다. ( 10) GStreamer 도구 를 참고 )

playbin 본 예제에서는 playbin 이라는 단일 엘레멘트로 구성된 파이프라인을 구축하고 있습니다 ( pipeline = gst_parse_launch ("playbin uri=...", NULL);) playbin은 소스 및 싱크 역할을 하는 특수 엘레멘트이며 전체 파이프 라인입니다. 내부적으로는 미디어를 재생하는데 필요한 모든 엘레멘트를 만들고 연결하므로 상세한 내용을 신경 쓸 필요가 없습니다. 단, 수동 파이프라인이 수행할 수 있는 제어 세분성을 허용하지는 않습니다.

이 예제에서 재생하려는 미디어의 URI는 playbin uri=... 를 통해 정의할 수 있습니다. playbin의 다양한 사용 방법을 알고 싶다면 https://gstreamer.freedesktop.org/documentation/playback/playbin.html?gi-language=c 를 참고하시기 바랍니다. ( ex : playbin uri=file:///video_path.avi 를 이용한 로컬 비디오 파일 실행 )

GstStateChangeReturn gst_element_set_state (GstElement * element, GstState state) GStreamer의 엘레멘트에 상태를 정의하는 함수입니다. 본 예제에서는 playbin 엘레멘트의 플레이 상태를 정의하고 있습니다. (gst_element_set_state (pipeline, GST_STATE_PLAYING);)

예제 코드를 수정하지 않고 컴파일하여 실행할 경우 URI에 정의된 미디어가 바로 시작되는 것을 알 수 있습니다. 예제코드 내용을 다음과 같이 수정하고 컴파일하여 실행하여 보세요.

gst_element_set_state (pipeline, GST_STATE_PAUSED);

이 경우 미디어가 실행되지 않고 윈도우만 생성되는 것을 확인할 수 있을 겁니다. 따라서 GstState 값을 참고하여 미디어 플레이어의 상태를 제어할 수 있다는 것을 알 수 있습니다.

# wait until EOS or error
bus = pipeline.get_bus()
msg = bus.timed_pop_filtered(
    Gst.CLOCK_TIME_NONE,
    Gst.MessageType.ERROR | Gst.MessageType.EOS
)

위 코드는 오류가 발생하거나 스트림의 끝을 찾을 때까지 대기합니다. gst_element_get_bus()는 파이프라인의 버스를 검색하고 gst_bus_timed_pop_filtered()는 호출 대상의 BUS를 통해 ERROR 또는 `End-Of-Stream)을 수신할 때까지 차단됩니다. 위 코드에 대해서는 다음 장 2) 사용자 정의 파이프 라인 생성 에서 다시 한번 설명하겠습니다.

결론

자, 이제 Hello World 예제가 끝이 났습니다. 프로그램이 실행하면 GStreamer를 통해 미디어 재생이 됨을 확인할 수 있습니다. 미디어가 끝에 도달하거나 오류가 발생하면 실행이 종료되고, 콘솔에서 Ctrl+C를 통해 프로그램을 종료할 수 있습니다.

우리는 이번 예제를 통해 다음 내용을 배울 수 있었습니다.

  • gst_init ()를 사용하여 GStreamer를 초기화하는 방법 .
  • gst_parse_launch ()를 사용하여 파이프 라인을 빠르게 빌드하는 방법 .
  • playbin 을 사용하여 자동 재생 파이프 라인을 만드는 방법 .
  • gst_element_set_state ()를 사용하여 재생을 시작하도록 GStreamer에 신호를 보내는 방법 .
  • GStreamer가 gst_element_get_bus () 및 gst_bus_timed_pop_filtered ()를 사용하여 모든 것을 처리하는 동안 미디어를 즐기는 방법.

다음 예제에서는 더 많은 기본 GStreamer 엘레멘트를 계속 소개하고 자동으로 생성된 파이프라인이 아닌 개발자가 임의로 파이프 라인을 빌드하는 방법을 보여줍니다.