애플리케이션 개발자에게 GStreamer에서 가장 중요한 객체는 GstElement 객체입니다. Element는 미디어 파이프라인의 기본 구성 요소입니다. 여러분이 사용할 다양한 고급 구성 요소는 모두 GstElement에서 파생됩니다. 모든 decoder, encoder, demuxer, 그리고 비디오 또는 오디오 출력은 실제로 GstElement입니다.
Element 란?
애플리케이션 개발자의 경우 element는 블랙박스로 가장 잘 시각화됩니다. 한쪽 끝에 뭔가를 넣으면 element가 뭔가를 하고 다른 쪽에서 다른 것이 나옵니다. 예를 들어 decoder element의 경우 인코딩된 데이터를 넣으면 해당 element는 디코딩된 데이터를 출력합니다. 다음 챕터 (Pads and capabilities)에서는 element의 데이터 입력 및 출력과 이를 애플리케이션에서 설정하는 방법에 대해 자세히 알아봅니다.
Source elements
Source element는 파이프라인에서 사용할 데이터 (예를 들면 디스크 또는 사운드 카드에서 읽기)를 생성합니다. 아래 Source element의 이미지는 source element를 시각화한 것 입니다. 항상 element의 오른쪽에 source pad를 그립니다.

Source element는 데이터 입력를 허용하지 않으며 데이터를 생성만 합니다. Source pad (오른쪽)만 있으므로 위 이미지에서 이를 볼 수 있습니다. Source pad는 데이터만 생성할 수 있습니다.
Filters, convertors, demuxers, muxers and codecs
Filter 및 filter와 유사한 element에는 입력 및 출력 pad가 모두 있습니다. 입력(sink) pad에서 수신한 데이터에 대해 작동하고 출력(source) pad에 데이터를 제공합니다. 이러한 element의 예로는 volume element (filter), video scaler (convertor), 그리고 Ogg demuxer 또는 Vorbis decoder가 있습니다.
Filter와 같은 element는 source 또는 sink pad를 원하는 수만큼 가질 수 있습니다. 예를 들어, video demuxer는 하나의 sink pad와 여러 개의 (1-N) source pad (컨테이너 형식에 포함된 각 기본 스트림에 대해 하나씩)를 갖습니다. 반면에 decoder에는 source pad와 sink pad가 하나만 있습니다.

위의 filter element의 이미지는는 filter와 유사한 element를 시각화하여 보주고 있습니다. 이 특정 element에는 하나의 source pad와 하나의 sink pad가 있습니다. 입력 데이터를 수신하는 sink pad는 element 왼쪽에 표시됩니다. Source pad는 여전히 오른쪽에 있습니다.

위에서 보는 것 처럼 두 개 이상의 출력 pad가 있는 filter element의 이미지는 또 다른 filter와 유사한 element를 보여줍니다. 이 element에는 두 개 이상의 출력(source) pad가 있습니다. 그러한 element 중 하나의 예는 오디오와 비디오를 모두 포함하는 Ogg 스트림에 대한 Ogg demuxer일 수 있습니다. 하나의 source pad에는 기본 비디오 스트림이 포함되고, 다른 source pad에는 기본 오디오 스트림이 포함됩니다. Demuxer는 일반적으로 새 pad가 생성될 때 signal을 발생시킵니다. 그런 다음 애플리케이션 개발자는 signal handler에서 새로운 기본 스트림을 처리할 수 있습니다.
Sink elements
Sink element는 미디어 파이프라인의 마지막 지점입니다. 이 element들은 데이터를 받아들이지만 아무것도 생산하지 않습니다. 디스크 쓰기, 사운드 카드 재생 및 비디오 출력은 모두 sink element로 구현됩니다. 아래에 있는 sink element의 이미지에는 싱크 요소가 표시됩니다.

