5.4. 엘리먼트 팩토리에 대한 자세한 내용

이전 섹션에서, 엘리먼트 인스턴스를 만드는 방법으로 GstElementFactory에 대해 이미 간단하게 소개를 했습니다. 그러나 엘리먼트 팩토리는 그보다 더 많은 내용을 담고 있습니다. 엘리먼트 팩토리는 GStreamer 레지스트리에서 검색 가능한 기본 타입이고, GStreamer에서 생성 가능한 모든 엘리먼트와 플러그인에 대해 설명합니다. 이것은 엘리먼트 팩토리가 오토플러거가 하는 것 처럼 자동으로 엘리먼트를 인스턴스화하고, 사용 가능한 엘리먼트 리스트를 생성하는데 유용합니다.

 

5.4.1. 팩토리를 이용하여 엘리먼트에 관한 정보를 추출하기

gst-inspect 같은 툴은 엘리먼트에 대한 플러그인 제작자, 플러그인을 설명하는 이름, 랭크나 카테고리 같은 포괄적인 정보를 제공합니다. 카테고리는 엘리먼트 팩토리리를 이용해 만들 수 있는 엘리먼트의 타입을 가져오는데 사용할 수 있습니다. 카테고리의 예는 Codec/Decoder/Video (video decoder), Codec/Encoder/Video (video encoder), Source/Video (a video generator), Sink/Video (a video output)와 이거소가 같은 오디오 관련 사항이 됩니다. 거기에 더해 Codec/Demuxer, Codec/Muxer 등이 더 있습니다.  gst-inspect는 모든 팩토리의 목록을 알려주며, gst-inspect <팩토리 이름>은 위에 설명한 정보에 더하여 더 풍부한 정보를 알려줍니다.

gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY)를 이용해 GStreamer로 알 수 있는 모든 팩토리 목록을 가져올 수 있습니다.

 

5.4.2. 엘리먼트가 어떤 패드를 가질 수 있는지 알아보기

아마도 엘리먼트 팩토리에서 가장 강력한 요소는 엘리먼트가 생성할 수 있는 패드에 대한 설명과 패드의 캐퍼빌리티(어떤 미디어 타입이 패드를 통해 흐를 수 있는지) 정보를 플러그인을 메모리에 올리지 않고도 가지고 올 수 있다는 것입니다. 이것을 이용해 인코더를 위한 코덱 선택을 위해 제공하거나, 미디어 플레이어를 의해 오토플러그인 요청에 사용할 수 있습니다. 현재 모든 GStreamer 기반의 미디어 플레이어나 오토플러거가 이러한 방식으로 동작합니다. GstPad와 GstCap에 대해 다음장에서 배울 때 이것에 대한 더 자세한 사항을 알아보도록 하겠습니다.

 

5.5. 엘리먼트 연결

소스 엘리먼트는 0 혹은 다수의 필터 유형의 엘리먼트와 그리고 결국은 싱크 엘리먼트와 연결하여, 미디어 파이프 라인을 설정합니다. 데이터는 엘리먼트를 통해 흐릅니다. 이것이 GStreamer에서 미디어 처리의 기본 개념입니다.

그림 5 – 5. 세 개의 엘리먼트 연결 시각화그림 5 – 5. 세 개의 엘리먼트 연결 시각화

세 개의 엘리먼트를 연결하여, 아주 간단한 엘리먼트 체인을 생성하였습니다. 이렇게 엘리면트를 연결하면, 소스 엘리먼트(일리먼트 1)의 출력은 필터 유사 엘리먼트(엘리먼트 2)의 입력으로 들어가게 됩니다. 필터 유사 엘리먼트는 데이터를 처리하여 그 결과를 싱크 엘리먼트(엘리먼트 3)로 전달합니다.

위의 그림을 간단한 Ogg/Vorbis 오디오 디코더라고 상상해보세요. 소스는 디스크에서 파일을 읽는 디스크 소스가 됩니다. 두번째 엘리먼트는 Ogg/Vorbis 오디오 디코더가 됩니다. 싱크 엘리먼트는 디코딩된 오디오 데이터를 출력하는 사운드 카드가 됩니다. 이 간단한 그림은 메뉴얼 후반에서 Ogg/Vorbis 플레이어를 만들 때 사용할 것 입니다.

코드로는 위의 그림을 위와 같이 나타낼 수 있습니다.

보다 구체적인 행동을 위해, gst_element_link()와 gst_element_link_pads()라는 함수가 있습니다. 패드와 링크 레퍼런스를 얻기 위해 다양한 gst_pad_link_*() 함수를 사용할 수 있습니다. 보다 자세한 사항은 API 레퍼런스를 참고하세요.

