본문 바로가기

GStreamer

Basic tutorial 3: Dynamic pipelines

https://gstreamer.freedesktop.org/documentation/tutorials/basic/dynamic-pipelines.html?gi-language=c 

 

Basic tutorial 3: Dynamic pipelines

Basic tutorial 3: Dynamic pipelines Please port this tutorial to python! Please port this tutorial to javascript! Goal This tutorial shows the rest of the basic concepts required to use GStreamer, which allow building the pipeline "on the fly", as informat

gstreamer.freedesktop.org

 

즉석에서 동적으로 파이프라인을 구성하는 방법에 대한 튜토리얼.

 

Example pipeline with two branches.

 

동적으로 파이프라인을 구성하는 이유.

demuxer는 컨테이너 파일에서 어떤 데이터를 생산하는지에 대한 정보를 데이터를 받기 전까지는 알지 못한다.

그래서 demuxer까지 파이프라인을 구축하여 실행하도록 설정하고 런타임에 컨테이너의 스트림 수와 종류에 대해 알 수 있게되면 source pad를 만든다.

스트림의 종류에 적합한 파이프라인의 나머지 엘리먼트를 생성한 demuxer source pad에 연결해준다.

 

 

Signals

아래는 data.source인 uridecodebin element에 “pad-added” signal을 붙이는 코드이다.

/* Connect to the pad-added signal */
g_signal_connect (data.source, "pad-added", G_CALLBACK (pad_added_handler), &data);

Signals 이름에 의해 식별되며 각각의 GObject는 고유한 signal들이 있다.

 

The callback

source element가 생산하는 데이터 정보를 알게되면 source pad들을 생성하고 이는 “pad-added” signal을 발동시킨다.

이 시점에서 callback이 호출된다.

//src : signal이 발동되는 GstElement
//new_pad : src element에 추가되는 GstPad, 우리가 링크하려고 하는 pad이다.
//data : callback을 signal에 연결할 때 제공한 포인터, 정보를 공유할 수 있다. 
static void pad_added_handler (GstElement *src, GstPad *new_pad, CustomData *data) {

 

gst_element_get_static_pad 메서드를 통해 sink pad를 추출한다.

GstPad *sink_pad = gst_element_get_static_pad (data->convert, "sink");

 

추출한 sink pad는 new_pad에 링크할 pad이다.

이전 튜토리얼에서는 element와 element를 연결하면 Gstreamer에서 알아서 적절한 pad를 골라 연결해줬다.

하지만 여기서는 pad들을 직접 연결하게된다.

 

 

 

/* Check the new pad's type */
new_pad_caps = gst_pad_get_current_caps (new_pad, NULL);
new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
new_pad_type = gst_structure_get_name (new_pad_struct);
if (!g_str_has_prefix (new_pad_type, "audio/x-raw"))
{
    g_print ("It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);
    goto exit;
}

예제에서 우리가 생성한 파이프라인은 오디오에 관련된 것이라 비디오를 생성하는 pad에는 연결할 수 가 없다.

그래서 new pad에서 나오는 데이터 타입을 체크할 필요가 있다.

 

 

 

/* Attempt the link */
ret = gst_pad_link (new_pad, sink_pad);
if (GST_PAD_LINK_FAILED (ret)) {
  g_print ("Type is '%s' but link failed.\n", new_pad_type);
} else {
  g_print ("Link succeeded (type '%s').\n", new_pad_type);
}

gst_pad_link() 메서드는 2개의 pad를 연결하는 것을 시도한다.

gst_element_link() 메서드와 마찬가지로 링크는 source에서 sink로 지정되어야하고

두 pad는 동일한 bin 또는 파이프라인에 있는 element의 pad여야 한다.

 

 

 

 

 

'GStreamer' 카테고리의 다른 글

Basic tutorial 2: GStreamer concepts Goal  (0) 2022.05.07