8.3. 어떤 캐퍼빌리티(capabilities)를 사용할 것인가?

캐퍼빌리티(짧게는 캡스)는 두 개의 패드 사이를 흐르거나, 혹은 하나의 패드(템플릿)이 지원하는 데이터의 유형을 나타냅니다. 이것은 여러 가지로 유용합니다.

  • 오토플러깅 : 캐퍼빌리티를 기반으로 패드와 연결 될 엘리먼트를 자동으로 찾는 것을 말합니다. 모든 오토플러거는 이런 방법을 사용합니다.
  • 호환성 검사 : 두 개의 패드가 연결되면, GStreamer는 두 개의 패드가 같은 미디어 타입에 대해 얘기하는 것을 확인할 수 있습니다. 두 개의 패드를 연결하고, 패드 간 호환성을 검사하는 동작을 캡스 네고시에이션이(caps negotiation)라고 부릅니다.
  • 메타데이터 : 애플리케이션은 패드에 있는 캐퍼빌리티를 읽음으로써 현재 재생 중인 미디어 유형에 대한 정보를 패드를 통해 흐르는 스트림 정보를 읽어 제공할 수 있습니다.
  • 필터링 : 애플리케이션은 캐퍼빌리티를 사용하여 두 패드간에 흐르는 스트림을 지원하는 스트림 유형의 특정한 부분 집합으로 설정해 재생 가능한 미디어 유형을 제한할 수 있습니다. 예를 들어, 애플리케이션은 두 개의 패드 사이를 흐르는 스트림의 특정한 비디오 사이즈를 필터드 캡스(filtered caps)를 사용해 설정할 수 있습니다. 필터드 캡에 대한 예는 이 책 뒷부분에서 알아볼 것입니다. 캡스 필터링은 캡스필터 엘리먼트에 “caps” 프로퍼티를 설정하여 파이프라인에 삽입하면 가능합니다. 캡스필터 엘리먼트는 오디오 컨버터, 오디오 리샘플러, 비디오 컨버터, 비디오 스케일러와 같은 컨버터 뒤에 붙어 컨버터가 스트림의 특정 시점에서 특정한 출력 포맷으로 데이터를 변환하도록 사용합니다.

 

8.3.1. 메타데이터를 위하여 캐퍼빌리티 사용하기

패드는 캐퍼빌리티 집합을 가질 수 있습니다. 캐퍼빌리티(GstCaps)은 하나 이상의 GstStructure로 표현됩니다. 그리고 각각의 GstStructure는 필드 각 필드가 이름 문자열(예, width)이나 타입 값(예, G_TYPE_INT)으로 구성된 필드와 필드의 배열입니다.

패드의 파서블 캐퍼필리티(possible capabilities)와 얼로우드 캡스(allowed caps), 네고시에이티드 캡스(negotiated caps) 사이에는 뚜렷한 차이가 있다는 것을 기억하세요.

  • 파서블 캐퍼빌리티 : gst-inspect에 보여지는 패드 템플릿의 캐퍼빌리티
  • 얼로우드 캡스 : 파서블 캐퍼빌리티와 같거나 그 부분 집합. 연결되는 패드가 원하는 캡스의 파서블 캡스에 따라 결정.
  • 네고시에이티드 캡스 : 픽스드 캡스(fixed caps), 현재 스트림이나 버퍼의 정확한 포맷을 나타냄. 범위나 리스트와 깉이 가변 비트가 없고, 딱 하나의 정확한 구조체만 가짐.

하나의 구조체에 각 프로퍼티의 값을 질의해서 캐퍼빌리티 집합에서 프로퍼티 값을 가져올 수 있습니다. 캡스에서 구조체를 가져오는 것은 gst_caps_get_structure() 함수를 이용합니다. 그리고 GstCaps에서 구조체의 개수를 가져오는 것은 gst_caps_get_size() 함수를 사용합니다.