중요 : 엘리먼트를 빈에 넣을 때, 이전 연결을 모두 끊기 때문에, 엘리먼트를 연결하기 전에 반드시 엘리먼트를 빈이나 파이프라인에 추가해야 합니다. 또한 같은 파이프 라인이나 빈에 없는 엘리먼트를 직접 연결할 수 없습니다.  만약, 다른 계층 레벨에 있는 엘리먼트를 연결하려고 한다면, 고스트 패드를 사용해야 합니다(고스트 패드에 관한 자세한 사항은 차후 알아봅시다. 8.4에서 볼 수 있습니다.).

 

5.6. 엘리먼트 상태

엘리먼트 생성 후, 엘리먼트는 아직 어떠한 실제 행동을 하지 않습니다. 엘리먼트가 어떤 행동을 하도록 만들려면 엘리먼트의 상태를 변경해주어야 합니다. GStreamer는 특정한 의미를 담고 있는 4가지 상태를 가지고 있습니다.

그 4가지 상태는

  • GST_STATE_NULL : 기본 상태입니다. 이 상태에서는 리소스가 할당되지 않습니다. 그래서 이 상태로 변경하면 모든 리소스는 해제됩니다. 엘리먼트 레프카운트가 0, 혹은 프리가되면, 엘리먼트가 GST_STATE_NULL 상태가 됩니다.
  • GST_STATE_READY : 준비 상태입니다. 엘리먼트는 모든 전역 리소스(스트림 내에서 유지될 수 있는 리소스)를 할당합니다. 이것은 디바이스를 열고, 버퍼를 할당하는 등의 행동으로 생각할 수 있습니다. 그러나 스트림은 이 상태에서 열지는 않습니다. 그래서, 스트림의 위치가 자동적으로 0이 됩니다. 스트림이 이전에 열렸을 경우, Ready 상태로 올 때 스트림을 닫습니다. 그리고 프로퍼티와 위치 정보 등은 초기화됩니다.
  • GST_STATE_PAUSED : 이 상태에서 엘리먼트는 스트림을 열지만 처리를 하지 않습니다. 엘리먼트가 스트림을 수정하는 것이 허용되면, 데이트를 읽고 처리하여 PLAYING 상태로 이동할 준비를 합니다. 그러나 클락이 동작할 때와 같이 데이터가 플레이되지 않습니다. 요약하자면, 클락이 동작하는 것만 제외하면 PAUSED 상태는 PLAYING 상태와 똑같습니다.엘리먼트는 PLAYING 상태로 최대한 빨리 이동하기 위하여 PAUSED 상태에서 관련된 준비를 합니다. 예를 들어, 비디오와 오디오 출력은 데이터가 도착하는 것을 기다리고, 큐에 데이터를 넣습니다. 그래서 상태가 변경될 때, 바로 재생을 시작할 수 있도록 준비합니다. 또한, 비디오 싱크는 이미 첫 프레임을 재생할 수 있습니다(비디오 싱크가 클락에 아직 영향을 주지 않았기 때문에). 오토 플러거는 이미 파이프라인으로 연결된 엘리먼트를 같은 상태로 만듭니다. 그러나, 코덱과 필터 같은 다른 엘리먼트 대부분은 PAUSED상태에서 아무것도 할 필요가 없습니다.
  • GST_STATE_PLAYING : PLAYING 상태에서는 클락이 동작하는 것을 제외한 모든 것이 PAUSED상태와 같습니다.

gst_element_set_state() 함수를 이용하여, 엘리먼트의 상태를 설정할 수 있습니다. 엘리먼트의 상태를 바꾸면, GStreamer는 내부적으로 모든 중간 상태를 거쳐 상태를 설정합니다. 그래서 NULL에서 PLAYING 상태로 설정하면, GStreamer는 내부적으로 READY와 PAUSED 상태를 거쳐서 상태를 변경합니다.

GST_STATE_PLAYING 상태로 전환하면, 파이프라인은 자동으로 데이터를 처리합니다. 어떠한 형태로든지 반복할 필요가 없습니다. 내부적으로 GStreamer는 작업을 수행할 스레드를 생성합니다. GStreamer는 GstBus를 이용해 파이프라인 스레드에서 애플리케이션 스레드로 메시지를 전달합니다.

빈이나 파이프라인을 특정 상태로 설정하면, 빈이나 파이프라인 내부에 있는 모든 엘리먼트의 상태를 자동으로 변경합니다. 그래서 보통 파이프라인을 시작하거나 닫을 때, 최상위 파이프라인의 상태를 변경하면 됩니다. 그러나, “pad-add” 시그널 콜백과 같이 이미 동작하는 파이프라인에 동적으로 엘리멘트를 추가할 때, gst_element_set_state()나 gst_element_sync_state_with_parent() 함수를 이용하여 엘리먼트를 목표상태로 직접 설정해야 합니다.

Posted by _유부남J군_