2025년 2월 27일 목요일

250227 할일

 

  1. 시스템 패키지 강제 다운그레이드 대신 대체 환경 구성

    • Bookworm OS 전체의 안정성을 유지하면서, GStreamer 1.22.0 (특히 webrtcbin 플러그인을 포함한 버전)으로 작업할 별도의 환경(예: Docker 컨테이너 또는 chroot 환경)을 구성하는 방법을 고려할 수 있습니다.
    • 이렇게 하면, 호스트 시스템의 Mesa/GL 라이브러리와 충돌 없이 원하는 구버전 환경을 구성할 수 있습니다.
  2. 현재 설치된 최신 라이브러리 환경에서 webrtcbin 사용 재검토

    • 현재 GStreamer 1.22.0 환경에서 webrtcbin이 활성화되지 않는 이유가 단순히 빌드 옵션 또는 추가 종속성 문제일 수 있습니다.
    • Bookworm OS의 기본 패키지와 의존성을 그대로 사용하면서 webrtcbin을 소스 빌드하는 방법을 다시 시도해 보십시오.
    • 이 경우, 위에서 제시한 libnice, libsrtp2, libjson-glib 등은 이미 설치되어 있으므로, 소스 tarball(예: gst-plugins-bad-1.22.0.tar.xz)을 다운로드하여 빌드하는 것이 좋습니다.
  3. 소스 빌드 시, 환경 변수와 경로 설정

    • 소스 빌드할 때, 시스템에 설치된 GStreamer 1.22.0 헤더와 라이브러리 경로를 정확하게 지정하면, Bookworm의 최신 Mesa/GL 라이브러리와의 호환성을 유지하면서 webrtcbin 플러그인을 빌드할 수 있습니다.
    • 예를 들어, Meson 빌드 시 PKG_CONFIG_PATH/usr/lib/aarch64-linux-gnu/pkgconfig를 포함시키고, GST_PLUGIN_PATH 환경 변수를 적절하게 설정합니다.

결론
시스템의 핵심 라이브러리(특히 Mesa/GL 관련)는 현재 Bookworm OS의 최신 버전으로 유지하는 것이 중요합니다. 따라서 libelf1을 강제로 다운그레이드하여 충돌을 해결하는 것은 권장되지 않습니다. 대신, 위의 대안 중 하나를 선택하여 구버전 GStreamer 환경(특히 webrtcbin을 포함한)을 별도의 컨테이너 또는 chroot 환경에서 구성하거나, 현재 환경에서 소스 빌드 시 호환성 옵션을 조정하여 webrtcbin을 활성화하는 방향으로 진행하는 것이 바람직합니다.











bookworm os 의 GStreamer1.22.0 의존성 파일명

GStreamer 코어 라이브러리: libgstreamer1.0-0:arm64=1.22.0-2+deb12u1
기본 플러그인: gstreamer1.0-plugins-base:arm64=1.22.0-3+deb12u4
좋은 플러그인: gstreamer1.0-plugins-good:arm64=1.22.0-5+deb12u2
나쁜 플러그인: gstreamer1.0-plugins-bad:arm64=1.22.0-4+deb12u5
추한 플러그인: gstreamer1.0-plugins-ugly:arm64=1.22.0-2+deb12u1
FFmpeg 플러그인: gstreamer1.0-libav:arm64=1.22.0-2
X11 비디오 출력 플러그인: gstreamer1.0-x:arm64=1.22.0-3+deb12u4

libnice-dev 추가설치
(sudo apt-get install libnice-dev ) > (sudo apt-get install --reinstall gstreamer1.0-plugins-bad)
libsrtp2-dev
( sudo apt-get install libsrtp2-dev ) > (sudo apt-get install --reinstall gstreamer1.0-plugins-bad)
libjson-glib-dev 추가설치
( sudo apt-get install libjson-glib-dev ) > ( sudo apt-get install --reinstall gstreamer1.0-plugins-bad)

pi@raspberrypi:~ $ gst-inspect-1.0 webrtcbin
No such element or plugin 'webrtcbin'
pi@raspberrypi:~ $ sudo find /usr/lib/ -iname "*webrtcbin*"
pi@raspberrypi:~ $ 

기존에 설치된 GStreamer 1.22.0 및 그 의존성은 그대로 유지하면서
webrtcbin 플러그인만 소스에서 직접 빌드하여 통합

할일

빌드 환경 일치:
소스에서 빌드할 때, GStreamer 1.22.0 버전의 헤더와 라이브러리를 사용하도록 환경 변수를 설정하고, 올바른 태그(예: 1.22.0)에 맞춰 빌드해야 합니다.


플러그인 설치 경로:
빌드된 webrtcbin 플러그인을 기존 GStreamer 플러그인 디렉터리(예: /usr/lib/aarch64-linux-gnu/gstreamer-1.0/ 또는 /usr/lib/gstreamer-1.0/)에 설치해야 gst-inspect나 gst-launch가 이를 인식합니다.


의존성 확인:
webrtcbin은 libnice, libsrtp2, libjson-glib 등 여러 라이브러리에 의존합니다. 이들 라이브러리의 버전이 설치된 GStreamer와 호환되는지 확인해야 합니다.


목표
esp32cam의 mjpeg을 rpi5서버에서 수신해서 gstreamer로 vp8 트랜스코딩하고 webrtc로 rpi5에 offer를 보내고 client에서answer를 보내고 이후 과정을 거쳐 영상을 스트리밍하는거다.

webrtcbin 플러그인을 사용해서 구현중 에러
서버에서 ice후보 생성이 안됨, 버전이나 종속성이 맞지 않아 발생된 문제라 추정중

시스템 구성 요소 및 버전 정보

구성 요소 버전/정보 비고 및 설명
OS (커널) 6.6.74+rpt-rpi-2712 (Debian 1:6.6.74-1+rpt1, 2025-01-27, aarch64) Raspberry Pi OS (Debian 기반) – uname -a 명령어 출력
GStreamer Core 1.22.0 gst-launch-1.0 --version 결과
gst-plugins-base 1.22.0-3+rpt1+deb12u4 기본 플러그인 – 핵심 요소 제공
gst-plugins-good 1.22.0-5+rpt1+deb12u2 품질 좋고 라이선스 문제 없는 플러그인 패키지
gst-plugins-bad 1.22.0-4+deb12u5 아직 완전히 검증되지 않은 기능 포함 플러그인
gst-plugins-ugly 미설치 특허/라이선스 이슈로 별도 설치 필요 (현재는 설치되지 않음)
Python 3.11.2 기본 Python 인터프리터 버전
gi (GStreamer 바인딩) 3.42.2 Python에서 GStreamer, GObject Introspection 기능 사용 (gi 모듈 버전)
Node.js v18.19.0 Express, WebSocket 기반 시그널링 서버 등에서 사용
Go 언어 미확인 (설치되지 않았거나 확인 필요) Go 언어 사용 여부는 go version 명령어로 확인 가능 (현재 확인되지 않음)

2025년 2월 25일 화요일

수정본 GStreamer 프레임워크 매뉴얼

 


GStreamer 프레임워크 매뉴얼

서문

GStreamer는 스트리밍 미디어 애플리케이션 개발을 위한 강력하고 유연한 프레임워크입니다. 모듈화를 통해 새로운 플러그인 모듈을 쉽게 통합할 수 있지만, 그만큼 복잡성도 올라갈 수 있어 애플리케이션 개발 시 난이도가 높아질 수 있습니다.

이 매뉴얼은 GStreamer 프레임워크를 이해하고 이를 기반으로 애플리케이션을 개발하는 방법을 안내합니다. 먼저 간단한 오디오 플레이어 예제를 통해 GStreamer의 개념을 익히고, 이후 미디어 재생·캡처·편집 등 다양한 미디어 처리 기능을 다룹니다.


소개

이 매뉴얼의 대상

이 문서는 애플리케이션 개발자를 위한 매뉴얼입니다. GStreamer 라이브러리와 도구를 사용해 애플리케이션을 작성하는 방법을 중점적으로 설명하며, 플러그인 작성에 대한 세부 정보는 별도의 플러그인 작성자 가이드를 참고하세요.

사전 지식

  • C 언어 기본 이해가 필요합니다.
  • GStreamer는 GObject 프로그래밍 모델을 따르므로, GObject와 glib 프로그래밍(객체 인스턴스화, 속성 설정/조회, 참조/해제, 메모리 관리, 신호 및 콜백, 메인 루프 등)에 대한 기본 지식이 있으면 좋습니다.

매뉴얼 구성

  1. GStreamer 개요
    GStreamer의 기본 개념과 설계 원칙에 대해 설명합니다.

  2. 애플리케이션 개발
    GStreamer 애플리케이션 개발의 기본을 다룹니다. 이를 통해 간단한 오디오 플레이어를 만들어볼 수 있습니다.

  3. 고급 GStreamer 개념
    애플리케이션-파이프라인 상호작용, 스레드 기반 파이프라인, 스케줄링과 동기화 등 고급 기능을 다룹니다.

  4. 고급 인터페이스
    playbin 및 자동 플러그인 로딩(autoplugger) 등 GStreamer 애플리케이션을 위한 고급 프로그래밍 API를 소개합니다.

  5. 부록
    GNOME, KDE, macOS, Windows와의 통합, 디버깅 도움말, GStreamer 프로그래밍 개선/단순화 팁을 포함합니다.

위 내용을 숙지하면 GStreamer 애플리케이션 개발을 진행할 수 있습니다.


1. GStreamer 개요

GStreamer는 스트리밍 미디어 애플리케이션을 만들기 위한 프레임워크로, 오디오·비디오·이미지 등 다양한 미디어 데이터를 처리하는 기반을 제공합니다. 파이프라인 개념을 사용해 다양한 요소(필터·코덱·소스·싱크 등)를 조합할 수 있으며, 플러그인 시스템을 통해 손쉽게 기능을 확장할 수 있습니다.

디자인 원칙

깔끔하고 강력함

  • 애플리케이션 프로그래머: 복잡한 미디어 조작을 최소한의 코드로 구현할 수 있는 강력한 도구를 제공합니다.
  • 플러그인 프로그래머: 간단하면서도 강력한 API와 디버깅/추적 메커니즘을 제공합니다.

객체 지향

  • GStreamer는 GLib 2.0 객체 모델인 GObject를 따릅니다.
  • GObject 방식으로 신호, 속성, 참조 카운팅, 메모리 관리 등을 처리합니다.

확장성

  • 모든 GStreamer 객체는 GObject로 구현되어 있어 동적으로 확장 가능합니다.
  • 플러그인은 독립적으로 로드·업그레이드할 수 있습니다.

바이너리 전용 플러그인 지원

  • 플러그인은 런타임에 로드되는 공유 라이브러리 형태로 제공됩니다.
  • 헤더 파일 없이도 GObject 속성을 통해 플러그인을 제어할 수 있습니다.

높은 성능

  • GLib GSlice 할당기 사용
  • 플러그인 간 최소한의 오버헤드(포인터 역참조 정도)
  • memcpy 사용을 최소화하는 copy-on-write 구조 등

코어/플러그인 분리

  • 코어는 미디어와 독립적인 가장 기본 기능만 담당하고,
  • 실제 미디어 처리는 모두 플러그인이 담당합니다.

코덱 실험을 위한 프레임워크

  • 열린 멀티미디어 코덱(예: Theora, Vorbis) 개발을 촉진하는 실험적인 코덱 개발 환경으로 사용될 수도 있습니다.

2. 애플리케이션 개발

GStreamer 초기화

간단한 초기화

  • GStreamer 라이브러리를 사용하기 전에 gst_init을 반드시 호출해야 합니다.
  • 명령줄 옵션을 파싱하지 않으려면 gst_init(NULL, NULL) 형태로 사용 가능합니다.

GOption 인터페이스

  • GLib의 GOption 테이블을 사용해 애플리케이션 고유 파라미터를 초기화할 수 있습니다.
  • gst_init_get_option_group 함수를 통해 GStreamer 관련 옵션을 통합하여 파싱할 수 있습니다.

요소(Element)

요소란?

  • GStreamer의 핵심 객체는 GstElement입니다.
  • 디코더, 인코더, 디멀티플렉서, 소스, 싱크 등은 모두 GstElement로 표현됩니다.

소스 요소

  • 데이터를 생성(읽어오는) 요소입니다. 파일, 네트워크, 캡처 장치 등에서 데이터를 가져옵니다.

필터·변환·디멀티플렉서·코덱 등

  • 입력·출력 두 가지 패드를 가지고 있어, 입력 데이터를 받아 변환/처리 후 출력 패드를 통해 다음 요소로 전달합니다.

싱크 요소

  • 데이터를 최종적으로 받아 처리(출력)하는 요소입니다.
  • 예: 사운드 카드로 오디오 재생, 디스플레이로 비디오 출력 등

GstElement 생성하기

  • 가장 간단한 방법은 gst_element_factory_make("요소팩토리이름", "별칭")을 사용하는 것입니다.

