[GStreamer] Tutorial 튜토리얼 정리
FFmpeg, GStreamer, VLC 2026. 4. 16. 09:06 |반응형
Basic tutorial 1: Hello world!
#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://gstreamer.freedesktop.org/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));
// GST_MESSAGE_ERROR, GST_MESSAGE_EOS 는 GstMessageType 열거형의 멤버로, 각각 오류 메시지와 End Of Stream 메시지를 나타낸다.
// GstMessageType으로 형변환 해야한다.
// gst_bus_timed_pop_filtered 함수는 버스에서 지정된 유형의 메시지를 기다리고, 해당 메시지가 도착하면 반환한다.
// GST_CLOCK_TIME_NONE는 무한 대기 시간을 의미한다. 따라서 이 코드는 오류나 EOS 메시지가 도착할 때까지 기다린다.
/* See next tutorial for proper error message handling/parsing */
if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR) {
g_printerr("An error occurred! Re-run with the GST_DEBUG=*:WARN environment variable set for more details.\n");
}
/* Free resources */
gst_message_unref(msg);
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}
playbin uri에 IP 카메라 스트리밍 주소(RTSP)를 넣어도 잘 작동하지만 파이프라인 최적화가 되지 않아 반응이 느리다.
pipeline = gst_parse_launch("playbin uri=rtsp://admin:admin@192.168.0.92:554/stream1", NULL);

Basic tutorial 12: Streaming
#include <gst/gst.h>
#include <string.h>
typedef struct _CustomData {
gboolean is_live;
GstElement* pipeline;
GMainLoop* loop;
} CustomData;
static void cb_message(GstBus* bus, GstMessage* msg, CustomData* data) {
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_ERROR: {
GError* err = NULL;
gchar* debug = NULL;
gst_message_parse_error(msg, &err, &debug);
g_print("Error: %s\n", err->message);
g_error_free(err);
g_free(debug);
gst_element_set_state(data->pipeline, GST_STATE_READY);
g_main_loop_quit(data->loop);
break;
} // case 내부에서 변수를 선언하고 초기화할 때는 중괄호로 감싸줘야 한다.
case GST_MESSAGE_EOS:
/* end-of-stream */
gst_element_set_state(data->pipeline, GST_STATE_READY);
g_main_loop_quit(data->loop);
break;
case GST_MESSAGE_BUFFERING: {
gint percent = 0;
/* If the stream is live, we do not care about buffering. */
if (data->is_live)
break;
gst_message_parse_buffering(msg, &percent);
g_print("Buffering (%3d%%)\r", percent);
/* Wait until buffering is complete before start/resume playing */
if (percent < 100)
gst_element_set_state(data->pipeline, GST_STATE_PAUSED);
else
gst_element_set_state(data->pipeline, GST_STATE_PLAYING);
break;
} // case 내부에서 변수를 선언하고 초기화할 때는 중괄호로 감싸줘야 한다.
case GST_MESSAGE_CLOCK_LOST:
/* Get a new clock */
gst_element_set_state(data->pipeline, GST_STATE_PAUSED);
gst_element_set_state(data->pipeline, GST_STATE_PLAYING);
break;
// GST_MESSAGE_CLOCK_LOST: The current clock, as selected by the pipeline,
// became unusable. The pipeline will select a new clock on the next PLAYING
// state change.
// GStreamer에서 GST_MESSAGE_CLOCK_LOST 메시지는 파이프라인에서 현재 사용 중인
// 클럭(Clock)을 더 이상 사용할 수 없게 되었을 때 발생한다. 이 메시지는 주로 다음과
// 같은 상황에서 나타난다.
// - 현재 클럭 제공자 유실: 파이프라인의 시간 기준(Master Clock)을 제공하던 요소
// (예: 오디오 싱크, 오디오 소스 등)가 더 이상 클럭을 제공할 수 없을 때 발생.
// - 새로운 소스 추가/변경: RTSP 스트림 추가 등 동적으로 파이프라인 소스가 변경되면서
// 기존 클럭이 유효하지 않게 된 경우.
// - 재생 상태 변경: 파이프라인이 재생(PLAYING) 상태에서 멈추거나 플러시(Flush)된 후
// 다시 시작할 때 클럭을 재선택해야 하는 상황.
default:
/* Unhandled message */
break;
}
}
int main(int argc, char* argv[]) {
GstElement* pipeline;
GstBus* bus;
GstStateChangeReturn ret;
GMainLoop* main_loop;
CustomData data;
/* Initialize GStreamer */
gst_init(&argc, &argv);
/* Initialize our data structure */
memset(&data, 0, sizeof(data));
/* Build the pipeline */
pipeline = gst_parse_launch("playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm", NULL);
//pipeline = gst_parse_launch("playbin uri=rtsp://admin:admin@192.168.0.92:554/stream1", NULL); // IP 카메라 스트림
bus = gst_element_get_bus(pipeline);
/* Start playing */
ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
// GST_STATE_CHANGE_FAILURE (0) – the state change failed
g_printerr("Unable to set the pipeline to the playing state.\n");
gst_object_unref(pipeline);
return -1;
}
else if (ret == GST_STATE_CHANGE_NO_PREROLL) {
// GST_STATE_CHANGE_NO_PREROLL (3) – the state change succeeded but the element cannot produce data in GST_STATE_PAUSED.
// This typically happens with live sources.
// IP 카메라 스트림과 같이 라이브 스트림을 재생할 때는 이 상태가 반환될 수 있다.
data.is_live = TRUE;
}
main_loop = g_main_loop_new(NULL, FALSE);
data.loop = main_loop;
data.pipeline = pipeline;
gst_bus_add_signal_watch(bus);
g_signal_connect(bus, "message", G_CALLBACK(cb_message), &data);
g_main_loop_run(main_loop);
/* Free resources */
g_main_loop_unref(main_loop);
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}
반응형
'FFmpeg, GStreamer, VLC' 카테고리의 다른 글
| [GStreamer] Application Development Manual - Your first application (1) | 2026.04.14 |
|---|---|
| [GStreamer] 간단한 설명 (0) | 2026.04.13 |
| Reason of RTSP Streaming with Delay and Pixelation 스트리밍과 딜레이 그리고 픽셀레이션(깍뚜기) 현상의 원인 (0) | 2026.04.08 |
| [VLC] LibVLCSharp 영상 재생 2 (feat. 간단한 동영상 플레이어) (0) | 2026.04.05 |
| [FFmpeg] Winform PictureBox 동영상 비트맵 재생 (0) | 2026.04.05 |
