首先,我們先釐清一件事情,GStreamer可以看做是一個框架,而DeepStream其實可以當作一個程式庫,不過他將這個程式庫整合為GStreamer插件(Plugin)。在介紹DeepStream之前,我們必須先搞清楚GStreamer到底在做什麼,因為DeepStream你只需要拿來使用,可是你得了解GStreamer才會知道使用方法
GStreamer是一個開源的多媒體串流框架,框架的核心就是圍繞著非常多樣的「插件」,提供一套工具讓開發者能夠以「直觀」的方式去規劃不同的元件要如何串聯在一起。也就是說,開發者的目標就是將一群元件以一定的邏輯連接成一個Pipeline,框架會自行調度,讓影音串流可以順著Pipeline的設計運行
每個GStreamer插件會提供一些元件,元件就是負責處理資料的單元。GStreamer將元件分成3大類:Source、Filter、Sink。
只有輸出端點,就是將資料傳遞到框架內並輸出到下游,例如影片、即時串流
具備輸入、輸出兩個端點,負責處理「特定格式」的輸入,轉換為「特定格式」的輸出。何謂特定格式我們後續再討論
只有輸入端點,負責接收上游的資料傳遞到框架之外,例如檔案、GUI顯示。框架之外可以是任意型式,你想的到的方式都可以,總之就是把資料搬出框架

Pad和Caps我個人覺得GStreamer之所以能發展出如此多樣的插件,Pad和Caps這兩個要素功不可沒
首先,每個Element可以擁有一個或是多個Pad。Pad具有方向性,分為Src Pad和Sink Pad,根據Element的分類會決定其具備的Pad類型,Source只具備Src Pad,Filter具備Src Pad和Sink Pad,Sink則只具備Sink Pad。那麼神奇的事情就發生了,框架透過Pad把所有元件串聯成一個Pipeline,下圖是官方文件的一個範例
仔細看可以發現ogg-demuxer將一個輸入轉為兩個輸出,這類元件稱之為Demuxer(解封裝器),負責將複合資料拆分開來,例如我們可以將mp4拆為影像和音訊。與之對應的就是把分散的資料組合在一起的Muxer(封裝器),例如把影像和音訊組合成mp4。
光有Pad框架只能知道元件之間的連接順序,但元件之間能不能接起來就得看Pad Capabilities,我們直接看官方文件範例:
SINK template: 'sink'
Availability: Always
Capabilities:
audio/x-raw
format: S16LE
rate: [ 1, 2147483647 ]
channels: [ 1, 2 ]
audio/x-raw
format: U8
rate: [ 1, 2147483647 ]
channels: [ 1, 2 ]
SRC template: 'src'
Availability: Always
Capabilities:
video/x-raw
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
framerate: [ 0/1, 2147483647/1 ]
format: { I420, NV12, NV21, YV12, YUY2, Y42B, Y444, YUV9, YVU9, Y41B, Y800, Y8, GREY, Y16 , UYVY, YVYU, IYU1, v308, AYUV, A420 }
可以看到,Capabilities(Caps)是負責描述資料的「格式」,它表達的是我這個元件可以接受什麼格式的輸入,會產生什麼格式的輸出。
例如範例中的Sink Pad可以接受兩種格式
Src Pad可以產生video/x-raw,也就是影格,但支援非常多種format
所以元件到底該用什麼格式的輸入及輸出,就會由框架出馬讓每個元件之間作協商。
協商的過程大概如下:
框架就會根據這個資訊去協調上下游元件最終使用的Caps,例如最終協調的結果是使用video/x-raw,format=RGBA
為什麼要大費周章先介紹這些呢?因為DeepStream能夠加速的祕密就藏在Caps內,快還要更快。
而DeepStream的元件基本上也都跟它設計的Caps息息相關,因為元件的數量其實不少,這邊就直接先上連結,後續會挑幾個比較重要的跟大家介紹。
DeepStream的元件們