GstElement 생성
Element를 생성하는 가장 간단한 방법은 gst_element_factory_make()를 사용하는 것입니다. 이 함수는 새로 생성된 element의 factory 이름과 element 이름을 사용합니다. 예를 들어 element의 이름은 나중에 bin에서 element를 조회하는 데 사용할 수 있습니다. 이 이름은 디버그 출력에도 사용되며, NULL을 name 인수로 전달하여 고유한 기본 이름을 얻을 수 있습니다.
해당 element가 더 이상 필요하지 않으면 gst_object_unref()를 사용하여 참조를 해제해야 합니다. 이렇게 하면 element의 참조 횟수가 1씩 감소합니다. Element는 생성될 때 참조 횟수가 1입니다. 참조 횟수가 0으로 감소하면 element가 완전히 소멸 됩니다.
다음 예제 [1]은 fakesrc라는 factory name을 가진 source element를 element factory에서 생성하는 방법을 보여줍니다. 생성이 성공했는지 확인합니다. 확인한 후 요소의 참조를 취소합니다.
#include <gst/gst.h>
int
main (int argc,
char *argv[])
{
GstElement *element;
/* init GStreamer */
gst_init (&argc, &argv);
/* create element */
element = gst_element_factory_make ("fakesrc", "source");
if (!element) {
g_print ("Failed to create element of type 'fakesrc'\n");
return -1;
}
gst_object_unref (GST_OBJECT (element));
return 0;
}
gst_element_factory_make는 실제로 두 함수의 조합을 단축한 것입니다. GstElement 객체는 팩토리에서 생성됩니다. Element를 생성하려면 고유한 factory name을 사용하여 GstElementFactory 객체에 접근해야 합니다. 이는 gst_element_factory_find()를 사용하여 수행됩니다.
아래 코드는 fake data source인 fakesrc element를 생성하는 데 사용할 수 있는 factory를 획득하는 방법을 보여 주고 있습니다. 그리고 gst_element_factory_create() 함수는 획득한 element factory를 사용하여 주어진 이름 (아래 코드에서는 "source")을 가진 element를 생성합니다.
#include <gst/gst.h>
int
main (int argc,
char *argv[])
{
GstElementFactory *factory;
GstElement * element;
/* init GStreamer */
gst_init (&argc, &argv);
/* create element, method #2 */
factory = gst_element_factory_find ("fakesrc");
if (!factory) {
g_print ("Failed to find factory of type 'fakesrc'\n");
return -1;
}
element = gst_element_factory_create (factory, "source");
if (!element) {
g_print ("Failed to create element, even though its factory exists!\n");
return -1;
}
gst_object_unref (GST_OBJECT (element));
gst_object_unref (GST_OBJECT (factory));
return 0;
}
GObject 처럼 element 사용하기
GstElement는 표준 GObject 속성을 사용하여 구현되는 여러 속성을 가질 수 있습니다. 따라서 속성 값과 GParamSpecs을 질의 하거나 설정 하거나 또는 가져오는 일반적인 GObject 메서드가 지원됩니다.
모든 GstElement는 상위 GstObject로부터 최소한 하나의 속성인 "name" 속성을 상속 받습니다. 이는 gst_element_factory_make() 또는 gst_element_factory_create() 함수에 제공하는 이름입니다. gst_object_set_name 및 gst_object_get_name 함수를 사용하거나 아래 코드에서와 같이 GObject 속성 메커니즘을 사용하여 이 속성을 가져오고 설정할 수 있습니다.
#include <gst/gst.h>
int
main (int argc,
char *argv[])
{
GstElement *element;
gchar *name;
/* init GStreamer */
gst_init (&argc, &argv);
/* create element */
element = gst_element_factory_make ("fakesrc", "source");
/* get name */
g_object_get (G_OBJECT (element), "name", &name, NULL);
g_print ("The name of the element is '%s'.\n", name);
g_free (name);
gst_object_unref (GST_OBJECT (element));
return 0;
}
대부분의 플러그인은 구성에 대한 추가 정보를 제공하거나 element를 구성하기 위해 추가 속성을 제공합니다. gst-inspect는 특정 element의 속성을 질의하는 데 유용한 도구입니다. 또한 속성 내부 검사를 사용하여 속성의 기능과 속성이 지원하는 매개변수 유형 및 범위에 대한 간단한 설명을 제공합니다. gst-inspect에 대한 자세한 내용은 부록의 gst-inspect를 참조하세요.
GObject 속성에 대한 자세한 내용을 보려면 GObject 매뉴얼과 Glib 객체 시스템 소개를 읽어 보시기 바랍니다.
GstElement는 유연한 콜백 메커니즘으로 사용할 수 있는 다양한 GObject signal도 제공합니다. 여기에서도 gst-inspect를 사용하여 특정 element가 어떤 signal을 지원하는지 확인할 수 있습니다. Signal과 속성은 element와 애플리케이션이 상호 작용하는 가장 기본적인 방법입니다.
Element factory에 대한 추가 정보
이전 섹션에서는 이미 element의 인스턴스를 생성하는 방법으로 GstElementFactory 객체를 간략하게 소개했습니다. 그러나 element factory는 그 이상입니다. Element factory는 GStreamer 레지스트리에서 검색된 기본 타입이며 GStreamer가 생성할 수 있는 모든 플러그인과 element를 설명합니다. 즉, element factory는 autoplugger의 기능과 같은 자동화된 element 인스턴스화 및 사용 가능한 element 목록 생성에 유용합니다.
Factory를 사용하여 element에 대한 정보 얻기
gst-inspect와 같은 도구는 플러그인을 작성한 사람, descriptive name (및 shortname), rank 및 카테고리와 같은 element에 대한 몇 가지 일반적인 정보를 제공합니다. 카테고리는 이 element factory를 사용하여 생성할 수 있는 element의 타입을 가져오는 데 사용할 수 있습니다. 카테고리의 예로는 Codec/Decoder/Video (video decoder), Codec/Encoder/Video (video encoder), Source/Video (video generator), 그리고 Sink/Video (video output)가 있으며 이러한 모든 항목은 오디오에도 존재합니다. 물론, 그 다음에는 Codec/Demuxer와 Codec/Muxer 등이 있습니다. gst-inspect는 모든 factory 목록을 제공하고 gst-inspect <factory-name>은 위의 모든 정보와 그 이상을 보여줍니다.
#include <gst/gst.h>
int
main (int argc,
char *argv[])
{
GstElementFactory *factory;
/* init GStreamer */
gst_init (&argc, &argv);
/* get factory */
factory = gst_element_factory_find ("fakesrc");
if (!factory) {
g_print ("You don't have the 'fakesrc' element installed!\n");
return -1;
}
/* display information */
g_print ("The '%s' element is a member of the category %s.\n"
"Description: %s\n",
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)),
gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS),
gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_DESCRIPTION));
gst_object_unref (GST_OBJECT (factory));
return 0;
}
gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY)를 사용하여 GStreamer가 알고 있는 모든 element factory 목록을 얻을 수 있습니다.
Element에 어떤 pad가 포함될 수 있는지 알아내기
아마도 element factory의 가장 강력한 기능 중 하나는 실제로 element를 생성할 필요 없이 element가 생성할 수 있는 pad에 대한 전체 설명과 해당 pad의 기능(쉽게 말하면 어떤 유형의 미디어가 해당 pad를 통해 스트리밍할 수 있는지)을 메모리에 로드하지 않고도 포함하고 있다는 것입니다. 이는 encoder에 대한 codec 선택 목록을 제공하는데 사용되거나 미디어 플레이어에 대한 자동 연결 목적으로 사용될 수 있습니다. 현재의 모든 GStreamer 기반 미디어 플레이어와 autoplugger는 이러한 방식으로 작동합니다. 다음 챕터 (Pads and capabilities)에서 GstPad 및 GstCaps에 대해 배우면서 이러한 기능에 대해 자세히 살펴보겠습니다.
Element 연결
Source element를 0개 이상의 filter-like element와 마지막으로 sink element와 연결하여 미디어 파이프라인을 설정합니다. 데이터는 element를 통해 흐릅니다. 이것이 GStreamer의 미디어 처리의 기본 개념입니다.