요소 팩토리

  • GStreamer 레지스트리에 등록된 플러그인, 요소 정보를 관리하는 객체입니다.
  • 자동화된 요소 인스턴스화(자동 플러그인 등)에 유용합니다.

패드와 연결하기

  • 요소 간 데이터 흐름은 소스 패드에서 싱크 패드로 이루어집니다.
  • 패드를 연결해 파이프라인(요소들의 연결 구조)을 완성할 수 있습니다.

요소 상태

  • GST_STATE_NULL: 기본 상태, 자원 할당 없음
  • GST_STATE_READY: 전역 자원 할당
  • GST_STATE_PAUSED: 스트림을 열었지만 데이터는 처리 안 함
  • GST_STATE_PLAYING: 실제 데이터 재생(처리) 중

빈(Bin)

  • **빈(bin)**은 여러 요소를 하나로 묶는 컨테이너 요소입니다.
  • 빈 자체도 GstElement로 취급되므로, 다른 요소처럼 상태를 설정하거나 관리할 수 있습니다.

빈이란?

  • 복잡한 파이프라인을 작은 단위로 나누어 관리할 수 있게 해 줍니다.
  • 연결된 요소들을 한 그룹으로 묶고, 상태 변경을 일괄 처리합니다.

빈 생성하기

  • gst_bin_new()gst_pipeline_new()와 같은 함수를 사용합니다.
  • gst_bin_add()로 요소를 추가하면 빈이 그 요소를 소유하게 됩니다.

사용자 정의 빈

  • 특정 작업을 수행하는 요소들을 미리 구성한 사용자 정의 빈을 만들 수 있습니다.

빈은 자식 요소들의 상태를 관리함

  • 빈의 상태를 변경하면 내부 자식 요소들도 함께 상태가 변합니다.
  • 이미 실행 중인 파이프라인에 요소를 추가할 경우, gst_element_sync_state_with_parent() 등을 통해 상태를 맞춰줘야 합니다.

버스(Bus)

  • 버스는 스트리밍 스레드에서 발생하는 메시지를 애플리케이션 스레드로 전달해주는 시스템입니다.
  • GStreamer는 내부적으로 스레드를 많이 사용하지만, 버스를 통해 메시지를 중앙에서 처리할 수 있어 애플리케이션 코드가 단순해집니다.

버스를 사용하는 방법

  1. GLib/Gtk+ 메인 루프
    gst_bus_add_watch(), gst_bus_add_signal_watch()로 메인 루프와 연동
  2. 직접 메시지 확인
    gst_bus_poll() 등을 통해 메시지를 직접 확인 가능

메시지 유형

  • 오류, 경고, 정보
  • 스트림 종료(EOS)
  • 태그(메타데이터 감지 시)
  • 상태 변경
  • 버퍼링
  • 요소/애플리케이션 고유 메시지

Pads와 Capabilities

Pads

  • 요소가 외부와 연결되는 인터페이스입니다.
  • 소스 Pad(출력), 싱크 Pad(입력) 등 방향이 있고, 가용성(항상·때때로·요청 시)으로 구분됩니다.

동적(때때로) Pads

  • 요소에 따라 필요할 때마다 Pad가 생성·삭제될 수 있습니다.
  • 예: oggdemux(디멀티플렉서)는 스트림을 분석해 새로운 트랙을 발견하면 동적 Pad를 만듭니다.

요청 Pad

  • 필요할 때만 생성되는 Pad입니다.
  • 예: tee 요소에서 여러 출력 Pad가 필요하면 그때 요청 Pad가 생성됩니다.

Capabilities

  • 각 Pad가 처리 가능한 미디어 타입을 GstCaps 객체 형태로 기술합니다.
  • 캡은 한 개 이상의 GstStructure를 포함하며, 각 구조체는 미디어 타입을 설명합니다.
  • 능력 협상(capabilities negotiation)을 통해 서로 호환되는 타입인지 확인하고 데이터 처리를 진행합니다.

버퍼(Buffer)와 이벤트(Event)

  • 파이프라인을 통해 흐르는 실제 미디어 데이터는 버퍼에 담겨 전달됩니다.
  • 이벤트는 탐색(seeking), 스트림 종료(EOS) 등 제어 정보를 전달합니다.

버퍼

  • 메모리 포인터, 타임스탬프, 참조 카운트, 플래그 등으로 구성됩니다.
  • 일반적으로 소스가 버퍼를 만들어 다음 요소로 푸시하고, 해당 요소가 처리 후 새 버퍼를 만들어 넘기는 방식으로 동작합니다.

이벤트

  • 파이프라인 내에서 상·하류 방향으로 전달되는 제어 정보입니다.
  • 하류 이벤트: 스트림 종료, 탐색 완료 등
  • 상류 이벤트: 탐색 명령, 플러시 등

첫 번째 애플리케이션

헬로 월드

  • 간단한 Ogg/Vorbis 오디오 플레이어 예제
  • filesrc + oggdemux + vorbisdec + autoaudiosink 연결
  • oggdemux는 동적 패드를 생성하므로 “pad-added” 콜백 설정 필요
  • 파이프라인 빌드 후 PLAYING 상태로 전환하여 재생
  • gst_bus_add_watch()를 통해 오류나 EOS 메시지를 처리

컴파일 및 실행

  • 예:
    lua
    gcc -Wall helloworld.c -o helloworld $(pkg-config --cflags --libs gstreamer-1.0)
  • 비표준 경로에 GStreamer가 설치된 경우 PKG_CONFIG_PATH 설정이 필요할 수 있습니다.

3. 고급 GStreamer 개념

이전 장에서는 간단한 예제를 통해 GStreamer 파이프라인을 구성해보았습니다. 그러나 GStreamer는 이보다 훨씬 광범위하고, 다양한 고급 기능을 제공합니다. 이 장에서는 스케줄링, 동기화, 버퍼링, 애플리케이션-파이프라인 상호작용 등과 같은 심화 개념을 다룹니다.

위치 추적(쿼리) 및 탐색(이벤트)

  • 쿼리: 스트림의 길이, 현재 재생 위치 등을 얻기 위해 사용
  • 이벤트: 탐색(seek)이나 스트림 상태 변경 등을 요청할 때 사용

쿼리

  • gst_element_query_position(), gst_element_query_duration() 등을 주로 사용
  • 내부적으로 디멀티플렉서나 라이브 소스가 처리

탐색(이벤트)

  • seek-event로 구현되며, 재생률, 오프셋, 플래그, 탐색 방법 등을 지정
  • 파이프라인에서 적절히 처리되어 스트림 위치를 변경

메타데이터

  • 스트림 태그: 노래 제목, 저자, 앨범 등 일반적인 메타정보
  • 스트림 정보: 비디오 해상도, 오디오 샘플링 레이트 등 기술적 정보

태그는 버스의 태그 메시지로 전달되며, 애플리케이션에서 이를 수신하여 표시하거나 업데이트할 수 있습니다.

인터페이스

  • GObject의 GTypeInterface를 활용해 복잡한 기능(URI 핸들러, 색상 균형, 비디오 오버레이 등)을 통일된 방법으로 접근할 수 있게 합니다.
  • 예) GstURIHandler: 파일이나 네트워크 URI를 지원하는 요소 추상화
  • 예) GstColorBalance: 비디오 밝기·대비 등의 색상 속성 제어
  • 예) GstVideoOverlay: 지정된 윈도우 위에 비디오를 오버레이

GStreamer의 클럭과 동기화

  • 여러 스트림(오디오·비디오 등)을 동기화하기 위해 공통 클럭을 사용
  • 실행 시간(running time): 파이프라인이 PLAYING 상태로 전환될 때 시작되는 기준 시간
  • 스트림 시간: 미디어 파일 내에서의 위치를 의미(예: 1분 30초 지점)
  • 싱크 요소가 버퍼의 실행 시간을 기준으로 실제 출력 타이밍을 맞춥니다.

버퍼링

  • 느린 네트워크 환경에서 재생을 부드럽게 유지하기 위해, 파이프라인에 일정 데이터 양을 모아두는 기법
  • BUFFERING 메시지를 모니터링하여 버퍼가 충분할 때까지 PAUSED 상태로 대기하고, 100%에 도달하면 PLAYING으로 전환

동적 제어 가능한 매개변수

  • gstcontroller를 통해 시간(스트림 시간)에 따라 요소의 특정 속성을 동적으로 변화시킬 수 있습니다.
  • 예) 오디오 볼륨을 곡이 진행됨에 따라 천천히 올리는 효과 등

스레드

  • GStreamer는 멀티스레드 프레임워크이며, 많은 내부 처리가 스레드 기반으로 이루어집니다.
  • 요소 간 데이터를 주고받는 과정에서 스레드를 자동 생성하기도 하며, queue 요소 등을 통해 명시적으로 스레드 경계를 형성할 수도 있습니다.

자동 플러깅(Autoplugging)

  • 스트림의 형식을 자동으로 감지하여 디코더·필터·싱크 등을 자동으로 연결해주는 기능
  • typefinding(유형 찾기)을 거쳐, 적절한 디코더/플러그인을 조합해 파이프라인을 구성
  • playbin, decodebin 등의 자동 플러거 요소가 대표적

파이프라인 조작

  • gst_pad_add_probe() 등을 사용해 프로브를 달아 데이터 흐름을 감시하거나 이벤트를 가로챌 수 있습니다.
  • 플레이 중 특정 구간만 재생할 때는 seek 이벤트를 사용합니다.
  • 임의의 데이터 삽입(appsrc), 추출(appsink), 포맷 강제(capsfilter) 등으로 파이프라인을 동적으로 제어할 수 있습니다.
  • 이미 PLAYING 중인 파이프라인에 요소를 추가/제거하려면 데이터 흐름 차단, EOS 전송, 상태 동기화 등 일련의 과정을 거쳐야 합니다.

4. 고급 인터페이스

복잡한 세부 구현보다 더 단순하고 직관적인 방법으로 미디어 재생을 다루고 싶다면, GStreamer는 다양한 고급 인터페이스를 제공합니다.

재생 구성 요소

  • playbin: 가장 손쉬운 재생 파이프라인 구성 요소

    • URI 설정만으로 오디오·비디오·자막 등을 자동 재생
    • 속성: uri, audio-sink, video-sink, suburi(자막) 등
    • 여러 트랙(오디오/자막)을 제공할 경우 동적 트랙 선택 가능
  • decodebin / uridecodebin:

    • 스트림 형식을 자동으로 감지하고 적절한 디코더를 연결
    • uridecodebin은 네트워크 스트림 버퍼링을 자동으로 처리하는 등 편의 기능 제공
  • playsink: 오디오·비디오·텍스트 트랙을 하나로 관리하는 강력한 싱크 요소


5. 부록

GNOME, KDE, macOS, Windows와의 통합

  • GStreamer는 다양한 플랫폼·데스크톱 환경과 통합될 수 있습니다.
  • 각 플랫폼별 오디오/비디오 디바이스 제어, 이벤트 루프 통합 등이 가능합니다.

디버깅 도움말

  • GST_DEBUG 환경 변수
  • gst-launch-1.0 --gst-debug-level=2 등으로 디버깅 로그 확인
  • GST_DEBUG_DUMP_DOT_DIR를 통해 파이프라인 그래프(.dot 파일) 생성 가능

GStreamer 프로그래밍 개선 및 단순화 팁

  • 복잡한 파이프라인은 **빈(Bin)**을 사용해 작은 단위로 나누어 구성
  • 자동 플러거를 적극 활용(playbin, decodebin, uridecodebin 등)
  • GObject 속성, 신호, 이벤트, 쿼리를 숙지해 유지보수성을 높이기

[Plugins] webrtcbin

webrtcbinW3C WebRTC 표준(특히 PeerConnection API) 구현에 근접한 GStreamer 플러그인입니다.

  • 제안(Offer), 응답(Answer) 생성 및 로컬/원격 SDP 설정을 지원
  • 각 입력/출력 Pad가 WebRTC 트랙에 해당하며, 데이터 채널까지 포함해 SDP로 정의 가능
  • ICE, DTLS 등을 통한 안전한 전송 통로(Transport)를 구성
  • 번들(Bundle) 정책, ICE 후보 제어, 재협상 이벤트(on-negotiation-needed) 등 다양한 시나리오 지원

주요 특징

  • 계층 구조: GstBin을 상속받으며, 내부적으로 ICE/DTLS/코덱 처리 요소를 구성
  • 시그널: on-data-channel, on-ice-candidate, on-new-transceiver 등 WebRTC 특유의 이벤트를 GStreamer 신호로 제공
  • 액션 시그널: create-offer, create-answer, add-transceiver, add-ice-candidate
  • 속성: local-description, remote-description, bundle-policy

GStreamer프레임워크 알아보기(주로 번역)

 

GStreamer 프레임워크 매뉴얼

출처 : https://gstreamer.freedesktop.org/documentation/application-development/index.html?gi-language=c

