본문 바로가기
IT와 개발/GStreamer Study

Playback Components

by 도서 임보자 2024. 7. 26.

GStreamer에는 애플리케이션 개발자의 삶을 단순화하기 위한 여러 가지 상위 수준 구성 요소가 포함되어 있습니다. 여기에서 논의된 모든 구성 요소 (현재)는 미디어 재생을 대상으로 합니다. 이러한 각 구성 요소의 아이디어는 GStreamer 파이프라인과 최대한 밀접하게 통합하는 것이지만 미디어 유형 감지의 복잡성과 Advanced GStreamer concepts[각주:1]에서 논의된 기타 다소 복잡한 주제를 숨기는 것입니다.

 

현재 필요에 따라 playbin (Playbin 참조) 또는 decodebin (Decodebin 참조)을 사용하는 것이 좋습니다. Playbin은 제대로 작동해야 하는 미디어의 간단한 재생과 관련된 모든 것에 권장되는 솔루션입니다. Decodebin은 재생 목록 지원, 오디오 트랙의 crossfading 등과 같은 고급 기능을 추가하는 데 사용할 수 있는 보다 유연한 autoplugger 입니다. 하지만 프로그래밍 인터페이스는 playbin보다 낮은 수준입니다.

 

Playbin

Playbin은 표준 GStreamer API (예: gst_element_factory_make())를 사용하여 생성할 수 있는 element입니다. 이 factory는 편의상 'playbin'이라고 불립니다. GstPipeline (및 GstElement)이 됨으로써 playbin은 오류 처리, 태그 지원, 상태 처리, 스트림 위치 가져오기, 검색 등을 포함하여 이 클래스의 모든 기능을 자동으로 지원합니다.


Playbin 파이프라인 설정은 playbin element의 인스턴스를 생성하고 playbin의 "uri" 속성을 사용하여 파일 위치를 설정한 다음 해당 element를 GST_STATE_PLAYING 상태로 설정하는 것만큼 간단합니다. (Location은 유효한 URI여야 합니다. "<protocol>://<location>", 예: file:///tmp/my.ogg 또는 http://www.example.org/stream.ogg) 내부적으로 playbin은 미디어 위치를 재생하기 위한 파이프라인을 설정합니다.

#include <gst/gst.h>

[.. my_bus_callback goes here ..]

gint
main (gint   argc,
      gchar *argv[])
{
  GMainLoop *loop;
  GstElement *play;
  GstBus *bus;

  /* init GStreamer */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* make sure we have a URI */
  if (argc != 2) {
    g_print ("Usage: %s <URI>\n", argv[0]);
    return -1;
  }

  /* set up */
  play = gst_element_factory_make ("playbin", "play");
  g_object_set (G_OBJECT (play), "uri", argv[1], NULL);

  bus = gst_pipeline_get_bus (GST_PIPELINE (play));
  gst_bus_add_watch (bus, my_bus_callback, loop);
  gst_object_unref (bus);

  gst_element_set_state (play, GST_STATE_PLAYING);

  /* now run */
  g_main_loop_run (loop);

  /* also clean up */
  gst_element_set_state (play, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (play));

  return 0;
}

 

Playbin에는 이전에 논의된 몇 가지 기능이 있습니다.

  • 설정 가능한 비디오 및 오디오 출력 ("video-sink" 및 "audio-sink" 속성 사용)

  • 오류 처리, EOS 처리, 태그 처리, 상태 처리 (GstBus를 통한), 미디어 위치 처리 및 검색을 포함하여 대부분 GstElement로 제어 및 추적 가능합니다.

  • GstBus를 통해 전달되는 buffer fullness 알림과 함께 network-source를 버퍼링합니다.

  • Audio-only 미디어에 대한 시각화를 지원합니다.

  • 미디어와 별도 파일 모두에서 자막을 지원합니다. 별도의 자막 파일은 “suburi” 속성을 사용하세요.

  • 스트림 선택 및 비활성화를 지원합니다. 미디어에 오디오 또는 자막 트랙이 여러 개 있는 경우 재생할 트랙을 동적으로 선택하거나 완전히 끄기로 결정할 수 있습니다 (자막을 끄는 데 특히 유용함). 각각에 대해 "current-text" 및 기타 관련 속성을 사용하십시오.

편의상 "gst-launch-1.0 playbin uri=file:///path/to/file" 명령을 사용하여 커맨드라인에서 "playbin"을 테스트할 수 있습니다.

 

Decodebin

Decodebin은 이전 섹션에서 논의한 playbin의 실제 autoplugger 백엔드입니다. 간단히 말해서 Decodebin은 sinkpad에 연결된 source로부터 입력을 받아들이고 스트림에 포함된 미디어 유형을 감지하고 각각에 대한 디코더 루틴을 설정하려고 시도합니다. 디코더가 자동으로 선택됩니다. 각 디코딩된 스트림에 대해 클라이언트에게 새로 발견된 디코딩된 스트림에 대해 알리기 위해 "pad-added" 신호를 내보냅니다. 알 수 없는 스트림 (전체 스트림일 수 있음)의 경우 "unknown-type" 신호를 내보냅니다. 그런 다음 애플리케이션은 사용자에게 오류를 보고하는 역할을 담당합니다.

#include <gst/gst.h>


[.. my_bus_callback goes here ..]



GstElement *pipeline, *audio;

static void
cb_newpad (GstElement *decodebin,
       GstPad     *pad,
       gpointer    data)
{
  GstCaps *caps;
  GstStructure *str;
  GstPad *audiopad;

  /* only link once */
  audiopad = gst_element_get_static_pad (audio, "sink");
  if (GST_PAD_IS_LINKED (audiopad)) {
    g_object_unref (audiopad);
    return;
  }

  /* check media type */
  caps = gst_pad_query_caps (pad, NULL);
  str = gst_caps_get_structure (caps, 0);
  if (!g_strrstr (gst_structure_get_name (str), "audio")) {
    gst_caps_unref (caps);
    gst_object_unref (audiopad);
    return;
  }
  gst_caps_unref (caps);

  /* link'n'play */
  gst_pad_link (pad, audiopad);

  g_object_unref (audiopad);
}

gint
main (gint   argc,
      gchar *argv[])
{
  GMainLoop *loop;
  GstElement *src, *dec, *conv, *sink;
  GstPad *audiopad;
  GstBus *bus;

  /* init GStreamer */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* make sure we have input */
  if (argc != 2) {
    g_print ("Usage: %s <filename>\n", argv[0]);
    return -1;
  }

  /* setup */
  pipeline = gst_pipeline_new ("pipeline");

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, my_bus_callback, loop);
  gst_object_unref (bus);

  src = gst_element_factory_make ("filesrc", "source");
  g_object_set (G_OBJECT (src), "location", argv[1], NULL);
  dec = gst_element_factory_make ("decodebin", "decoder");
  g_signal_connect (dec, "pad-added", G_CALLBACK (cb_newpad), NULL);
  gst_bin_add_many (GST_BIN (pipeline), src, dec, NULL);
  gst_element_link (src, dec);

  /* create audio output */
  audio = gst_bin_new ("audiobin");
  conv = gst_element_factory_make ("audioconvert", "aconv");
  audiopad = gst_element_get_static_pad (conv, "sink");
  sink = gst_element_factory_make ("alsasink", "sink");
  gst_bin_add_many (GST_BIN (audio), conv, sink, NULL);
  gst_element_link (conv, sink);
  gst_element_add_pad (audio,
      gst_ghost_pad_new ("sink", audiopad));
  gst_object_unref (audiopad);
  gst_bin_add (GST_BIN (pipeline), audio);

  /* run */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_main_loop_run (loop);

  /* cleanup */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}

 

