mulll

[GStreamer] 기본 튜토리얼 1 - Hello World Screen을 띄어보자 본문

GStreamer

[GStreamer] 기본 튜토리얼 1 - Hello World Screen을 띄어보자

dongha 2023. 1. 7. 00:14

메인 페이지: https://mulll.tistory.com/23

 

출처: https://gstreamer.freedesktop.org/documentation/tutorials/basic/hello-world.html?gi-language=c

 

목표

 

개발환경을 설치하면 가장 먼저 Hello world를 출력해보듯이 GStreamer는 멀티미디어를 다루는 프레임워크이므로 샘플 비디오를 재생해본다.

 

C언어를 처음 배울 때, #include나 int main 등의 낯선 키워드들이 등장하지만 나중에는 어려운 내용이 아니게 느껴지는 것처럼 아래의 코드 양에 놀라지 않아도된다.

 

Hello world

 

GStreamer가 설치되어 있다면 basic-tutorial-1.c 파일을 생성하고 아래의 코드를 복사 붙여넣기 한다.

 

basic-tutorial-1.c

 

#include <gst/gst.h>

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif

int
tutorial_main (int argc, char *argv[])
{
  GstElement *pipeline;
  GstBus *bus;
  GstMessage *msg;

  /* Initialize GStreamer */
  gst_init (&argc, &argv);

  /* Build the pipeline */
  pipeline =
      gst_parse_launch
      ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
      NULL);

  /* Start playing */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* Wait until error or EOS */
  bus = gst_element_get_bus (pipeline);
  msg =
      gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
      GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

  /* See next tutorial for proper error message handling/parsing */
  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
    g_error ("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
        "variable set for more details.");
  }

  /* Free resources */
  gst_message_unref (msg);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;
}

int
main (int argc, char *argv[])
{
#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
  return gst_macos_main (tutorial_main, argc, argv, NULL);
#else
  return tutorial_main (argc, argv);
#endif
}

 

그 이후 아래의 명령을 입력하여 컴파일을 수행한다.

 

gcc basic-tutorial-1.c -o basic-tutorial-1 `pkg-config --cflags --libs gstreamer-1.0`


# 실행
./basic-tutorial-1

 

아래와 같이 새로운 영상이 재생되면 실행에 성공한 것이다. 이전 GStreamer 설치 포스팅을 보고 테스트 코드를 실행해보았다면 사실 똑같은 코드인 것을 알아차렸을 것이다.

 

 

Walkthrough / 하나하나씩 코드의 역할을 해석해보자.

 

gst_init()

 

  /* Initialize GStreamer */
  gst_init (&argc, &argv);
  • 가장 처음에 초기화되어야하는 함수이다.
  • 모든 GStreamer 내부 구조를 초기화한다.
  • gstreamer와 관련되어 실행 시 command line option으로 주었던 옵션을 실행한다.
  • argc와 argv를 생략하고 실행하였다면 자동으로 기본 옵션이 gst_init() 시에 적용된다.

 

 

gst_parse_launch()

 

GStreamer는 멀티미디어의 플로우를 다루기 위한 프레임워크이다. 미디어(Media)는 "source" elements 부터 "sink" elements로 이동한다. 이동을 하면서 각각의 기능을 수행하는 중간 요소(intermediate elements)를 거치게된다. 이렇게 중간에 연결된 요소(elements)의 집합을 파이프라인(pipeline) 이라고 부른다.

 

GStreamer Framework를 이용하면 각각의 요소(element)들을 조합하여 pipeline을 build 할 수 있다. 그러나 pipeline이 간단하고, 고급 기능이 필요하지 않으면 gst_parse_launch() 를 이용하여 쉽게 코드를 구성할 수 있다.

 

이 기능은 그냥 편하게 텍스트 표현만을 통해 파이프라인을 실제로 구성할 수 있다.

 

playbin

 

우리가 gst_parse_launch()에 어떻게 파이프라인을 구성하도록 요청할 수 있을까?

 