서문

GStreamer는 스트리밍 미디어 애플리케이션 개발을 위한 강력하고 유연한 프레임워크임. 모듈화를 통해 새로운 플러그인 모듈을 쉽게 통합할 수 있음. 하지만 이로 인해 복잡성이 증가할 수 있어 애플리케이션 개발이 쉽지 않을 수 있음.

이 매뉴얼은 GStreamer 프레임워크를 이해하고 이를 기반으로 애플리케이션을 개발하는 방법을 안내함. 처음엔 간단한 오디오 플레이어 개발을 통해 GStreamer의 개념을 이해하고, 이후에는 미디어 재생, 캡처, 편집 등 다양한 미디어 처리 기능을 다룸.



소개

이 매뉴얼의 대상

애플리케이션 개발자를 위한 매뉴얼로, GStreamer 라이브러리와 도구를 사용해 애플리케이션을 작성하는 방법을 설명함. 플러그인 작성법은 별도의 플러그인 작성자 가이드를 참고해야 함.

사전 지식

C 언어 기본 이해가 필요함.
또한 GStreamer는 GObject 프로그래밍 모델을 따르므로, GObject와 glib 프로그래밍에 대한 이해가 필요함. 주요 개념은 GObject 인스턴스화, 속성 설정/조회, 참조/해제, 메모리 관리, 신호 및 콜백, 메인 루프 등이 있음.






매뉴얼 구성

  1. GStreamer 개요
    GStreamer의 기본 개념과 설계 원칙 설명.

  2. 애플리케이션 개발
    GStreamer 애플리케이션 개발의 기본적인 부분을 다룸. 이를 통해 오디오 플레이어를 개발할 수 있음.

  3. 고급 GStreamer 개념
    GStreamer의 경쟁력을 높여주는 고급 기능들을 다룸.

    • 애플리케이션-파이프라인 상호작용
    • 스레드 기반 파이프라인
    • 스케줄링과 동기화
      이 파트에서는 문제 해결과 깊은 이해를 돕기 위한 개념들이 다뤄짐.
  4. 고급 인터페이스
    GStreamer 애플리케이션을 위한 고급 프로그래밍 API를 다룸. 기본적인 GStreamer 개념 이해가 필요함.

    • playbin 및 자동 플러그인 로딩 (autoplugger) 등을 다룸.
  5. 부록

    • GNOME, KDE, macOS, Windows와의 통합
    • 디버깅 도움말
    • GStreamer 프로그래밍 개선 및 단순화 팁

이 가이드를 통해 GStreamer 애플리케이션 개발을 진행할 수 있음.







1. GStreamer 개요


GStreamer는 스트리밍 미디어 애플리케이션을 만들기 위한 프레임워크임. 기본 설계는 오리건 대학원의 비디오 파이프라인과 DirectShow에서 아이디어를 차용함.

GStreamer의 개발 프레임워크는 오디오, 비디오 또는 둘 다 처리하는 애플리케이션을 쉽게 만들 수 있게 해줌. 오디오와 비디오에만 국한되지 않고, 모든 종류의 데이터 흐름을 처리할 수 있음. 파이프라인 설계는 필터가 유도하는 오버헤드 외에는 거의 부하를 추가하지 않아서, 고급 오디오 애플리케이션에서 낮은 지연 시간 요구 사항을 충족할 수 있는 좋은 프레임워크임.

GStreamer의 가장 명백한 용도 중 하나는 미디어 플레이어를 만드는 것임. GStreamer는 MP3, Ogg/Vorbis, MPEG-1/2, AVI, Quicktime, mod 등 다양한 포맷을 지원하는 미디어 플레이어를 만들 수 있는 구성 요소들을 포함하고 있음. 하지만 GStreamer는 단순한 미디어 플레이어 이상임. 그 주요 장점은 플러그인 구성 요소들이 서로 혼합되고 파이프라인으로 연결되어, 오디오나 비디오 편집 애플리케이션을 작성할 수 있다는 점임.

프레임워크는 다양한 코덱과 기능을 제공하는 플러그인들을 기반으로 함. 플러그인들은 파이프라인에서 링크되고 배열되어 데이터 흐름을 정의함. 파이프라인은 GUI 편집기를 통해 편집할 수 있으며, XML로 저장하여 최소한의 노력으로 파이프라인 라이브러리를 만들 수 있음.

GStreamer의 핵심 기능은 플러그인, 데이터 흐름, 미디어 타입 처리 및 협상, 그리고 애플리케이션을 작성할 수 있는 API를 제공하는 것임.

구체적으로 GStreamer는 다음과 같은 기능을 제공함:

  • 멀티미디어 애플리케이션용 API
  • 플러그인 아키텍처
  • 파이프라인 아키텍처
  • 미디어 타입 처리 및 협상 메커니즘
  • 동기화 메커니즘
  • 250개 이상의 플러그인과 1000개 이상의 요소 제공
  • 여러 도구 세트

GStreamer 플러그인은 다음과 같이 분류할 수 있음:

  • 프로토콜 처리
  • 소스: 오디오 및 비디오 (프로토콜 플러그인 포함)
  • 포맷: 파서, 포매터, 멀티플렉서, 디멀티플렉서, 메타데이터, 자막
  • 코덱: 인코더 및 디코더
  • 필터: 변환기, 믹서, 효과 등
  • 싱크: 오디오 및 비디오 (프로토콜 플러그인 포함)

GStreamer는 다음과 같은 패키지로 구성됨:

  • gstreamer: 핵심 패키지
  • gst-plugins-base: 필수적이고 대표적인 요소 세트
  • gst-plugins-good: LGPL 하에 배포되는 좋은 품질의 플러그인 세트
  • gst-plugins-ugly: 배포에 문제가 있을 수 있는 좋은 품질의 플러그인 세트
  • gst-plugins-bad: 품질이 더 필요한 플러그인 세트
  • gst-libav: libav를 래핑한 인코딩 및 디코딩 플러그인 세트
  • 기타 여러 패키지

디자인 원칙

깔끔하고 강력함

GStreamer는 다음과 같은 인터페이스를 제공함:

  • 애플리케이션 프로그래머: 미디어 파이프라인을 구축하려는 프로그래머에게 강력한 도구 세트를 제공. 코드 한 줄 없이 복잡한 미디어 조작을 쉽게 수행할 수 있음.
  • 플러그인 프로그래머: 플러그인 프로그래머에게 깔끔하고 간단한 API를 제공. 강력한 디버깅 및 추적 메커니즘도 통합되어 있음. GStreamer는 실제 플러그인 예제도 많이 포함하고 있음.

객체 지향

GStreamer는 GLib 2.0 객체 모델인 GObject를 따름. GLib 2.0이나 GTK+에 익숙한 프로그래머는 GStreamer 사용에 어려움이 없음.

  • GStreamer는 신호 및 객체 속성 메커니즘을 사용함.
  • 모든 객체는 런타임에서 다양한 속성과 기능을 조회할 수 있음.
  • GStreamer는 GTK+와 유사한 프로그래밍 방법론을 따름. 객체 모델, 객체 소유권, 참조 카운팅 등이 포함됨.

확장성

모든 GStreamer 객체는 GObject 상속 방법을 사용하여 확장 가능함.

  • 모든 플러그인은 동적으로 로드되며 독립적으로 확장 및 업그레이드 가능함.

바이너리 전용 플러그인 지원

플러그인은 런타임에 로드되는 공유 라이브러리임. 플러그인 속성은 GObject 속성을 사용해 설정할 수 있어, 플러그인의 헤더 파일을 설치할 필요 없음.

  • 플러그인은 완전히 자가 포함된 형태로 제작됨. 플러그인 관련 모든 측면은 런타임에 조회할 수 있음.

높은 성능

높은 성능은 다음을 통해 얻어짐:

  • GLib의 GSlice 할당기 사용
  • 플러그인 간 매우 가벼운 링크. 데이터는 최소한의 오버헤드로 파이프라인을 통해 이동함. 플러그인 간 데이터 전달은 일반적으로 포인터 역참조만 포함됨.
  • 타겟 메모리에서 직접 작업할 수 있는 메커니즘 제공. 예를 들어, 플러그인은 X 서버의 공유 메모리 공간에 직접 쓸 수 있음. 버퍼는 사운드 카드의 내부 하드웨어 버퍼와 같은 임의의 메모리를 가리킬 수 있음.
  • 참조 카운팅 및 복사 시 쓰기 방식으로 memcpy 사용을 최소화. 서브 버퍼는 버퍼를 효율적으로 분할하여 관리할 수 있도록 함.
  • 전용 스트리밍 스레드 사용, 스케줄링은 커널에서 처리됨.
  • 하드웨어 가속을 전문 플러그인을 사용해 허용.
  • 플러그인 사양을 포함한 플러그인 레지스트리를 사용하여 플러그인 로딩을 실제로 사용될 때까지 지연시킬 수 있음.

깔끔한 코어/플러그인 분리

GStreamer의 코어는 미디어와 독립적임. 기본 요소만 포함하고 있으며, 바이트와 블록에 대해서만 알고 있음. GStreamer의 코어는 cp와 같은 낮은 수준의 시스템 도구를 구현할 수 있을 만큼 기능이 충분함.

  • 모든 미디어 처리 기능은 코어 외부의 플러그인에서 제공됨. 플러그인들은 코어에게 특정 미디어 타입을 처리하는 방법을 알려줌.

코덱 실험을 위한 프레임워크 제공

GStreamer는 Xiph.Org Foundation에서 개발한 Theora와 Vorbis와 같은 열린 멀티미디어 코덱의 개발을 촉진할 수 있는 실험적인 코덱 개발을 위한 프레임워크로 사용되길 원함.





2.애플리케이션 개발

GStreamer 초기화

GStreamer 애플리케이션을 작성할 때, gst/gst.h를 포함하면 라이브러리 함수에 접근할 수 있음. 그 외에도 GStreamer 라이브러리를 초기화해야 함.

간단한 초기화

GStreamer 라이브러리를 사용하기 전에 gst_init 함수를 호출해야 함. 이 호출은 라이브러리 초기화와 GStreamer 관련 명령줄 옵션 파싱을 수행함.


GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO 매크로를 사용하거나 gst_version 함수를 사용해 현재 애플리케이션이 연결된 GStreamer 버전을 가져올 수 있음. GStreamer는 현재 주요 버전과 부버전이 같으면 API 및 ABI가 호환되는 방식으로 버전을 관리함.

gst_init 함수에 두 개의 NULL 인자를 전달하면 GStreamer가 명령줄 옵션을 파싱하지 않음.

GOption 인터페이스

다음 예시처럼 GOption 테이블을 사용해 애플리케이션 고유의 파라미터를 초기화할 수 있음

GOption 테이블을 사용해 애플리케이션 고유의 명령줄 옵션을 정의하고, gst_init_get_option_group 함수에서 반환된 옵션 그룹과 함께 이 테이블을 GLib 초기화 함수에 전달할 수 있음. 애플리케이션 옵션은 GStreamer의 표준 옵션과 함께 파싱됨.


요소 Element

GStreamer에서 애플리케이션 프로그래머에게 가장 중요한 객체는 GstElement 객체임. 요소는 미디어 파이프라인의 기본 빌딩 블록임. 사용자가 사용할 다양한 고수준 구성 요소는 모두 GstElement에서 파생됨. 모든 디코더, 인코더, 디멀티플렉서, 비디오 또는 오디오 출력은 사실 GstElement임.

요소란?

애플리케이션 프로그래머에게 요소는 검은 상자처럼 시각화됨. 한쪽 끝에 뭔가를 넣으면, 요소가 그것을 처리하고 다른 쪽 끝에서 뭔가가 나옴. 예를 들어 디코더 요소의 경우, 인코딩된 데이터를 넣으면 요소가 그것을 디코딩한 후 디코딩된 데이터를 출력함.

소스 요소

소스 요소는 파이프라인에서 사용할 데이터를 생성함. 예를 들어 디스크에서 읽거나 사운드 카드에서 읽는 작업을 함. 소스 요소는 데이터를 받아들이지 않고 데이터를 생성함. 소스 요소는 항상 우측에 소스 패드를 그림.

필터, 변환기, 디멀티플렉서, 멀티플렉서, 코덱

필터와 필터 유사 요소는 입력과 출력 패드를 모두 가짐. 입력(싱크) 패드에서 데이터를 받고, 출력(소스) 패드에서 데이터를 제공함. 예시로는 볼륨 요소(필터), 비디오 스케일러(변환기), Ogg 디멀티플렉서 또는 Vorbis 디코더가 있음.

싱크 요소

싱크 요소는 미디어 파이프라인의 끝 지점임. 데이터를 받아들이지만 데이터를 생성하지 않음. 디스크 쓰기, 사운드 카드 재생, 비디오 출력 등이 싱크 요소로 구현됨.

GstElement 생성하기

