728x90

이전 포스팅에 이어 Tutorial 2를 진행하면서 gstreamer의 기초 요소인 elements와 pipeline 등의 개념을 살펴봅니다.

 

Basic tutorial 2: GStreamer concepts

Please port this tutorial to javascript! Basic tutorial 2: GStreamer concepts Goal The previous tutorial showed how to build a pipeline automatically. Now we are going to build a pipeline manually by instantiating each element and linking them all together

gstreamer.freedesktop.org

#include <QCoreApplication>
#include <QDebug>
#include "gst/gst.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    GstElement *pipeline, *source, *sink;
    GstBus *bus;
    GstMessage *msg;
    GstStateChangeReturn ret;

    /* Initialize GStreamer */
    gst_init (&argc, &argv);

    /* Create the elements */
    source = gst_element_factory_make ("videotestsrc", "source");
    sink = gst_element_factory_make ("autovideosink", "sink");

    /* Create the empty pipeline */
    pipeline = gst_pipeline_new ("test-pipeline");

    if (!pipeline || !source || !sink) {
        g_printerr ("Not all elements could be created.\n");
        return -1;
    }

    /* Build the pipeline */
    gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
    if (gst_element_link (source, sink) != TRUE) {
        g_printerr ("Elements could not be linked.\n");
        gst_object_unref (pipeline);
        return -1;
    }

    /* Modify the source's properties */
    g_object_set (source, "pattern", 0, NULL);

    /* Start playing */
    ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
    if (ret == GST_STATE_CHANGE_FAILURE) {
        g_printerr ("Unable to set the pipeline to the playing state.\n");
        gst_object_unref (pipeline);
        return -1;
    }

    /* 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));

    /* Parse message */
    if (msg != NULL) {
        GError *err;
        gchar *debug_info;

        switch (GST_MESSAGE_TYPE (msg)) {
        case GST_MESSAGE_ERROR:
            gst_message_parse_error (msg, &err, &debug_info);
            g_printerr ("Error received from element %s: %s\n",
                        GST_OBJECT_NAME (msg->src), err->message);
            g_printerr ("Debugging information: %s\n",
                        debug_info ? debug_info : "none");
            g_clear_error (&err);
            g_free (debug_info);
            break;
        case GST_MESSAGE_EOS:
            g_print ("End-Of-Stream reached.\n");
            break;
        default:
            /* We should not reach here because we only asked for ERRORs and EOS */
            g_printerr ("Unexpected message received.\n");
            break;
        }
        gst_message_unref (msg);
    }

    /* Free resources */
    gst_object_unref (bus);
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);

    return a.exec();
}

gstreamer는 elements라는 요소로 이루어지고 있고 source elements로부터 sink elements까지 downstream으로 진행되고 있습니다. 그 중간에는 filter라는 elements도 존재합니다.

elements들은 gst_elements_factory_make라는 함수로 만들고 첫 번째 파라미터에 elements의 종류를 넣고 두 번째에 원하는 이름을 넣어줍니다.

예제에서 생성한 elements들은 videotestsrc, autovideosink로 필터가 없습니다.

/* Create the elements */
source = gst_element_factory_make ("videotestsrc", "source");
sink = gst_element_factory_make ("autovideosink", "sink");

따라서 처음 나온 그림에서 필터가 제거된 모습의 아래와 같은 형태라고 보시면 됩니다.

여기서 video test는 test video pattern을 생성해 줍니다. autovideosink는 받아온 이미지를 띄워줍니다. 이때 여러 videosink 중에 상황에 따라 적절한 sink 타입으로 진행합니다.

test video pattern

pipeline은 elements들을 담을 수 있는 elements입니다. pipeline은 bin을 상속받기 때문에 bin이라고도 합니다.

/* Create the empty pipeline */
pipeline = gst_pipeline_new ("test-pipeline");

if (!pipeline || !source || !sink) {
    g_printerr ("Not all elements could be created.\n");
    return -1;
}

 

 

 

생성된 pipline에 source, sink elements을 포함시켜 줍니다. get_bin_add_many 함수를 통해 여러 elements들을 동시에 추가할 수도 있고 gst_bin_add 함수를 통해 개별로 추가할 수도 있습니다.

/* Build the pipeline */
gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);

추가 후 gst_elements_link 함수를 통해 source elements와 sink elements를 이어줍니다. 이어줌으로써 downstream을 이루게 됩니다.

if (gst_element_link (source, sink) != TRUE) {
    g_printerr ("Elements could not be linked.\n");
    gst_object_unref (pipeline);
    return -1;
}

생성된 elements들을 g_object_set / get 함수를 통해 property를 수정하거나 얻어올 수 있습니다. 

예를 들어 source elements인 videotestsrc의 property 중 pattern property입니다. elements, property name, 그리고 값을 넘기면 해당 속성에 따라 다른 패턴을 그려주게 됩니다.

/* Modify the source's properties */
g_object_set (source, "pattern", 0, NULL);

 

728x90

+ Recent posts