Playbin과 유사한 Decodebin은 다음 기능을 지원합니다.

  • 포함된 스트림을 무제한으로 디코딩하여 output pad로 디코딩할 수 있습니다.

  • 태그 또는 오류 전달 및 상태 처리를 포함하여 모든 방식으로 GstElement로 처리됩니다.

Decodebin은 좋은 autoplugger이지만 수행하지 않거나 의도하지 않은 작업이 많이 있습니다.

  • 알려진 미디어 유형 (예: DVD, 오디오 CD 등)을 사용하여 입력 스트림을 관리합니다.

  • 스트림 선택 (예: 다국어 미디어 스트림의 경우 재생할 오디오 트랙)

  • 디코딩된 비디오 스트림에 자막을 오버레이합니다.

Decodebin은 커맨드라인에서 쉽게 테스트할 수 있습니다. gst-launch-1.0 filesrc location=file.ogg ! decodebin ! audioconvert ! audiosample ! autoaudiosink 명령을 사용하세요.

 

URIDecodebin

URIDecodebin element는 decodebin과 매우 유사하지만 주어진 URI의 프로토콜을 기반으로 source plugin을 자동으로 연결한다는 점만 다릅니다.


URIDecodebin은 URI가 느린 네트워크 source인 경우 자동으로 버퍼링 element를 삽입합니다. 버퍼링 element는 Buffering에 설명된 대로 애플리케이션이 처리해야 하는 BUFFERING 메시지를 게시합니다. 다음 속성을 사용하여 버퍼링 방법을 구성할 수 있습니다.

  • buffer-size 속성을 사용하면 버퍼 element의 최대 크기 (바이트)를 구성할 수 있습니다.

  • buffer-duration 속성을 사용하면 버퍼 element의 최대 크기를 시간에 따라 구성할 수 있습니다. 시간은 네트워크의 bitrate를 기준으로 추정됩니다.

  • 다운로드 속성을 사용하면 Download buffering에 설명된 대로 download buffering 방법을 활성화할 수 있습니다. 이 옵션을 TRUE로 설정하면 Quicktime, Flash 비디오, avi 및 webm과 같은 선택된 형식에 대해서만 다운로드 버퍼링이 활성화됩니다.

  • use-buffering 속성을 사용하여 parsed/demuxed 데이터에 대한 버퍼링을 활성화할 수도 있습니다. 네트워크 파일 서버와 같은 slower random access 미디어에서 버퍼링을 활성화하는 것은 흥미로운 일입니다.