GstElement를 생성하는 가장 간단한 방법은 gst_element_factory_make()를 사용하는 것임. 이 함수는 팩토리 이름과 새로 생성된 요소의 이름을 받아들임. 요소 이름은 나중에 해당 요소를 찾는 데 사용될 수 있음.

GstElement를 GObject로 사용하기

GstElement는 여러 속성을 가질 수 있으며, 이 속성들은 표준 GObject 속성으로 구현됨. GObject 메소드를 사용해 속성 값을 조회하고 설정할 수 있음. 대부분의 플러그인은 추가적인 속성을 제공하여 플러그인의 설정이나 구성 정보를 제공함.

요소 팩토리

GstElementFactory 객체는 요소를 생성하는 기본적인 방법을 제공함. 팩토리는 GStreamer 레지스트리에서 모든 플러그인과 요소를 설명하는 기본 유형임. 팩토리는 자동화된 요소 인스턴스화, 예를 들어 자동 플러그인 등에 유용하게 사용됨.

패드와 연결하기

소스 요소를 필터 요소와 싱크 요소와 연결함으로써 미디어 파이프라인을 설정함. 데이터는 요소를 통해 흐름. 이는 GStreamer에서 미디어 처리의 기본 개념임.

요소 상태

요소가 생성된 후, 실제로 동작하기 위해서는 상태를 변경해야 함. GStreamer는 네 가지 요소 상태를 가짐:

  • GST_STATE_NULL: 기본 상태. 이 상태에서는 자원이 할당되지 않음.
  • GST_STATE_READY: 글로벌 자원을 할당하고, 스트림을 열지는 않음.
  • GST_STATE_PAUSED: 스트림이 열렸지만 데이터를 처리하지 않음.
  • GST_STATE_PLAYING: 스트림이 실제로 재생되고 데이터가 처리됨.

gst_element_set_state() 함수를 사용하여 요소의 상태를 변경할 수 있음. 상태가 GST_STATE_PLAYING으로 설정되면 파이프라인은 데이터를 자동으로 처리하기 시작함.


프로그램 개발


빈(Bins)

빈은 컨테이너 요소임. 요소를 빈에 추가할 수 있음. 빈은 자체가 요소이기 때문에 다른 요소처럼 취급할 수 있음. 따라서 이전 장(요소)에서 다룬 내용은 빈에도 동일하게 적용됨.

빈이란?

빈은 연결된 요소들을 하나의 논리적인 요소로 결합할 수 있게 해줌. 이제 개별 요소들이 아닌 하나의 요소인 빈만 다루면 됨. 복잡한 파이프라인을 만들 때 매우 유용함. 파이프라인을 더 작은 단위로 나눠서 구성할 수 있게 해줌.

빈은 자신이 포함하는 요소들을 관리함. 요소들에 대한 상태 변경을 처리하고, 버스 메시지를 수집하여 전달함.


빈 생성하기

빈은 다른 요소들을 생성하는 것과 동일한 방식으로 생성됨. 즉, 요소 팩토리를 사용함. gst_bin_new()gst_pipeline_new()와 같은 편의 함수들도 제공됨. 빈에 요소를 추가하거나 제거하려면 gst_bin_add()gst_bin_remove()를 사용함. 빈에 요소를 추가하면 그 빈이 해당 요소를 소유하게 됨. 빈을 파괴하면 그 안의 요소도 함께 참조 해제됨. 요소를 빈에서 제거하면 자동으로 참조 해제됨.

사용자 정의 빈

애플리케이션 프로그래머는 특정 작업을 수행할 수 있도록 요소들로 구성된 사용자 정의 빈을 만들 수 있음. 예를 들어, 다음 코드를 통해 Ogg/Vorbis 디코더를 작성할 수 있음.

(이 예시는 간단한 예시일 뿐이고, 실제로는 훨씬 더 강력하고 다용도로 사용할 수 있는 playbin 요소 같은 사용자 정의 빈이 이미 있음.)

사용자 정의 빈은 플러그인으로 만들거나 애플리케이션에서 직접 만들 수 있음. 더 많은 정보는 플러그인 작성자 가이드에서 확인할 수 있음.

빈은 자식 요소들의 상태를 관리함

빈은 그 안에 포함된 모든 요소들의 상태를 관리함. 빈을 특정 상태로 설정하면, 그 빈에 포함된 모든 요소들이 그 상태로 설정됨. 이로 인해 일반적으로 파이프라인의 최상위 상태만 설정해도 파이프라인을 시작하거나 종료할 수 있음.

빈은 자식 요소들의 상태 변경을 처리함. 예를 들어, 파이프라인을 종료할 때는 싱크 요소부터 상태가 변경되고, 그 후에 업스트림 요소들이 상태를 변경함. 이를 통해 다운스트림 요소가 데이터를 받을 준비가 되도록 함.

하지만 이미 실행 중인 파이프라인에 요소를 추가할 때는, 예를 들어 "pad-added" 신호 콜백 내에서 요소를 추가할 경우, 해당 요소는 자동으로 빈이나 파이프라인의 현재 상태나 목표 상태와 일치하지 않음. 이 경우, gst_element_set_state()gst_element_sync_state_with_parent()를 사용하여 상태를 수동으로 설정해야 함.


버스(Bus)

버스는 스트리밍 스레드에서 애플리케이션의 스레드 컨텍스트로 메시지를 전달하는 간단한 시스템임. 버스의 장점은 GStreamer가 내부적으로 스레드를 많이 사용하지만 애플리케이션은 스레드에 대해 신경 쓸 필요가 없다는 점임.

모든 파이프라인은 기본적으로 버스를 포함하고 있으므로 애플리케이션은 별도로 버스를 생성할 필요 없음. 애플리케이션은 단지 버스에 메시지 핸들러를 설정하면 됨. 메인 루프가 실행 중일 때, 버스는 주기적으로 새로운 메시지가 있는지 확인하고, 메시지가 있을 때 콜백을 호출함.


버스를 사용하는 방법

  1. GLib/Gtk+ 메인 루프 실행: GLib 메인 루프는 주기적으로 버스를 확인하고 새로운 메시지가 있을 때 알림을 보내므로, gst_bus_add_watch() 또는 gst_bus_add_signal_watch()를 사용하여 이를 구현함.
  2. 버스에서 직접 메시지 확인: gst_bus_peek()gst_bus_poll()를 사용하여 버스를 직접 확인할 수 있음.

핸들러는 메인 루프의 스레드 컨텍스트에서 호출됨. 즉, 파이프라인과 애플리케이션 간의 상호작용은 비동기적이며, 일부 실시간 처리에는 적합하지 않음. 예를 들어 오디오 트랙 간 크로스페이딩이나 무간격 재생, 비디오 효과 등은 파이프라인 내에서 처리하는 게 더 적합함. 그러나 버스는 파이프라인에서 애플리케이션으로 메시지를 전달하는 데 매우 유용함.


메시지 유형

GStreamer는 버스를 통해 전달되는 몇 가지 사전 정의된 메시지 유형이 있음. 메시지는 확장 가능하고, 플러그인이 추가 메시지를 정의할 수 있음. 애플리케이션은 오류 메시지를 처리하는 것이 좋음. 모든 메시지는 메시지의 출처, 유형 및 타임스탬프를 가짐. 메시지의 출처를 통해 어떤 요소가 메시지를 보냈는지 확인할 수 있음.

  • 오류, 경고, 정보 알림: 요소들이 파이프라인의 상태에 대해 사용자에게 표시해야 할 메시지를 전달할 때 사용됨.
  • 스트림 종료 알림: 스트림이 종료되었을 때 발생. 상태는 변경되지 않지만, 미디어 처리가 멈춤.
  • 태그: 스트림에서 메타데이터가 발견되었을 때 발생.
  • 상태 변경: 상태 변경이 성공적으로 완료된 후 발생.
  • 버퍼링: 네트워크 스트림 캐싱 중 발생. 진행 상황을 추출할 수 있음.
  • 요소 메시지: 특정 요소에 고유한 메시지. 요소의 문서에 어떤 메시지가 전송될 수 있는지 설명됨.
  • 애플리케이션 특정 메시지: 내부 사용을 위한 메시지. 주로 애플리케이션이 스레드 간 정보를 전달할 때 사용됨.

Pads와 Capabilities

Pads

Pads는 요소가 외부와 연결되는 인터페이스임. 데이터는 한 요소의 소스 Pad에서 다른 요소의 싱크 Pad로 흐름. 요소가 처리할 수 있는 미디어 타입은 Pad의 능력(능력)을 통해 알 수 있음. 능력에 대해서는 나중에 이 장에서 더 다룰 예정임.

Pad 타입은 두 가지 속성으로 정의됨: 방향과 가용성. 방향은 소스 Pad와 싱크 Pad 두 가지로 나뉘며, 요소는 싱크 Pad에서 데이터를 받고 소스 Pad에서 데이터를 생성함. 싱크 패드는 왼쪽에, 소스 패드는 오른쪽에 그려짐. 데이터는 왼쪽에서 오른쪽으로 흐름.

Pad의 가용성은 세 가지로 나뉨: 항상(Always), 때때로(Sometimes), 요청 시(On request). '항상'은 항상 존재하는 Pad, '때때로'는 특정 경우에만 존재하는 Pad, '요청 시'는 애플리케이션에서 요청할 때만 생성되는 Pad임.


동적(또는 때때로) Pads

일부 요소는 생성 시 모든 Pads를 가지지 않을 수 있음. 예를 들어 Ogg 디멀티플렉서 요소는 Ogg 스트림을 읽고 각 요소 스트림(예: vorbis, theora)을 감지할 때마다 동적 패드를 생성함. 스트림이 끝나면 패드를 삭제함. 이는 디멀티플렉서 요소에서 유용함.

gst-inspect-1.0 oggdemux를 실행하면 이 요소가 단 하나의 패드만 가지며, 다른 패드는 "유휴" 상태임을 볼 수 있음. '때때로' 패드 템플릿에서 이를 확인할 수 있음. Ogg 파일 유형에 따라 패드가 생성됨. "pad-added" 신호 핸들러를 설정하여 동적으로 생성된 패드를 처리할 수 있음.


요청 패드

요소는 요청 패드를 가질 수 있음. 이 패드는 자동으로 생성되지 않고, 필요할 때만 생성됨. 멀티플렉서, 집합기, 티 요소에서 유용함. 티 요소는 하나의 입력 스트림을 받아 각 출력 패드로 복사할 수 있는 요소로, 스트림이 필요할 때마다 새로운 출력 패드를 요청할 수 있음.


Capabilities

패드는 자신이 처리할 수 있는 미디어 타입을 정의하는 능력 정보를 가짐. 능력은 패드 템플릿과 패드에 첨부됨. 패드 템플릿에서는 패드가 생성될 때 해당 패드가 처리할 수 있는 미디어 타입을 설명함. 패드에서는 패드 템플릿에서 정의된 미디어 타입이나 현재 흐르는 미디어 타입을 설명함.

패드의 능력은 GstCaps 객체로 설명됨. GstCaps는 하나 이상의 GstStructure를 포함하고 있으며, 각 구조체는 하나의 미디어 타입을 설명함. 협상된 패드는 능력 집합을 가지며, 이 집합에는 고정된 값만 포함됨. 협상되지 않은 패드나 패드 템플릿은 고정되지 않은 값들을 포함할 수 있음.


Capabilities 예시

예를 들어, "vorbisdec" 요소의 능력을 확인할 수 있음. 이 요소는 두 개의 패드를 가지며, 각각의 패드는 항상 사용 가능하고 각 패드에는 능력이 첨부되어 있음. 싱크 패드는 "audio/x-vorbis" 유형의 인코딩된 오디오 데이터를 수용하며, 소스 패드는 디코딩된 오디오 샘플을 전달함.

패드 템플릿:

  • SRC 템플릿: 'src'

    • 가용성: 항상
    • 능력:
      • audio/x-raw
        • format: F32LE
        • rate: [ 1, 2147483647 ]
        • channels: [ 1, 256 ]
  • SINK 템플릿: 'sink'

    • 가용성: 항상
    • 능력:
      • audio/x-vorbis


Capabilities 사용 목적

능력은 두 패드 사이에서 흐르는 데이터 유형을 설명하므로 여러 목적에 유용함:

  • 자동 플러그인: 패드의 능력을 기준으로 자동으로 연결할 요소를 찾을 수 있음.
  • 호환성 검증: 두 패드가 동일한 미디어 타입을 다루고 있는지 확인함. 이를 "능력 협상"이라고 함.
  • 메타데이터: 패드에서 능력을 읽어 미디어의 유형을 확인하고 스트림 정보를 제공함.
  • 필터링: 애플리케이션이 두 패드 사이에서 허용되는 미디어 유형을 제한할 수 있음. 필터된 능력을 사용하여 특정 형식의 비디오 크기나 오디오 샘플링 속도를 설정할 수 있음.

고스트 패드