이 세 가지 element를 연결함으로써 우리는 매우 간단한 element 체인을 만들었습니다. 이로 인해 source element의 출력이 filter-like element의 입력으로 사용됩니다. Filter-like element는 데이터를 전달받아 작업을 수행하고 결과를 최종 sink element로 보냅니다.
위 이미지를 간단한 Ogg/Vorbis 오디오 디코더로 상상해 보세요. Source는 디스크에서 파일을 읽는 디스크 소스입니다. 두 번째 element는 Ogg/Vorbis 오디오 디코더입니다. Sink element는 디코딩된 오디오 데이터를 재생하는 사운드 카드입니다. 이 간단한 이미지를 사용하여 이 챕터의 뒷부분에서 Ogg/Vorbis 플레이어를 구성할 것입니다.
코드에서 위 이미지는 다음과 같이 작성됩니다.
#include <gst/gst.h>
int
main (int argc,
char *argv[])
{
GstElement *pipeline;
GstElement *source, *filter, *sink;
/* init */
gst_init (&argc, &argv);
/* create pipeline */
pipeline = gst_pipeline_new ("my-pipeline");
/* create elements */
source = gst_element_factory_make ("fakesrc", "source");
filter = gst_element_factory_make ("identity", "filter");
sink = gst_element_factory_make ("fakesink", "sink");
/* must add elements to pipeline before linking them */
gst_bin_add_many (GST_BIN (pipeline), source, filter, sink, NULL);
/* link */
if (!gst_element_link_many (source, filter, sink, NULL)) {
g_warning ("Failed to link elements!");
}
[..]
}
보다 구체적인 동작을 위해 gst_element_link() 및 gst_element_link_pads() 함수도 있습니다. 또한 개별 pad에 대한 참조를 얻고 다양한 gst_pad_link_*() 함수를 사용하여 이를 연결할 수도 있습니다. 자세한 내용은 API 참조를 확인하세요.
중요: Element를 연결하기 전에 bin이나 파이프라인에 element를 추가해야 합니다. Bin에 element를 추가하면 기존 링크의 연결이 끊어지기 때문입니다. 또한 동일한 저장소나 파이프라인에 있지 않은 element를 직접 연결할 수 없습니다. 다른 계층 구조 수준의 element나 pad를 연결하려면 ghost pad를 사용해야 합니다(ghost pad에 대해서는 나중에 자세히 설명할 예정임).
Element States
Element가 생성된 후에는 실제로 아직 어떤 작업도 수행하지 않습니다. 무언가를 수행하려면 element 상태를 변경해야 합니다. GStreamer는 각각 매우 구체적인 의미를 지닌 네 가지 element 상태를 알고 있습니다. 그 네 가지 상태는 다음과 같습니다.
- GST_STATE_NULL: 기본 상태입니다. 이 상태에서는 리소스가 할당되지 않으므로 이 상태로 전환하면 모든 리소스가 해제됩니다. Element는 참조 횟수가 0에 도달하고 해제될 때 이 상태에 있어야 합니다.
- GST_STATE_READY: 준비 상태에서 element는 전역 리소스, 즉 스트림 내에서 보관할 수 있는 리소스를 모두 할당했습니다. 장치 열기, 버퍼 할당 등에 대해 생각할 수 있습니다. 그러나 이 상태에서는 스트림이 열리지 않으므로 스트림 위치는 자동으로 0이 됩니다. 이전에 스트림이 열려 있었다면 이 상태에서 스트림을 닫아야 하며, 위치, 속성 등을 재설정해야 합니다.
- GST_STATE_PAUSED: 이 상태에서는 element가 스트림을 열었지만 적극적으로 처리하고 있지 않습니다. Element는 스트림의 위치를 변경하고 데이터를 읽고 처리하는 등 상태가 PAUSED로 변경되는 즉시 재생을 준비할 수 있지만 시계를 실행하게 만드는 데이터를 재생할 수는 없습니다. 요약하면 PAUSED는 PLAYING과 동일하지만 실행 중인 시계가 없습니다.
- PAUSED 상태로 들어가는 element는 가능한 한 빨리 PLAYING 상태로 이동할 준비를 해야 합니다. 예를 들어 비디오 또는 오디오 출력은 데이터가 도착할 때까지 기다렸다가 상태 변경 직후 재생할 수 있도록 대기열에 넣습니다. 또한 비디오 sink는 이미 첫 번째 프레임을 재생할 수 있습니다(이는 아직 시계에 영향을 미치지 않기 때문입니다). Autoplugger는 이와 동일한 상태 전환을 사용하여 이미 파이프라인을 연결할 수 있습니다. 그러나 코덱이나 필터와 같은 대부분의 다른 element는 이 상태에서 명시적으로 어떤 작업도 수행할 필요가 없습니다.
- GST_STATE_PLAYING: PLAYING 상태에서 element는 시계가 이제 실행된다는 점을 제외하면 PAUSED 상태와 정확히 동일합니다.
gst_element_set_state() 함수를 사용하여 element의 상태를 변경할 수 있습니다. Element를 다른 상태로 설정하면 GStreamer는 내부적으로 모든 intermediate 상태를 순회합니다. 따라서 element를 NULL에서 PLAYING으로 설정하면 GStreamer는 내부적으로 그 element를 READY와 PAUSED 사이로 설정합니다.
GST_STATE_PLAYING으로 이동하면 파이프라인이 자동으로 데이터를 처리합니다. 어떤 형태로든 반복할 필요가 없습니다. 내부적으로 GStreamer는 이 작업을 대신 수행하는 스레드를 시작합니다. GStreamer는 또한 GstBus를 사용하여 파이프라인 스레드에서 애플리케이션 자체 스레드로 메시지를 전환하는 작업도 처리합니다. 자세한 내용은 Bus를 참조하세요.
Bin 또는 파이프라인을 특정 대상 상태로 설정하면, 상태 변경이 bin 또는 파이프라인 내의 모든 element에 자동으로 전파되므로 일반적으로 파이프라인을 시작하거나 종료하려면 최상위 파이프라인의 상태만 설정하면 됩니다. 그러나 이미 실행 중인 파이프라인에 element를 동적으로 추가하는 경우, "pad-added" 신호 콜백 내에서 gst_element_set_state() 또는 gst_element_sync_state_with_parent()를 사용하여 직접 원하는 대상 상태로 설정하는 것과 같은 처리가 필요 합니다.
- 이 예제의 코드는 문서에서 자동으로 추출되어 GStreamer tarball의 test/examples/manual 아래에 빌드됩니다.
원문: Elements (gstreamer.freedesktop.org)
Elements
Elements The most important object in GStreamer for the application programmer is the GstElement object. An element is the basic building block for a media pipeline. All the different high-level components you will use are derived from GstElement. Every de
gstreamer.freedesktop.org
'IT와 개발 > GStreamer Study' 카테고리의 다른 글
| Bus (1) | 2024.04.19 |
|---|---|
| Bins (1) | 2024.04.12 |
| GStreamer 초기화 (0) | 2024.03.29 |
| Application Development Manual: Foundations (1) | 2024.03.22 |
| 디자인 원칙 (0) | 2024.03.20 |