URIDecodebin은 커맨드라인에서 쉽게 테스트할 수 있습니다. gst-launch-1.0 uridecodebin uri=file:///file.ogg ! audioconvert ! audioresample ! autoaudiosink 명령을 사용하세요.

 

Playsink

Playsink element는 강력한 sink element입니다. Raw decoded 오디오, 비디오 및 텍스트에 대한 request pad가 있으며 미디어 스트림을 재생하도록 자체 구성됩니다. 다음과 같은 기능이 있습니다.

  • GstStreamVolume, GstVideoOverlay, GstNavigation 및 GstColorBalance 인터페이스를 노출하고 필요할 때 인터페이스를 구현하기 위해 소프트웨어 element를 자동으로 연결합니다.

  • Conversion element를 자동으로 연결합니다.

  • 비디오 입력이 없을 때 선택적으로 시각화를 렌더링할 수 있습니다.

  • Sink element를 구성 할 수 있습니다.

  • Badly muxed 파일의 동기화를 미세 조정하기 위해 오디오/비디오 동기화 오프셋이 구성 가능 합니다.

  • 마지막 비디오 프레임의 스냅샷 촬영을 지원합니다.

다음은 playsink를 사용하는 방법의 예입니다. 우리는 uridecodebin element를 사용하여 raw 오디오 및 비디오 스트림으로 디코딩한 다음 playsink request pad에 연결합니다. 첫 번째 오디오 및 비디오 pad만 연결하므로 input-selector를 사용하여 모든 pad를 연결할 수 있습니다.

#include <gst/gst.h>


[.. my_bus_callback goes here ..]





GstElement *pipeline, *sink;

static void
cb_pad_added (GstElement *dec,
          GstPad     *pad,
          gpointer    data)
{
  GstCaps *caps;
  GstStructure *str;
  const gchar *name;
  GstPadTemplate *templ;
  GstElementClass *klass;

  /* check media type */
  caps = gst_pad_query_caps (pad, NULL);
  str = gst_caps_get_structure (caps, 0);
  name = gst_structure_get_name (str);

  klass = GST_ELEMENT_GET_CLASS (sink);

  if (g_str_has_prefix (name, "audio")) {
    templ = gst_element_class_get_pad_template (klass, "audio_sink");
  } else if (g_str_has_prefix (name, "video")) {
    templ = gst_element_class_get_pad_template (klass, "video_sink");
  } else if (g_str_has_prefix (name, "text")) {
    templ = gst_element_class_get_pad_template (klass, "text_sink");
  } else {
    templ = NULL;
  }

  if (templ) {
    GstPad *sinkpad;

    sinkpad = gst_element_request_pad (sink, templ, NULL, NULL);

    if (!gst_pad_is_linked (sinkpad))
      gst_pad_link (pad, sinkpad);

    gst_object_unref (sinkpad);
  }

  gst_clear_caps (&caps);
}

gint
main (gint   argc,
      gchar *argv[])
{
  GMainLoop *loop;
  GstElement *dec;
  GstBus *bus;

  /* init GStreamer */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* make sure we have input */
  if (argc != 2) {
    g_print ("Usage: %s <uri>\n", argv[0]);
    return -1;
  }

  /* setup */
  pipeline = gst_pipeline_new ("pipeline");

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, my_bus_callback, loop);
  gst_object_unref (bus);

  dec = gst_element_factory_make ("uridecodebin", "source");
  g_object_set (G_OBJECT (dec), "uri", argv[1], NULL);
  g_signal_connect (dec, "pad-added", G_CALLBACK (cb_pad_added), NULL);

  /* create audio output */
  sink = gst_element_factory_make ("playsink", "sink");
  gst_util_set_object_arg (G_OBJECT (sink), "flags",
      "soft-colorbalance+soft-volume+vis+text+audio+video");
  gst_bin_add_many (GST_BIN (pipeline), dec, sink, NULL);

  /* run */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_main_loop_run (loop);

  /* cleanup */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}

 

이 예는 사용자가 제공한 내용에 따라 오디오 및 비디오를 표시합니다. 오디오 파일에 대해 이 예를 시도해 보면 시각화가 표시되는 것을 볼 수 있습니다. vis-plugin 속성을 변경하여 런타임 시 시각화를 변경할 수 있습니다.

 

 

원문: Playback Components (gstreamer.freedesktop.org)

 

Playback Components

Playback Components GStreamer includes several higher-level components to simplify an application developer's life. All of the components discussed here (for now) are targetted at media playback. The idea of each of these components is to integrate as clos

gstreamer.freedesktop.org

 

반응형

'IT와 개발 > GStreamer Study' 카테고리의 다른 글

Things to check when writing an application  (0) 2024.08.09
Programs  (1) 2024.08.02
Pipeline manipulation  (0) 2024.07.19
Autoplugging  (2) 2024.07.05
Threads  (1) 2024.06.28