고스트 패드는 빈 요소에서 사용하는 특수한 패드임. 빈 자체는 패드가 없지만, 고스트 패드를 사용하면 빈에서도 패드를 생성하고 이를 다른 코드에서 사용할 수 있음. 고스트 패드는 일반적인 패드처럼 동작하며, gst_ghost_pad_new() 함수로 생성함.


버퍼와 이벤트

파이프라인을 통해 흐르는 데이터는 버퍼와 이벤트의 조합으로 이루어짐. 버퍼는 실제 미디어 데이터를 포함하고, 이벤트는 탐색 정보나 스트림 종료 알림과 같은 제어 정보를 포함함. 이 모든 것은 파이프라인이 실행 중일 때 자동으로 흐름. 이 장에서는 개념을 설명하는 데 중점을 둠. 실제로는 직접 다룰 필요는 없음.


버퍼

버퍼는 생성한 파이프라인을 통해 흐를 미디어 데이터를 포함함. 일반적으로 소스 요소는 새로운 버퍼를 생성하고 이를 패드를 통해 다음 요소로 전달함. GStreamer 인프라를 사용할 때, 버퍼를 직접 다룰 필요는 없음. 요소들이 이를 자동으로 처리함.

버퍼는 다음과 같은 요소들로 구성됨:

  • 메모리 객체에 대한 포인터: 메모리 객체는 메모리의 특정 영역을 캡슐화함.
  • 타임스탬프: 버퍼의 시간 정보를 나타냄.
  • 참조 카운트: 이 버퍼를 사용하는 요소의 수를 나타냄. 참조 카운트가 0이 되면 버퍼는 파괴됨.
  • 버퍼 플래그: 버퍼의 상태를 나타냄.

일반적인 경우, 버퍼는 생성되어 메모리가 할당되고, 데이터가 넣어진 후 다음 요소로 전달됨. 해당 요소는 데이터를 읽고 처리한 후 새 버퍼를 생성하여 데이터를 디코딩하고 기존 버퍼는 참조 해제되어 파괴됨. 전형적인 비디오나 오디오 디코더가 이와 같이 동작함.

복잡한 시나리오도 존재함. 요소는 버퍼를 제자리에서 수정할 수 있음(새 버퍼를 할당하지 않고). 또한 요소는 하드웨어 메모리(예: 비디오 캡처 소스)나 X 서버에서 할당된 메모리(XShm)를 사용할 수 있음. 버퍼는 읽기 전용일 수도 있음.


이벤트

이벤트는 파이프라인에서 버퍼와 함께 상하류로 전달되는 제어 정보임. 하류 이벤트는 스트림 상태를 알리기 위해 사용됨. 가능한 이벤트로는 탐색, 플러시, 스트림 종료 알림 등이 있음. 상류 이벤트는 애플리케이션과 요소 간, 또는 요소 간 상호작용에서 스트림 상태 변경 요청(예: 탐색)을 위해 사용됨. 애플리케이션에서는 상류 이벤트만 중요함. 하류 이벤트는 데이터 개념을 이해하기 위해 설명됨.


첫 번째 애플리케이션

이 장에서는 이전 장에서 배운 모든 내용을 요약함. GStreamer 애플리케이션의 모든 측면을 다루며, 라이브러리 초기화, 요소 생성, 요소를 파이프라인에 넣고 이를 실행하는 방법을 설명함. 이를 통해 간단한 Ogg/Vorbis 오디오 플레이어를 만들 수 있게 됨.


헬로 월드

간단한 첫 번째 애플리케이션을 만들 것임. Ogg/Vorbis 명령어 기반 오디오 플레이어를 만들 예정임. 여기서는 기본 GStreamer 구성 요소만 사용할 것임. 이 플레이어는 명령어로 지정한 파일을 읽어서 재생함. 시작하자!

1. GStreamer 초기화: 애플리케이션에서 첫 번째로 해야 할 일은 gst_init()을 호출하여 GStreamer를 초기화하는 것임. #include <gst/gst.h>를 통해 GStreamer의 함수와 객체들이 제대로 정의되도록 함.

2. 요소 생성: Ogg/Vorbis 오디오 플레이어를 위해서는 파일을 읽는 소스 요소, 파일을 파싱하고 원시 오디오로 디코딩하는 요소가 필요함. GStreamer에는 이를 위한 두 가지 요소가 있음:

  • “filesrc”: 파일 소스 요소
  • “oggdemux”: Ogg 스트림을 분리하는 요소
  • “vorbisdec”: Vorbis 오디오 디코더

또한, oggdemux는 동적 패드를 생성하므로, 이를 처리하기 위해 “pad-added” 이벤트 핸들러를 설정해야 함. 마지막으로 오디오 출력 요소인 **“autoaudiosink”**를 사용해 오디오 장치를 자동으로 감지하여 재생함.

3. 파이프라인 구성: 모든 요소를 GstPipeline에 추가하고, 파이프라인이 실행되도록 상태를 설정한 후, 오류를 처리하고 스트림 종료를 감지할 수 있도록 메시지 핸들러를 설정함.


컴파일 및 실행

이 코드를 컴파일하려면 다음과 같은 명령을 사용함

예시) gcc -Wall helloworld.c -o helloworld $(pkg-config --cflags --libs gstreamer-1.0)

GStreamer는 pkg-config를 사용해 컴파일러와 링커 플래그를 자동으로 설정함.

비표준 설치를 사용하는 경우(예: 소스에서 직접 GStreamer를 설치한 경우), PKG_CONFIG_PATH 환경 변수를 적절한 경로로 설정해야 함.


결론

이제 첫 번째 간단한 오디오 플레이어가 완성됨. 파이프라인을 설정하는 것이 매우 기본적이지만 강력함. 이후 더 높은 수준의 인터페이스를 사용하여 더 강력한 미디어 플레이어를 쉽게 만들 수 있음. 이 과정에서 GStreamer 요소의 재사용성을 알 수 있으며, 네트워크 스트림, 다른 미디어 유형, 다른 오디오 장치 등 다양한 요소로 확장할 수 있음.





3. 고급 GStreamer 개념

이전 장에서 배운 기본적인 내용을 통해 간단한 애플리케이션을 만들 수 있을 것이지만, GStreamer는 멀티미디어 재생을 위한 기본 이상의 기능을 제공함. 이 장에서는 GStreamer의 더 고급 기능과 일부 저수준 내부 동작을 다룰 예정임.

이 장의 일부 챕터는 GStreamer의 내부 동작 방식을 설명하는 데 중점을 두고 있음. 예를 들어, 스케줄링, 자동 플러그인, 동기화 등이 이에 해당함. 이러한 지식은 실제 애플리케이션 개발에서는 필수적이지 않지만, GStreamer가 어떻게 동작하는지 이해하는 데 유용함. 다른 챕터에서는 애플리케이션과 파이프라인 간의 상호작용을 보다 고급 방식으로 다룬 내용을 다룰 예정임. 여기에는 메타데이터, 쿼리 및 이벤트, 인터페이스, 동적 파라미터 및 파이프라인 데이터 조작이 포함됨.

서브페이지:

  • 위치 추적 및 탐색
  • 메타데이터
  • 인터페이스
  • GStreamer의 클럭과 동기화
  • 버퍼링
  • 동적 제어 가능한 파라미터
  • 스레드
  • 자동 플러그인
  • 파이프라인 조작

위치 추적 및 탐색

이전까지 우리는 미디어 처리 파이프라인을 만드는 방법과 이를 실행하는 방법에 대해 배웠음. 대부분의 애플리케이션 개발자는 미디어 진행 상황에 대한 피드백을 사용자에게 제공하려 할 것임. 예를 들어, 미디어 플레이어는 노래의 진행 상황을 표시하는 슬라이더와 스트림 길이를 나타내는 라벨을 제공하고자 할 수 있음. 트랜스코딩 애플리케이션은 작업이 얼마나 진행되었는지 표시하는 진행 바를 원할 수 있음. GStreamer는 이를 위한 내장된 지원을 제공하며, 이를 쿼리(Querying)라는 개념을 사용하여 처리함. 탐색(Seeking)도 유사하므로 함께 다룰 것임. 탐색은 이벤트를 사용하여 처리함.

쿼리: 스트림의 위치 또는 길이 얻기

쿼리는 진행 상황 추적과 관련된 특정 스트림 속성을 요청하는 것으로 정의됨. 이에는 스트림의 길이를 얻거나 현재 위치를 얻는 것이 포함됨. 이러한 스트림 속성은 시간, 오디오 샘플, 비디오 프레임 또는 바이트 등의 형식으로 반환될 수 있음. 이를 위해 가장 많이 사용되는 함수는 gst_element_query()이며, 일부 편리한 래퍼 함수인 gst_element_query_position()gst_element_query_duration()도 제공됨. 일반적으로 파이프라인을 직접 쿼리하면 내부 세부 사항을 파악하여 적절한 요소를 쿼리해줌.

쿼리는 내부적으로 싱크로 전송되고, "분배"되어 처리할 수 있는 요소로 전달됨. 일반적으로 이는 디멀티플렉서에서 처리되지만, 라이브 소스(예: 웹캠)에서는 소스 요소가 처리함.


이벤트: 탐색(및 그 외)

이벤트는 쿼리와 매우 유사하게 동작함. 예를 들어 이벤트도 동일한 방식으로 분배되며, 파이프라인의 최상위에서 처리되도록 보낼 수 있음. 애플리케이션과 요소 간의 상호작용에서 이벤트를 사용하여 스트림 상태를 변경할 수 있는데, 여기서는 탐색을 중점적으로 다룰 것임. 탐색은 seek-event를 사용하여 처리함.

seek-event는 다음과 같은 속성을 포함함:

  • 재생률(Playback rate): 얼마나 빨리 스트리밍이 진행될지.
  • 오프셋 형식(Seek offset format): 시간, 오디오 샘플, 비디오 프레임, 바이트 등과 같은 오프셋의 단위.
  • 탐색 관련 플래그: 내부 버퍼를 플러시해야 하는지 여부 등.
  • 탐색 방법(Seek method): 오프셋이 상대적일지 절대적일지 등을 나타냄.
  • 탐색 오프셋: 새 위치(시작)와 선택적으로 종료 위치(정지)를 지정.

탐색을 수행할 때 GST_SEEK_FLAG_FLUSH 플래그는 파이프라인이 PAUSED 또는 PLAYING 상태일 때만 사용해야 함. 그렇지 않으면 파이프라인이 "프리롤링(prerolling)" 상태로 들어가고, 새로운 데이터를 처리할 때까지 기다리게 됨. 이 과정은 내부적으로 다른 스레드에서 처리되며, 실시간으로 완료되지 않을 수 있음. 따라서 함수 호출이 즉시 탐색이 완료되었다는 것을 보장하지 않음.

탐색을 비플러시(GST_SEEK_FLAG_FLUSH 없이) 방식으로 할 경우, 파이프라인이 PLAYING 상태일 때만 수행할 수 있음. PAUSED 상태에서 비플러시 탐색을 시도하면 잠재적으로 데드락이 발생할 수 있음.

탐색 후, 파이프라인은 다시 PLAYING 상태로 돌아가며, 새 위치에서 데이터 처리가 시작됨.


메타데이터

GStreamer는 두 가지 유형의 메타데이터를 명확히 구분하여 지원함:

  1. 스트림 태그(Stream tags): 스트림의 내용을 기술적인 방식이 아닌 일반적인 방식으로 설명하는 메타데이터. 예를 들어, 노래의 저자, 제목, 앨범 등의 정보.
  2. 스트림 정보(Stream-info): 스트림의 속성을 기술적인 방식으로 설명하는 메타데이터. 예를 들어, 비디오 크기, 오디오 샘플링 속도, 사용된 코덱 등.

태그는 GStreamer의 태깅 시스템을 통해 처리되며, 스트림 정보는 GstPad에서 현재 협상된(negotiated) GstCaps를 통해 얻을 수 있음.


메타데이터 읽기

스트림 정보를 읽는 가장 쉬운 방법은 GstPad에서 읽는 것임. 이는 원하는 스트림 정보에 해당하는 모든 패드에 접근해야 함. 이 방식은 Using capabilities for metadata에서 이미 다룬 바 있으므로 여기서는 생략함.

태그를 읽는 것은 GStreamer의 버스를 통해 이루어짐. GST_MESSAGE_TAG 메시지를 수신하여 이를 처리할 수 있음. 이 메시지는 여러 번 발생할 수 있기 때문에, 애플리케이션에서는 이를 집계하고 일관되게 표시해야 함. 예를 들어, 새 제목이 나왔다면 이전 제목보다 우선하도록 GST_TAG_MERGE_PREPEND 방식으로 병합해야 함.


태그 작성

태그 작성은 GstTagSetter 인터페이스를 사용하여 수행됨. 파이프라인에서 태그 세팅을 지원하는 요소가 필요함.

