본문 바로가기
MultiMedia Framework/GStreamer

hello world 찍기

by 유주원 2015. 3. 19.

대부분의 언어들은 Hello world를 찍어보는 것을 시작으로 프로그래밍을 이야기한다.

그럼 과연 gstreamer에서도 hello world를 찍어볼 수 있을까?

여기서는 hello world를 화면에 찍어보기 보다는 gstreamer에서 hello world 격인 멀티미디어 재생을 해보려고 한다.

해당 Tutorial은 gstreamer sdk 문서를 참조하였다.



해당 코드를 우선 실행시켜보자.


아래와 같이 컴파일을 하면 tutorial1 이라는 실행 파일이 생성된다.


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


이제 생성된 tutorial1을 실행해보자.


$> ./tutorial1



화면이 잘 재생되는가??? 이제 우리는 gstreamer에서 hello world를 찍은 것이다.

이제 code를 하나하나 살펴보자.


gst_init(&argc, &argv);


gstreamer를 사용하기 전에는 gst_init을 꼭 호출해서 라이브러리들을 초기화 해야한다. gst_init은 내부 자료 구조를 초기화 하고, 설치되어 있는 플러그인들이 유효한지에 대한 체크를 진행하며, argc와 argv로 넘어온 gstreamer 옵션 값을 받아서 실행하는 역할을 한다.

'아~ 그래서 argc와 argv를 매개변수로 넘기는 거구나~'


 pipeline = gst_parse_launch("playbin uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);


gstreamer에서 영상을 재생시키기 위해서는 "source element"와 "sink element"가 존재하고, 이 source에서 sink로 데이터가 흘러야한다.

이렇게 흘러가는 일련의 과정을 pipeline 이라고 부르는데, 이 pipeline은 개발자가 일일이 개별 요소를 구축해서 생성할 수도 있고, 위와 같이 gst_parse_launch를 통해서 자동으로 pipeline을 생성할 수도 있다.


이 둘의 차이를 간략히 설명하자면 사용자가 pipeline의 요소를 일일이 생성하는 경우는 요소에 어떤 이벤트를 받고자 할 경우, 예를 들어 'source element에서 sink element로 연결이 이루어졌을 때, 이벤트를 잡아서 어떤 처리를 하고 싶다.' 이런 경우에는 개발자가 일일이 개별 요소를 만들어 주어야 한다.


하지만 단지 영상 재생만을 목적으로 하는 경우라면 gst_parse_launch를 통해 알아서 파이프라인을 구축하게 하는 것이 간편하다.

gst_parse_launch의 원형을 보면 다음과 같이 되어 있는데,


GstElement * gst_parse_launch(const gchar *pipeline_description, GError **error);


playbin이라는 element가 멀티미디어가 위치한 uri를 받아서 그에 맞는 적절한 element를 생성하게 된다. 이렇게 생성된 playbin element를 통해 gst_parse_launch에서는 해당 playbin을 읽어들여 그에 맞는 pipeline을 새롭게 생성하는 것이다.


gst_element_set_state(pipeline, GST_STATE_PLAYING);


pipeline은 여러 형태의 상태 값을 가질 수가 있다. 

GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING이 바로 그것인데, 위의 코드에서 보면 만들어진

pipeline의 상태를 playing하려고 하는 것을 볼 수 있다.


bus = gst_element_get_bus(pipeline);

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


위 코드는 pipeline으로부터 bus를 가져오고 bus의 이벤트가 에러이거나(GST_MESSAGE_ERROR), 파일의 끝(GST_MESSAGE_EOS)일 때까지 block시킴을 의미한다. 실제 예제 코드로 컴파일 시에는 int를 GstMessageType으로 바꿀 수 없다는 형변환 에러가 발생하기 때문에 (GstMessageType)이라고 명시적으로 형변환을 시켜주었다.


if(msg != NULL){

    gst_message_unref(msg);

}

gst_object_unref(bus);

gst_element_set_state(pipeline, GST_STATE_NULL);

gst_object_unref(pipeline);


Cleanup(자원 반환) 코드이다. bus로부터 반환된 메시지를 해제하고, bus 객체도 해제한다.

pipeline의 상태를 NULL로 바꿔주고(default) pipeline 객체를 해제하면 모든 자원 반환이 완료된다.


이것으로 우리는 일단 gstreamer를 이용하여 멀티미디어를 재생시킬 수 있게 되었다!!