본문 바로가기
MultiMedia Framework/GStreamer

수동으로 파이프라인 구축하기

by 유주원 2015. 3. 20.

전 포스팅에는 uri를 가져와서 playbin에 담은 후 gst_parse_launch를 통해 pipeline을 구축하는 방법을 설명했다.

이번에는 직접 pipeline을 구축해 보려고 한다.



이번에도 컴파일을 한 후 재생을 해보자.

$> g++ -o tutorial2 tutorial2.c `pkg-config --cflags --libs gstreamer-1.0`




예전에 화면 조정 시간에 많이 봤던 장면이네..

코드를 살펴보자..


gst_init(&argc, &argv);


이전 포스팅에서 설명했으니 이번엔 skip..


source = gst_element_factory_make("videotestsrc", "source");

sink = gst_element_factory_make("autovideosink", "sink");


위 구문은 중요한데.. element를 생성할 때는 gst_element_factory_make 함수를 사용한다. 

이전 포스팅에서는 element를 자동으로 생성하게 했기 때문에 gst_element_factory_make 함수를 따로 사용할 일이 없었지만 이번 시간에는 수동으로 pipeline을 구축해야 하기 때문에 위 함수를 사용한다.


첫 번째 매개변수에는 생성할 element type이 들어가는데, 이 타입의 종류에 대해서는 추후에 다시 언급하겠다.

두 번째 매개변수에는 element의 custom 이름이 들어간다. 그냥 내가 만들고 싶은 이름을 기입하면 된다. debug 시에 유용하다.


pipeline = gst_pipeline_new("test-pipeline");


해당 element를 다 만들었다면 이제 이 element를 담을 수 있는 pipeline을 생성해야 한다.

pipeline의 생성은 gst_pipeline_new 함수를 통해 이루어 지며 매개변수로 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;

}


gst_bin_add_many 함수를 통해 pipeline에 element들을 추가한다. 만약 하나의 element만을 추가하고 싶을 경우에는 gst_bin_add 함수를 이용한다.


pipeline에 담은 element들을 이제는 서로 간에 연결을 시켜줘야 한다. (그래야 데이터가 흘러갈테니깐..)

element간의 연결을 제공하는 함수는 gst_element_link이며 파라미터로 연결하고자 할 element를 넘겨준다. 

element간의 연결은 같은 bin(pipeline)에 있는 element 간에만 된다는 것을 명심하자.


만약에 2개 이상의 element들 간의 연결을 하고 싶다면 gst_element_link_many 함수를 이용한다.


g_object_set(source, "pattern", 0, NULL);


대부분의 element들은 속성 값을 가지고 있다. 속성 값은 g_object_get 함수로 읽을 수가 있고 g_object_set 함수로 설정할 수가 있다.

파라미터로는 우선 바꾸고자 하는 속성 값을 지닌 element, 그리고 속성 이름과 바꾸려고 하는 값 그리고 마지막 값은 NULL을 전달해야 한다.


msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));

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

        case GST_MESSAGE_EOS:

            g_print("End-Of-Stream reached.\n");

            break;

        default:

            g_printerr("Unexpected message received.\n");

            break;

    }

    gst_message_unref(msg);

}     


이전 포스팅에서 gst_bus_timed_pop_filtered 함수가 ERROR 메시지나 EOS 신호가 발생하기 전까지는 상태를 블록시키는 함수라고 설명했었다. (아마 waiting for signal과 비슷한 개념?)

위 switch 문에서는 해당 결과 메시지를 받았을 때 이 결과 메시지가 에러인지 EOS인지를 판별한 후 출력해준다. 


메시지 결과를 확인하고 싶다면 ./tutorial2를 실행한 후 영상 창의 닫기 버튼을 클릭하면 아래와 같이 메시지가 출력되는 것을 확인할 수 있다.


Error received from element sink-actual-sink-xvimage: Output window was closed

Debugging information: xvimagesink.c(551): gst_xvimagesink_handle_xevents(): /GstPipeline:test-pipeline........


자세히는 모르겠지만 대략적으로 출력 창이 닫혀졌다는 메시지를 뿌리는 것 같다.