// basic-tutorial-1.c
#include <gst/gst.h>
int 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,
(GstMessageType)(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;
}
/* Initialize GStreamer */
gst_init (&argc, &argv);
gst_init (int* argc, char*** argv)
매개변수:
argc ([inout][allow-none])
응용 프로그램의 argc에 대한 포인터
argv ([inout][arraylength=argc][allow-none])
응용 프로그램의 argv에 대한 포인터
pipeline =
gst_parse_launch
("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
NULL);
GstElement * gst_parse_launch_full (
const gchar * pipeline_description,
GstParseContext * context,
GstParseFlags flags,
GError ** error)
GStreamer에서는 일반적으로 개별 요소를 수동으로 조합하여 pipeline을 구축하지만, 간단한 작업같은 경우엔 pipeline 구성을 자동으로 구축해주는 함수를 바로 호출하여 사용 가능합니다.
gst_parse_launch()는 pipeline의 텍스트 표현을 가져와 실제 pipeline으로 변환하는 편리한 함수입니다.
GStreamer은 멀티미디어(동영상, 음성 등)의 흐름을 제어하는 프레임워크이며, 이 흐름은 Source(the producer)에서 Sink(the consumer)로 향하여 모든 종류의 작업을 수행합니다. 이 과정에서 여러 중간 요소를 통과하게 되고, 상호 연결된 모든 요소의 집합을 파이프라인(Pipeline)이라고 합니다.
playbin은 source 및 sink의 역할을 하는 특수 요소이며 완전한 pipeline입니다. 즉, 내부적으로 미디어를 재생하는 데 필요한 모든 요소를 생성하고 연결해줍니다.
위의 코드는 텍스트 형태로 playbin과 pipeline에 입력될 비디오를 URI주소의 형태로 전해주고 있습니다.
playbin에 단 하나의 인자, URI로 전달하고 있는데 https://, http://, file:// 등의 형식으로 전달되어도 상관없으며, playbin은 적절한 source를 인스턴스화 하게 됩니다.
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
GstStateChangeReturn gst_element_set_state(
GstElement * element,
GstState state)
모든 GStreamer 요소에는 연결된 상태(e.g. Play, Pause, etc.)가 있습니다.
위 코드 예시에서는 pipeline을 PLAYING state로 설정함으로써 비디오가 재생됩니다.
매개변수:
element
상태를 변경할 GstElement
state
요소의 새로운 GstState
/* 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);
GstBus *gst_element_get_bus (GstElement * element)
GstMessage *gst_bus_timed_pop_filtered(
GstBus * bus,
GstClockTime timeout,
GstMessageType types)
해당 부분은 오류가 발생하거나 스트림의 끝이 발견될 때까지 기다립니다.
gst_element_get_bus()는 pipeline의 버스를 검색하고,
gst_bus_timed_pop_filtered()는 버스를 통해 error 또는 EOS(End-Of-Stream)을 수신할 때까지 차단됩니다.
미디어가 끝(EOS)에 도달하거나 오류가 발생하면 실행이 종료됩니다. 콘솔에서 control+C를 눌러 애플리케이션을 항상 중지할 수 있습니다.
/* 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;
인스턴스화한 pipeline과 bus 및 message는 작업이 끝나면 메모리 상에서 해제시켜주어야 합니다.
gst_bus_timed_pop_filtered()는 gst_message_unref()로 해제시키고, gst_element_get_bus()는 gst_object_unref()로 해제시킵니다.
pipeline은 해제시키기 전에 gst_element_set_state() 함수를 통해 NULL state로 설정을 하여 리로스도 메모리 상에서 해제할 수 있도록 합니다. 그리고 최종적으로 gst_object_unref(pipeline)으로 해제시키면서 프로그램이 종료됩니다.