파이프라인의 요소가 태그 쓰기를 지원하는지 확인하려면 gst_bin_iterate_all_by_interface (pipeline, GST_TYPE_TAG_SETTER) 함수를 사용할 수 있음. 이후 해당 요소에서 gst_tag_setter_merge_tags() 또는 gst_tag_setter_add_tags()를 사용하여 태그를 추가하거나 병합할 수 있음.

GStreamer의 태그 지원의 장점 중 하나는 태그가 파이프라인에서 보존된다는 것임. 즉, 태그가 포함된 파일을 다른 태그 지원 미디어 형식으로 트랜스코딩하면, 태그가 데이터 스트림의 일부분으로 처리되어 새로 작성된 미디어 파일에 병합됨.


인터페이스

GObject를 사용하여 요소를 다루는 것은 애플리케이션과 요소가 상호작용할 수 있는 간단한 방법을 제공하지만, 이는 단순한 getter와 setter에만 적합함. 더 복잡한 사용 사례를 처리하기 위해 GStreamer는 GObject의 GTypeInterface를 기반으로 한 인터페이스를 사용함.

이 텍스트는 입문용으로, 소스 코드 예시는 포함되지 않음. 추가적인 세부 사항은 API 참조를 참고할 것.


URI 핸들러 인터페이스

지금까지 예시에서는 "filesrc" 요소를 사용하여 로컬 파일만 처리했지만, GStreamer는 다양한 위치 소스를 지원함.

GStreamer는 애플리케이션이 URI에 대한 구체적인 사항을 알 필요 없이 작업할 수 있도록 해줌. 이 세부 사항은 GstURIHandler 인터페이스를 통해 추상화됨.

URI 이름 지정에는 엄격한 규칙이 없지만, 일반적으로 다음과 같은 표준 명명 규칙을 따름:

  • file:///<path>/<file>
  • http://<host>/<path>/<file>
  • rtsp://<host>/<path>
  • dvb://<CHANNEL>

특정 URI를 지원하는 소스 또는 싱크 요소를 얻으려면 gst_element_make_from_uri()를 사용하면 됨. 방향에 따라 GST_URI_SRC 또는 GST_URI_SINK를 사용함.

파일명을 URI로 변환하거나 그 반대로 변환하려면 GLib의 g_filename_to_uri()g_uri_to_filename()을 사용하면 됨.


색상 균형 인터페이스

GstColorBalance 인터페이스는 요소에서 비디오 관련 속성(예: 밝기, 대비 등)을 제어하는 방법을 제공함. 이 인터페이스의 목적은 GObject를 사용하여 동적으로 속성을 등록하는 방법이 없기 때문에 만들어짐.

이 색상 균형 인터페이스는 여러 플러그인에서 구현되며, 여기에는 xvimagesink, glimagesink, Video4linux2 요소들이 포함됨.


비디오 오버레이 인터페이스

GstVideoOverlay 인터페이스는 애플리케이션 창에 비디오 스트림을 삽입하는 문제를 해결하기 위해 만들어짐. 애플리케이션은 이 인터페이스를 구현한 요소에 창 핸들을 제공하면, 해당 요소는 새로운 최상위 창을 생성하는 대신 제공된 창 핸들을 사용하여 비디오를 표시함. 이는 비디오 플레이어에 비디오를 삽입할 때 유용함.

이 인터페이스는 Video4linux2 요소와 glimagesink, ximagesink, xvimagesink, sdlvideosink와 같은 다른 요소에서 구현됨.


기타 인터페이스

GStreamer는 다양한 인터페이스를 제공하며, 일부 요소에서 이를 구현함. 그 예시는 다음과 같음:

  • GstChildProxy: 다중 자식 요소의 내부 속성에 접근하기 위해 사용
  • GstNavigation: 탐색 이벤트를 보내고 파싱하기 위한 인터페이스
  • GstPreset: 요소의 프리셋을 처리하기 위한 인터페이스
  • GstRTSPExtension: RTSP 확장 인터페이스
  • GstStreamVolume: 스트림 볼륨 레벨에 접근하고 제어하기 위한 인터페이스
  • GstTagSetter: 미디어 메타데이터를 처리하기 위한 인터페이스
  • GstTagXmpWriter: XMP 직렬화를 제공하는 요소를 위한 인터페이스
  • GstTocSetter: TOC와 유사한 데이터를 설정하고 검색하기 위한 인터페이스
  • GstTuner: RF 튜닝 작업을 제공하는 요소를 위한 인터페이스
  • GstVideoDirection: 비디오 회전 및 플립 제어를 위한 인터페이스
  • GstVideoOrientation: 비디오 방향 제어를 위한 인터페이스
  • GstWaylandVideo: Wayland 비디오 인터페이스


GStreamer의 클럭과 동기화

복잡한 미디어를 재생할 때 각 오디오 및 비디오 샘플은 특정 시간에 특정 순서로 재생되어야 함. 이를 위해 GStreamer는 동기화 메커니즘을 제공함.

GStreamer는 다음과 같은 사용 사례를 지원함:

  • 비실시간 소스: 파일에서 미디어를 읽고 동기화된 방식으로 재생하는 경우. 이때 오디오, 비디오, 자막 등 여러 스트림을 동기화해야 함.
  • 라이브 소스에서의 캡처 및 동기화된 멀티플렉싱/믹싱: 마이크나 카메라에서 오디오와 비디오를 캡처하고 이를 파일로 멀티플렉싱하는 경우.
  • 네트워크 스트리밍(버퍼링): HTTP를 사용해 스트리밍 서버에서 콘텐츠를 접근하는 경우.
  • 라이브 소스에서 캡처 및 지연 시간 조정된 재생: 예를 들어 카메라에서 캡처하고 효과를 적용하여 결과를 표시하는 경우.
  • 미리 녹음된 콘텐츠로부터의 동시 라이브 캡처 및 재생: 이전에 녹음된 오디오를 재생하면서 새로운 샘플을 녹음하는 경우.

GStreamer는 GstClock 객체, 버퍼 타임스탬프, SEGMENT 이벤트를 사용하여 파이프라인 내의 스트림을 동기화함.


클럭 실행 시간

컴퓨터에는 여러 시간 소스가 있음(예: 시스템 시간, 사운드 카드, CPU 성능 카운터 등). GStreamer는 이러한 여러 시간 소스를 위한 GstClock 구현을 제공함. 클럭 시간은 0부터 시작할 필요는 없으며, 일부 클럭은 특정 시작 날짜나 마지막 재부팅 시점부터 카운트하기 시작함.

GstClockgst_clock_get_time()을 사용하여 해당 클럭에 따른 절대 시간을 반환함. 절대 시간은 계속해서 증가함.

실행 시간(running-time)은 이전의 절대 시간 스냅샷인 base-time과 다른 절대 시간 간의 차이임

GstPipeline 객체는 PLAYING 상태로 갈 때 GstClock 객체와 base-time을 유지함. 이 클럭은 파이프라인 내의 모든 요소와 공유되어, 파이프라인의 실행 시간에 맞춰 동기화가 가능함.


버퍼 실행 시간

버퍼 실행 시간을 계산하려면, 해당 버퍼의 타임스탬프와 그 전에 발생한 SEGMENT 이벤트가 필요함. SEGMENT 이벤트를 GstSegment 객체로 변환한 후, gst_segment_to_running_time() 함수를 사용하여 버퍼의 실행 시간을 계산함.

버퍼의 실행 시간이 클럭 시간과 일치하도록 동기화하는 작업은 주로 싱크 요소에서 수행됨. 이 요소들은 파이프라인의 지연 시간을 고려하여 버퍼 실행 시간에 더하고 동기화 작업을 수행함.


버퍼 스트림 시간

버퍼 스트림 시간은 미디어의 총 길이 내에서 0과 총 길이 사이의 값으로, 버퍼 타임스탬프와 그 전에 발생한 SEGMENT 이벤트를 기반으로 계산됨.

버퍼 스트림 시간은 다음에서 사용됨:

  • 현재 스트림 위치를 보고하는 POSITION 쿼리.
  • 탐색 이벤트 및 쿼리에서 사용되는 위치.
  • 제어 값 동기화에서 사용되는 위치.

버퍼 스트림 시간은 스트림 간 동기화에 사용되지 않음. 스트림 동기화는 실행 시간을 기반으로 함.


시간 개요

여기서는 GStreamer에서 사용하는 다양한 타임라인에 대한 개요를 다룸. 아래 그림은 100ms 샘플을 재생하고 50ms에서 100ms까지의 구간을 반복하는 경우의 타임라인을 나타냄.

GStreamer 클럭과 다양한 시간

버퍼의 실행 시간은 항상 클럭 시간과 함께 증가하며, 버퍼는 실행 시간이 클럭 시간에서 base-time을 뺀 값과 같을 때 재생됨. 스트림 시간은 스트림 내의 위치를 나타내며 반복 시 뒤로 돌아감.


클럭 제공자

클럭 제공자는 파이프라인에서 GstClock 객체를 제공할 수 있는 요소임. 이 객체는 PLAYING 상태일 때 절대 시간이 증가하는 값을 제공해야 하며, PAUSED 상태에서는 클럭을 일시 중지할 수 있음.

클럭 제공자는 미디어를 일정한 비율로 재생하는 요소로, 이 비율은 시스템 클럭 비율과 반드시 일치하지 않음. 예를 들어, 사운드 카드가 44.1kHz로 재생하더라도, 시스템 클럭에서 1초가 지난 후 사운드 카드가 정확히 44100 샘플을 재생했다고 보장할 수 없음. 실제로 오디오 장치는 재생된 샘플 수를 기준으로 한 내부 클럭을 사용함.

파이프라인이 PLAYING 상태로 전환될 때, 모든 요소는 자신이 클럭을 제공할 수 있는지 확인함. 파이프라인에서 클럭을 제공할 수 있는 마지막 요소가 클럭 제공자가 됨.


지연 시간 (Latency)

지연 시간은 타임스탬프 X에서 캡처된 샘플이 싱크로 도달하는 데 걸리는 시간임. 이 시간은 파이프라인 내의 클럭을 기준으로 측정됨. 라이브 소스가 있는 파이프라인에서는 지연 시간이 발생할 수 있음. 예를 들어, 오디오 소스가 처음 샘플을 캡처할 때 타임스탬프가 0이고, 클럭 시간은 1초 이상이 될 경우, 싱크는 이 버퍼를 늦어서 드롭함. 이를 해결하기 위해 싱크에서 지연 시간 보상 기능을 사용해야 함.


지연 시간 보상

파이프라인이 PLAYING 상태로 전환되기 전에, 파이프라인은 LATENCY 쿼리를 통해 각 싱크의 지연 시간을 계산하고, 가장 큰 지연 시간을 선택하여 LATENCY 이벤트로 설정함. 이를 통해 모든 싱크는 동일한 지연 시간만큼 재생이 지연되므로 동기화됨.


동적 지연 시간

파이프라인에 요소를 추가하거나 제거하거나 요소 속성을 변경하면 파이프라인의 지연 시간이 변경될 수 있음. 요소는 지연 시간 변경을 요청할 수 있으며, 이때 애플리케이션은 새 지연 시간을 쿼리하고 재분배할지 결정할 수 있음. 지연 시간 변경은 시각적 또는 청각적인 결함을 일으킬 수 있으므로, 애플리케이션에서 허용되는 경우에만 수행해야 함.


버퍼링

버퍼링의 목적은 파이프라인에서 충분한 데이터를 축적하여 중단 없이 매끄럽게 재생될 수 있도록 하는 것이다. 일반적으로 (느린) 네트워크 소스에서 데이터를 읽을 때 사용되며, 라이브 소스에도 사용할 수 있다.

GStreamer는 다음과 같은 용도를 지원한다:

  • 데이터를 재생하기 전에 메모리에서 일정량의 데이터를 버퍼링하여 네트워크 변동을 최소화한다. (스트림 버퍼링 참조)
  • 네트워크 파일을 로컬 디스크에 다운로드하고 다운로드된 데이터에서 빠르게 탐색한다. (다운로드 버퍼링 참조)
  • (세미) 라이브 스트림을 로컬 디스크에 링 버퍼로 캐싱하여 캐시된 영역에서 탐색할 수 있게 한다. (타임시프트 버퍼링 참조)

GStreamer는 애플리케이션에 현재 버퍼링 상태에 대한 진행 상황을 보고하고, 애플리케이션이 어떻게 버퍼링할지와 언제 버퍼링을 멈출지 결정할 수 있게 한다.

가장 간단한 경우, 애플리케이션은 버스에서 BUFFERING 메시지를 듣는다. BUFFERING 메시지 내의 백분율 지표가 100 미만이면 파이프라인이 버퍼링 중이다. 100% 메시지를 받으면 버퍼링이 완료된다. 버퍼링 상태에서 애플리케이션은 파이프라인을 PAUSED 상태로 유지하고, 버퍼링이 완료되면 다시 PLAYING 상태로 전환할 수 있다.


스트림 버퍼링

+---------+ +---------+ +-------+
| httpsrc | | buffer | | demux | | src - sink src - sink .... +---------+ +---------+ +-------+