구조체를 하나만 가지고 있는 캡스를 심플 캡스(simple caps)라고 부릅니다. 그리고 픽스드 캡스(fixed caps)는 오직 하나의 구조체만 가지고 있고, 범위나 리스트와 같은 다른 가변 필드를 가지고 있지 않는 캡스를 말합니다. 캡스의 다른 특별한 두 개의 타입은 애니 캡스와 엠티 캡스가 있습니다.

아래는 픽스드 비디오 캡스 집합에서 비디오 사이즈를 추출하는 예 입니다.

8.3.2. 필터링을 위한 캐퍼빌리티 생성

패드의 미디어 타입을 나타내기 위해 플러그인 안에서 캐퍼빌리티를 사용할 때, 애플리케이션 개발자는 플러그인과 인터페이스를 위하여 캐퍼빌리티에 대한 기본 지식을 알 필요가 있습니다. 필터드 캡스나 고정을 사용하는 것은 두 개의 패드 사이를 흐르는 미디어의 타입을 패드가 지원하는 미디어 타입의 부분 집합으로 제한하는 것입니다. 그렇게 하기 위해 파이프라인에서 캡스필터(capsfilter) 엘리먼트를 사용합니다. 캡스필터 엘리먼트를 사용하기 위해서, 당신이 사용할 GstCaps를 만들어야 합니다. GstCaps을 만들기 위해 편리한 gst_caps_new_simple() 함수를 사용하는 것이 가장 쉬운 방법입니다.

위의 코드는 두 개의 엘리먼트 사이의 데이터 흐름을 특정한 비디오 포맷, 사이즈와 프레임 레이트()로 강제합니다(혹은 연결되는 엘리먼트가 해당 캡스를 지원하지 않으면 연결은 실패합니다). gst_element_link_filtered() 함수를 사용하면 자동으로 캡스필터 엘리먼트를 생성하고, 생성 된 엘리먼트를 연결하길 원하는 두 엘리먼트 사이에 있는 빈이나 파이프라인에 넣어 준다는 사실을 명심하세요(연결된 엘리먼트의 연결을 끊으려면, 대신 캡스필터로 연결 된 모든 엘리먼트의 연결을 끊어주어야 하기 때문에 이것은 중요합니다 ).

어떤 상황에서는 두 개의 패드 사이의 링크를 필터링하기 위해 보다 정교한 캐퍼빌리티 집합 설정을 원할 수 있습니다. 이럴 때는 그래서 gst_caps_new_full() 함수를 사용합니다.

GstStructure와 GstCaps의 모든 API는 API 레퍼런스를 참고하세요.

 

8.4. 고스트 패드

그림 8 – 1에는 자신의 패드가 없는 빈을 보여줍니다. 여기서 고스트 패드(ghost pad)를 이용할 필요가 생깁니다.

그림 8 – 1. GstBin의 그림그림 8 – 1. GstBin의 그림

그림 8 – 2. 고스트 패드가 있는 GstBin의 그림그림 8 – 2. 고스트 패드가 있는 GstBin의 그림

고스트 패드는 빈에서 직접 접근할 수도 있는 빈에 존재하는 어떤 엘리먼트의 패드입니다. 고스트 패드는 유닉스의 심볼릭 링크와 비교될 수 있습니다. 빈에서 고스트 패드를 사용하면, 빈에도 패드가 있게 되고, 코드의 다른 부분에서 엘리먼트와 같은 방법으로 투명하게 사용할 수 있습니다.

그림 8 – 2는 고스트 패드를 표현하고 있습니다. 엘리먼트 1의 싱크 패드가 빈의 패드입니다. 고스트 패드는 다른 패드와 똑같이 생겼고 동작하기 때문에, 다른 패드와 마찬가지로 GstBin에만 추가될 수 있는게 아니라 모든 엘리먼트에 추가될 수 있습니다.

gst_ghost_pad_new() 함수를 이용해 고스트 패드를 생성합니다.

위의 예를 보면, 정해진 엘리먼트에서 “sink”라고 불리는 패드가 빈의 패드가 되었습니다. 이제부터 빈을 싱크 패드의 대용으로 사용할 수 있습니다. 예를 들어 다른 엘리먼트를 빈과 연결 할 수도 있습니다.

Posted by _유부남J군_