우리는 playbin이 라는 하나의 element를 구성할 것이다. playbin은 source 처럼 그리고 sink 처럼역할을 하는 특별한 element이며 하나의 pipeline 이다.

 

이 pipeline은 세분화하여 제어될 수 없지만 다양한 application에 충분히 커스터마이징될 수 있다.

 

이 튜토리얼에선 우리는 오로지 하나의 파라미터를 playbin에 준다. 이 파라미터는 우리가 실행시키고 싶은 미디어의 URI이다. 다른 http:// 또는 file:// URI로 바꾸는 것도 가능하며 playbin은 투명하게 적절한 GStreamer source를 인스턴스화할 것이다.

 

  /* Build the pipeline */
  pipeline =
      gst_parse_launch
      ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
      NULL);

 

모든 GStreamer element들은 연관된 상태(state)를 가진다. DVD Player에 Play / Pause 버튼이 있는 것을 쉽게 생각해볼 수 있다. 여기선, PLAYING 상태로 set 되기까지는 미디어가 실행되지 않을 것이다.

 

get_element_set_state()

 

다음 줄에 get_element_set_state() 는 pipeline을 실행 상태(PLAYING State)로 설정해주며 이제는 State를 set 해주면서 실행이 가능해진다.

 

  /* Start playing */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

 

 

이번 줄은 error가 발생하거나 stream이 끝난 경우까지 기다린다.

 

  /* Wait until error or EOS */
  bus = gst_element_get_bus (pipeline);
  msg =
      gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
      GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
      
      
  /* See next tutorial for proper error message handling/parsing */
  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
    g_error ("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
        "variable set for more details.");
  }

 

gst_element_get_bus(): pipeline의 버스를 가지고온다.

gst_bus_timed_pop_filtered(): pipline 버스에서 ERROR나 EOS(End of Stream) 을 수신할 때까지 차단된다.

 

(다음 튜토리얼에서 자세하게 설명된다.)

 

이 코드로부터 pipeline 실행은 미디어가 끝에 도달하거나 error가 발생하면 끝난다. 또한 실행 중인 콘솔에 control-C를 입력하여도 pipeline의 실행은 끝난다.

 

 

Cleanup code

 

  /* Free resources */
  gst_message_unref (msg);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;

 

gst_bus_timed_pop_filtered() 함수는 message를 return 하는데 gst_message_unref()에서 메모리 할당을 해제해줘야하는 것들을 포함한다.

 

gst_element_get_bus() 함수 또한 비슷하게 gst_object_unref()에서 free 되어야하하는 것들의 정보가 담겨있다.

 

또한 프로세스가 종료되기 전, pipeline의 state를 지우고 pipeline 리소스를 모두 free 한다.

 

 

Conclusion

 

이번 튜토리얼을 통해 학습한 내용을 되돌아보면 다음과 같다.

  • 어떻게 GStreamer를 gst_init()을 통해 초기화하는가?
  • 어떻게 gst_parse_launch()를 통해 빠르게 pipeline을 구성하는가?
  • 어떻게 automatic playback pipeline을 playbin으로 생성하는가?
  • 어떻게 GStreamer에 gst_element_set_state()를 사용하여 playback 신호를 주는가?
  • 어떻게 gst_element_get_bus()gst_bus_timed_pop_filterd() 를 이용해 GStreamer를 편하게 다룰 수 있는가?

 

원문 보기: https://gstreamer.freedesktop.org/documentation/tutorials/basic/hello-world.html?gi-language=c 

 

Basic tutorial 1: Hello world!

Please port this tutorial to javascript! Basic tutorial 1: Hello world! Goal Nothing better to get a first impression about a software library than to print “Hello World” on the screen! But since we are dealing with multimedia frameworks, we are going

gstreamer.freedesktop.org

 

'GStreamer' 카테고리의 다른 글

[GStreamer] 기본 튜토리얼 2 - GStreamer 개념  (0) 2023.01.07
[GStreamer] Ubuntu 설치  (0) 2023.01.05
[GStreamer] MacOS 설치  (0) 2023.01.05
[GStreamer] GStreamer 이해하기  (0) 2023.01.05
Comments