이 경우, 우리는 느린 네트워크 소스에서 데이터를 읽어 queue2 같은 버퍼링 요소에 전달한다.

버퍼링 요소는 바이트 단위로 낮은 경고선과 높은 경고선(워터마크)을 설정한다. 버퍼링 요소는 다음과 같이 워터마크를 사용한다:

  • 높은 워터마크가 도달하면 BUFFERING 메시지로 100%를 표시하고, 애플리케이션에 재생을 계속하라고 지시한다.
  • 재생 중에 낮은 워터마크에 도달하면 다시 BUFFERING 메시지를 보내어 파이프라인을 일시 정지시킨다. 이를 재버퍼링 단계라고 한다.
  • 재생 중에, 큐의 수준은 높은 워터마크와 낮은 워터마크 사이에서 변동하면서 네트워크 불규칙성을 보상한다.

다운로드 버퍼링

+---------+ +---------+ +-------+
| httpsrc | | buffer | | demux | | src - sink src - sink .... +---------+ +----|----+ +-------+ V file

서버가 고정 길이 파일을 스트리밍할 때, 애플리케이션은 파일 전체를 로컬에 다운로드할 수 있다. 버퍼링 요소는 다운로드된 파일에서 탐색할 수 있도록 push 또는 pull 방식의 srcpad를 제공한다.


타임시프트 버퍼링

+---------+ +---------+ +-------+
| httpsrc | | buffer | | demux | | src - sink src - sink .... +---------+ +----|----+ +-------+ V file-ringbuffer

이 모드에서는 서버 콘텐츠를 다운로드할 수 있는 고정 크기 링버퍼를 유지하여 캐시된 데이터에서 탐색할 수 있게 한다.


라이브 버퍼링

라이브 파이프라인에서는 캡처와 재생 요소 간에 고정된 지연 시간이 도입된다. 이 지연 시간은 queue(예: jitterbuffer)나 다른 방법(오디오 싱크)에 의해 발생할 수 있다. 버퍼링 메시지는 이 지연 버퍼링을 사용자에게 알리기 위해 방출된다.


버퍼링 전략

여기서는 BUFFERING 메시지와 BUFFERING 쿼리를 기반으로 구현할 수 있는 몇 가지 버퍼링 전략을 소개한다.


No-rebuffer 전략

이 전략은 파이프라인에서 데이터를 충분히 버퍼링하여 재생이 중단 없이 계속되도록 하는 것이다. 필요한 것은 파일의 총 남은 재생 시간과 총 남은 다운로드 시간이다. 버퍼링 시간이 재생 시간보다 짧다면, 중단 없이 재생을 시작할 수 있다.


동적 제어 가능한 매개변수

동적 제어 가능한 매개변수 시작하기 GStreamer 속성은 일반적으로 g_object_set()을 사용하여 설정되지만, 이러한 호출을 신뢰성 있게 타이밍을 맞추는 것은 불가능에 가깝다. 제어기 시스템은 스트림 시간에 맞춰 GObject 속성을 조정하는 간단한 방법을 제공한다.

제어기는 시간을 고려하여 작동하며, 제어 소스(GstControlSources)를 속성에 바인딩하여 이를 수행한다. 제어 소스는 보통 0.0에서 1.0 범위의 값을 제공하며, 제어 바인딩은 제어 값을 GObject 속성에 매핑하여 값을 변환하고 스케일링한다. 실행 중에는 요소들이 현재 스트림 시간에 맞춰 GObject 속성을 업데이트하기 위해 지속적으로 값 변화를 가져온다. GStreamer는 여러 가지 GstControlSources와 제어 바인딩을 제공하지만, 애플리케이션에서 직접 이를 확장하여 정의할 수 있다.

제어 메커니즘의 대부분은 GstObject에 구현되어 있으며, GstControlSources와 제어 바인딩의 기본 클래스는 코어 라이브러리에 포함되어 있지만, 기존 구현은 gstcontroller 라이브러리에 포함되어 있다. 

적절한 헤더를 포함하는 것 외에도, 애플리케이션은 gstreamer-controller 공유 라이브러리를 링크해야 한다. 

GstControlSource를 GObject 속성에 연결해야 한다. 이는 제어 바인딩을 사용하여 이루어진다. 하나의 제어 소스는 여러 개의 속성에 연결할 수 있다 (다른 객체의 속성에도 연결 가능).


스레드

GStreamer는 본질적으로 멀티 스레드 시스템이고, 완전히 스레드 안전함. 대부분의 내부 스레딩은 애플리케이션에서 숨겨져 있어서 애플리케이션 개발을 더 쉽게 만듦. 그러나 일부 경우에는 애플리케이션이 파이프라인의 일부에서 여러 스레드를 강제로 사용하는 등의 영향을 미칠 수 있음. GStreamer는 애플리케이션이 파이프라인의 일부에서 스레드를 강제로 사용할 수 있도록 허용함.


GStreamer에서의 스케줄링

각 요소는 어떻게 스케줄링될지를 결정함. 요소는 패드를 푸시 기반 또는 풀 기반으로 스케줄링할 수 있음. 예를 들어, 요소는 스레드를 시작해서 싱크 패드에서 데이터를 풀링하거나 소스 패드에서 푸시를 시작할 수 있음. GStreamer는 요소가 스케줄링되는 방식에 대해 어떤 제한도 두지 않음.

스레딩을 시작하는 요소들은 "스트리밍 스레드"라 불리는 스레드를 시작함. 스트리밍 스레드는 GstTask 객체로, 요소가 스트리밍 스레드를 만들 필요가 있을 때 GstTaskPool에서 생성됨.


GStreamer에서 스레드 구성하기

GStreamer는 스레드 상태를 알려주는 STREAM_STATUS 메시지를 버스에 전송함. 이 메시지는 스레드 생성 시, 스레드에 할당할 커스텀 GstTaskPool을 구성할 수 있는 정보를 제공함.

스레드를 생성할 때마다 GST_STREAM_STATUS_TYPE_CREATE 유형으로 알림을 받음. 이 때 GstTaskPool을 구성할 수 있으며, 커스텀 스레드 풀을 사용하여 스트리밍 스레드를 구현함.


스레드 우선순위 올리기

간단한 파이프라인에서 fakesrc 요소가 스트리밍 스레드를 시작하고 데이터를 fakesink로 푸시함. 스트리밍 스레드의 우선순위를 변경하려면, STREAM_STATUS 메시지를 처리하여 해당 스레드의 우선순위를 높일 수 있음.


우선순위가 높은 스레드 만들기

GStreamer에서 스레드를 강제로 사용할 수 있는 방법 중 하나는 queue 요소를 사용하는 것임. queue 요소는 스레드 경계를 설정하며, 이를 통해 파이프라인에서 두 개의 독립적인 스레드를 사용할 수 있음. queue는 기본적으로 데이터를 처리하는 스레드를 분리하고 버퍼로서 기능할 수 있음.

이와 같은 방식으로, GStreamer는 스레드 간의 데이터 흐름을 안전하게 처리하며, 다양한 데이터 버퍼링과 동기화 문제를 해결할 수 있음.


자동 플러깅 Autoplugging

이전의 첫 번째 애플리케이션에서는 Ogg/Vorbis 파일을 위한 간단한 미디어 플레이어를 만드는 방법을 배웠음. 하지만 이제는 스트림의 미디어 유형을 자동으로 감지하고 시스템에서 사용 가능한 모든 요소를 통해 최적의 파이프라인을 자동으로 생성하는 애플리케이션을 만들고 싶을 것임. 이 과정은 "자동 플러깅"이라고 하며, GStreamer에는 고품질의 자동 플러그거들이 있음. 자동 플러거를 찾고 있다면 Playback Components로 바로 넘어가면 됨. 이 장에서는 자동 플러깅과 유형 찾기(typefinding)의 개념을 설명하고, GStreamer가 어떻게 미디어 스트림의 유형을 동적으로 감지하고 이를 바탕으로 파이프라인을 생성하는지 설명함. 이 원칙들은 트랜스코딩에도 사용할 수 있음. GStreamer는 이 개념의 완전한 동적 특성 덕분에, 새로운 미디어 유형을 지원하기 위해 자동 플러거를 수정할 필요 없이 자동으로 확장할 수 있음.


미디어 유형을 통한 스트림 식별

우리는 이전에 미디어 유형을 식별하는 방법으로 캡슐화된 개념을 소개했음. 대부분의 컨테이너 포맷(예: Ogg)은 스트림을 설명하는데 속성이 필요하지 않으며, 미디어 유형만 필요함. GStreamer는 이 미디어 유형을 통해 스트림을 자동으로 식별함. 예를 들어 Ogg와 같은 미디어 유형이 각 패드에 연결될 때, GStreamer는 이들 패드가 예상하는 데이터 유형을 알고 있음. 이렇게 하면 GStreamer는 미디어 스트림을 자동으로 감지하고 적합한 파이프라인을 구성할 수 있음.


미디어 스트림 유형 감지

미디어 스트림을 로드할 때, 그 스트림의 유형이 바로 알려지지 않음. 즉, 파이프라인을 선택하기 전에 먼저 스트림 유형을 감지해야 함. GStreamer는 이를 "유형 찾기"라는 개념을 사용함. 유형 찾기는 파이프라인의 정상적인 일부로, 스트림 유형이 알려질 때까지 데이터를 읽음. 이 동안, GStreamer는 해당 스트림을 인식할 수 있는 모든 플러그인에게 데이터를 제공함. 하나의 타입 파인더가 스트림을 인식하면, 해당 타입을 감지한 후, 타입 파인더는 신호를 방출하고 그 이후에는 패스스루 모듈로 작동함. 만약 유형을 찾지 못하면, 오류가 발생하고 더 이상 미디어 처리가 진행되지 않음.

유형을 찾은 후, 애플리케이션은 이를 바탕으로 미디어 스트림을 디코딩할 파이프라인을 자동으로 설정할 수 있음.


플러그인에서의 타입 파인더 기능 구현

GStreamer에서 플러그인은 타입 파인더 기능을 구현할 수 있음. 플러그인 구현 시, 해당 미디어 유형에 대해 미디어 유형을 제출하고, 일반적으로 사용되는 파일 확장자 및 타입 찾기 함수도 정의함. 해당 함수가 호출되면, 플러그인은 이 미디어 스트림이 특정 패턴을 따르는지 확인하고, 이를 인식할 경우 타입 파인더에게 알려줌.


파이프라인 조작

이 장에서는 애플리케이션에서 파이프라인을 조작하는 다양한 방법을 소개함. 다룰 내용은 다음과 같음:

  • 애플리케이션에서 데이터를 파이프라인에 삽입하는 방법
  • 파이프라인에서 데이터를 읽는 방법
  • 파이프라인의 속도, 길이, 시작 지점을 조작하는 방법
  • 파이프라인의 데이터 처리 과정을 듣는 방법

이 장의 일부는 매우 저수준이므로, 이를 따라가려면 프로그래밍 경험과 GStreamer에 대한 깊은 이해가 필요함.


프로브 사용

프로빙은 패드 리스너에 접근하는 것처럼 이해할 수 있음. 기술적으로, 프로브는 gst_pad_add_probe()를 사용하여 패드에 부착할 수 있는 콜백 함수임. 반대로, gst_pad_remove_probe()를 사용하여 콜백을 제거할 수 있음. 프로브가 부착된 동안 패드에서 발생하는 활동을 알려줌. 프로브를 추가할 때 어떤 알림을 받을지 정의할 수 있음.


프로브 유형:

  • 버퍼가 푸시되거나 풀림: GST_PAD_PROBE_TYPE_BUFFER를 지정. 패드가 푸시 또는 풀 방식으로 예약될 수 있음.
  • 버퍼 리스트 푸시: GST_PAD_PROBE_TYPE_BUFFER_LIST를 사용.
  • 이벤트가 패드를 통해 이동: GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM 등을 사용.
  • 쿼리가 패드를 통해 이동: GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, GST_PAD_PROBE_TYPE_QUERY_UPSTREAM 등을 사용.

데이터 프로브

데이터 프로브는 패드를 통해 데이터가 흐를 때 알림을 받음. GST_PAD_PROBE_TYPE_BUFFER와 GST_PAD_PROBE_TYPE_BUFFER_LIST를 사용하여 이런 종류의 프로브를 생성할 수 있음.


데이터 수정

데이터 수정이 필요하다면 GStreamer 요소를 직접 작성하는 것이 더 적합함. GstAudioFilter, GstVideoFilter, GstBaseTransform 등의 기본 클래스를 사용하면 쉽게 작성할 수 있음.


미디어 파일의 특정 구간 재생

이 예제에서는 미디어 파일의 2초에서 5초 구간만 재생하고 종료하는 방법을 보여줌. uridecodebin을 사용하여 파이프라인을 설정하고, 해당 구간으로의 시킹을 수행함.


데이터 삽입 및 추출

자체 소스를 사용해 데이터를 삽입하거나, 파이프라인의 출력을 추출하려는 경우 appsrc와 appsink를 사용할 수 있음. 이 방법들은 기본 클래스 지원 없이 동기화 및 상태 변경을 철저히 이해하고 있어야 함.


appsrc를 사용한 데이터 삽입

appsrc는 푸시 또는 풀 모드에서 데이터를 파이프라인에 삽입할 수 있게 해줌. 앱이 데이터를 삽입하는 방법은 gst_app_src_push_buffer() 함수나 "push-buffer" 액션 신호를 사용하는 방식임.


appsink를 사용한 데이터 추출

appsink는 파이프라인에서 데이터를 추출하는 더 쉬운 방법임. pull-sample과 pull-preroll 신호를 사용하여 데이터를 추출할 수 있음.


포맷 강제 설정

특정 포맷을 설정하려면 capsfilter 요소를 사용할 수 있음. 예를 들어, 비디오 크기나 오디오 비트 크기 등을 강제할 수 있음.


PLAYING 상태에서 포맷 변경

capsfilter의 caps 속성을 변경하여 PLAYING 상태에서도 포맷을 동적으로 변경할 수 있음.


파이프라인 동적 변경

파이프라인을 동적으로 변경할 때 중요한 사항들을 다룸. 예를 들어, 요소를 제거하거나 추가할 때 데이터 흐름에 영향을 미치지 않도록 해야 함. 또한, 삽입된 요소가 올바르게 상태가 설정되어야 하며, 필요시 알맞은 변환 요소를 삽입해야 함.


파이프라인에서 요소 변경

파이프라인에서 요소를 변경하려면, 먼저 데이터 흐름을 차단하고, EOS 이벤트를 보내 데이터를 비우고, 요소를 교체한 후 다시 연결해야 함.


영상 효과 변경 예시

이 예제에서는 영상 효과를 1초마다 변경하는 방법을 보여줌. videotestsrc와 다양한 비디오 필터를 사용하여 효과를 동적으로 변경함.




4. GStreamer 을 위한 고급 인터페이스

앞서 두 부분에서는 GStreamer 애플리케이션 프로그래밍의 많은 내부 사항과 그에 해당하는 저수준 인터페이스를 배웠음. 하지만 많은 사람들은 그렇게 많은 제어(및 코드)를 원하지 않으며, 대부분의 어려운 내부 처리 작업을 대신해주는 표준 재생 인터페이스를 선호할 것임. 이 장에서는 자동 플러그거, 재생 관리 요소 및 그와 유사한 것들의 개념을 소개함. 이러한 고급 인터페이스들은 GStreamer 기반 애플리케이션 프로그래밍을 단순화하는 데 목적이 있음. 다만, 유연성은 감소시킬 수 있음. 어떤 인터페이스를 사용할지는 애플리케이션 개발자가 선택해야 함.


재생 구성 요소

GStreamer는 애플리케이션 개발자의 작업을 단순화하기 위해 여러 고급 구성 요소를 포함하고 있음. 여기에서 다룬 모든 구성 요소들은 현재 미디어 재생을 목표로 하고 있음. 이러한 각 구성 요소의 목적은 GStreamer 파이프라인과 최대한 밀접하게 통합되도록 하면서, 미디어 유형 탐지 및 고급 GStreamer 개념에서 다룬 여러 복잡한 주제들을 숨기는 것임.

우리는 현재 사람들에게 playbin(Playbin 참조)이나 decodebin(Decodebin 참조)을 필요에 따라 사용하는 것을 권장함. Playbin은 미디어의 간단한 재생과 관련된 모든 것에 추천되는 솔루션임. Decodebin은 더 많은 고급 기능을 추가할 수 있는 더 유연한 자동 플러그거로, 예를 들어 플레이리스트 지원, 오디오 트랙의 크로스페이드 등이 있음. 하지만 그 프로그래밍 인터페이스는 playbin보다 저수준임.


Playbin
Playbin은 표준 GStreamer API(예: gst_element_factory_make())를 사용하여 생성할 수 있는 요소임. 이 팩토리의 이름은 "playbin"임. GstPipeline(따라서 GstElement)이므로 playbin은 자동으로 이 클래스의 모든 기능을 지원함, 여기에는 오류 처리, 태그 지원, 상태 처리, 스트림 위치 가져오기, 탐색 등이 포함됨.

playbin 파이프라인 설정은 playbin 요소의 인스턴스를 생성하고, "uri" 속성에 파일 위치를 설정한 후, 요소를 GST_STATE_PLAYING 상태로 설정하는 것만큼 간단함(위치는 유효한 URI여야 하며, 예: file:///tmp/my.ogg 또는 http://www.example.org/stream.ogg). 내부적으로 playbin은 미디어 위치를 재생하기 위한 파이프라인을 설정함.

Playbin에는 이전에 논의한 여러 기능이 포함되어 있음:

  • 비디오 및 오디오 출력 설정 가능("video-sink" 및 "audio-sink" 속성 사용).
  • 대부분 GstElement로서 제어 및 추적 가능, 여기에는 오류 처리, eos 처리, 태그 처리, 상태 처리(GstBus 통해), 미디어 위치 처리 및 탐색 등이 포함됨.
  • 네트워크 소스를 버퍼링하며, 버퍼가 가득 차면 GstBus를 통해 버퍼 상태 알림.
  • 오디오 전용 미디어에 대해 시각화 지원.
  • 미디어 내 자막 및 별도 파일에서 자막 지원. 별도의 자막 파일에는 "suburi" 속성 사용.
  • 여러 오디오 또는 자막 트랙이 있는 경우, 어떤 트랙을 재생할지 동적으로 선택하거나 아예 끌 수 있음("current-text" 및 기타 관련 속성 사용).

명령줄에서 "playbin"을 테스트하려면 "gst-launch-1.0 playbin uri=file:///path/to/file" 명령을 사용할 수 있음.


Decodebin
Decodebin은 이전에 설명한 playbin의 실제 자동 플러그거 백엔드임.

Decodebin은 간단히 말해, 연결된 소스로부터 입력을 받아

미디어 유형을 탐지하고 각 유형에 대해 디코더 루틴을 설정함.

디코더를 자동으로 선택함.

디코딩된 각 스트림에 대해 "pad-added" 신호를 발생시켜

새로 발견된 디코딩된 스트림을 클라이언트에게 알림.

알려지지 않은 스트림(전체 스트림일 수도 있음)에 대해서는

"unknown-type" 신호를 발생시킴.

이때 애플리케이션은 오류를 사용자에게 보고할 책임이 있음.


Decodebin은 playbin처럼 다음과 같은 기능을 지원함:

  • 포함된 여러 스트림을 디코딩된 출력 패드로 디코딩할 수 있음.

  • 태그 또는 오류 전달, 상태 처리 등 모든 방식으로 GstElement로 처리됨.

  • decodebin은 좋은 자동 플러그거이지만, 여러 가지를 하지 않음:

    • 이미 미디어 유형이 알려진 입력 스트림 처리(예: DVD, 오디오 CD 등).
    • 스트림 선택(예: 다국어 미디어 스트림에서 오디오 트랙 선택).
    • 디코딩된 비디오 스트림 위에 자막 오버레이.

URIDecodebin
uridecodebin 요소는 decodebin과 매우 유사하지만,

URI의 프로토콜에 따라 자동으로 소스 플러그인을 연결함.

네트워크 소스가 느린 경우 버퍼링 요소도 자동으로 삽입함.


Playsink
playsink 요소는 강력한 싱크 요소로, 오디오, 비디오, 텍스트의 요청 패드를 가지고 있으며,

미디어 스트림을 재생할 수 있도록 스스로 구성됨.






5.부록


이제 GStreamer의 내부 구조와 GStreamer 프레임워크를 사용한

애플리케이션 프로그래밍에 대해 모두 배웠음.

이 부분에서는 GStreamer를 진지하게 애플리케이션 프로그래밍에 사용할 경우

유용한 몇 가지 정보를 다룰 것임.

여기에는 우리가 사용하는 인기 있는 데스크탑 환경(GNOME, KDE, OS X, Windows)과의 통합,

GStreamer와 함께 제공되는 애플리케이션이 어떻게 당신의 삶을 쉽게

만들어줄 수 있는지에 대한 설명, 그리고 디버깅 관련 정보가 포함됨.

또한 GStreamer-0.10 애플리케이션을 GStreamer-1.0으로 포팅하는 방법에

대한 포팅 가이드도 제공함.







[ Plugins ]


webrtcbin

webrtcbin은 가능한 한 W3의 peerconnection API와 구현 가이드를 구현한 요소임.

제안, 응답 생성 및 로컬/원격 SDP 설정 등이 지원됨.

미디어 설명과 데이터 채널을 포함한 설명도 지원됨.

각 입력/출력 패드는 W3에서 말하는 트랙에 해당하며, 이들은 webrtcbin에 추가/제거됨.

요청된 싱크 패드의 수는 수신자에게 전송될 스트림의 수와 같으며,

이는 GstWebRTCRTPTransceiver와 연결됨 (W3 RTPTransceiver와 매우 유사).

수신 측에서는 원격 설명을 설정한 후 RTPTransceiver가 생성됨.

설정된 설명에 포함된 수신 스트림에 대한 출력 패드도 데이터가 수신되면 생성됨.

TransportStream은 필요한 경우 데이터가 필요한 DTLS/ICE 채널을 통해

피어로 전송될 수 있도록 생성됨.

구성은 피어 간에 협상된 SDP에 따라 다르며, 번들 및 RTCP 구성에 따라 달라짐.

간단한 단일 오디오/비디오/데이터 세션에 대한 몇 가지 사례는 다음과 같음:

- max-bundle은 모든 미디어/데이터를 하나의 트랜스포트로 전송함.
재협상은 기존 트랜스포트에 필요한 스트림을 추가/제거하는 방식임.

- max-compat는 미디어 스트림마다 두 개의 트랜스포트 스트림을 사용하여
RTP와 RTCP 패킷을 전송하고, 모든 데이터 채널에 대해 하나의 트랜스포트 스트림을 사용함.
각 스트림 변경은 관련된 트랜스포트를 수정하는 방식임.


계층 구조

GObject
╰──GInitiallyUnowned ╰──GstObject ╰──GstElement ╰──GstBin ╰──webrtcbin

구현된 인터페이스

  • GstChildProxy

팩토리 세부 사항

  • 저자: Matthew Waters
  • 분류: 필터/네트워크/WebRTC
  • 랭크: 주요
  • 플러그인: webrtc
  • 패키지: GStreamer Bad Plug-ins

패드 템플릿

  • sink_%u

    • application/x-rtp
    • 존재: 요청
    • 방향: 싱크
    • 객체 유형: GstWebRTCBinSinkPad
  • src_%u

    • application/x-rtp
    • 존재: 가끔
    • 방향: 출발
    • 객체 유형: GstWebRTCBinSrcPad

시그널

  • on-data-channel: 새로운 데이터 채널이 생성되었을 때 발생
  • on-ice-candidate: ICE 후보가 발견되었을 때 발생
  • on-negotiation-needed: 협상이 필요할 때 발생
  • on-new-transceiver: 새로운 RTPTransceiver가 생성되었을 때 발생
  • prepare-data-channel: 데이터 채널 준비가 완료되었을 때 발생
  • request-aux-sender: 추가 전송기를 요청할 때 발생

액션 시그널

  • add-ice-candidate: ICE 후보를 추가하는 액션 시그널
  • add-transceiver: 새로운 트랜스시버를 추가하는 액션 시그널
  • create-answer: 응답을 생성하는 액션 시그널
  • create-data-channel: 데이터 채널을 생성하는 액션 시그널
  • create-offer: 제안을 생성하는 액션 시그널
  • get-stats: 세션 통계를 가져오는 액션 시그널

속성

  • bundle-policy: 번들링 정책 설정
  • connection-state: 연결 상태 확인
  • ice-agent: ICE 에이전트 설정
  • latency: 지터버퍼의 기본 대기 시간 설정
  • local-description: 로컬 설명 설정
  • remote-description: 원격 설명 설정
  • reuse-source-pads: 트랜스시버 상태에 따라 소스 패드를 재사용할지 여부 설정

GstWebRTCBinPad

  • transceiver: 해당 패드와 연결된 트랜스시버 설정

GstWebRTCBinSinkPad

  • msid: 해당 패드에 사용할 미디어 스트림 식별자 설정

GstWebRTCBinSrcPad

  • msid: 원격 피어가 이 패드에 대해 사용한 미디어 스트림 식별자 확인





ESP32-S3로 업그레이드

ESP32-S3 통합 프로젝트 최종 핀맵  기능 분류 부품 (Component) 전원 공급 연결 방식 GPIO 핀 비고 (Notes) 카메라 OV5640 카메라 보드 자체 공급 FPC 커넥터 N/A GPIO 핀을 소모하지 않음 입력...