2020年10月15日 星期四

如何通過gst-launch-1.0運行及測試Pipeline

gst-launch是我們平時使用最多的一個命令,它接收一個用字符串方式描述的Pipline,將其實例化並運行。我們可以用此命令快速的檢查Pipeline中各個元素是否能夠正確的連接起來。當我們需要構建的Pipeline很複雜時,我們也可以將Pipeline進行拆分,逐步通過gst-launch驗證Pipeline的合法性。

通過gst-launch驗證的字符串Pipeline可以直接使用gst_parse_launch()接口將其轉化為GstPipeline對象,節省了我們單獨調用API去創建Element的時間。

當我們用字符串描述Pipeline時,每個Element之間需要通過嘆號 “!" 分隔Element,這樣gst-launch才能正確識別。

在使用gst-launch時,根據不同的應用場景,我們可以分為以下的類型。


採用默認的參數創建Pipeline

這種方式我們只需將所使用的Element使用嘆號分隔即可,例如:

$ gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink


設置Element的屬性

在某些情況下,我們需要修改Element的屬性,或指定所需參數(例如playbin的uri參數),Element的屬性直接跟在Element之後。下面的命令會設置videotestsrc的視頻模式,輸出圖像為環形。屬性支持的值可以通過gst-inspect命令查看。

$ gst-launch-1.0 videotestsrc pattern=11 ! videoconvert ! autovideosink


如果屬性值中包含空格,我們可以將其置於單引號或雙引號中。

$ gst-launch-1.0 -v videotestsrc ! clockoverlay halignment=right valignment=bottom text="Edge City" shaded-background=true font-desc="Sans, 36" ! videoconvert ! autovideosink 


包含分支的Pipeline

每個Element都有name的屬性,我們可以利用name來實現包含多個分支的複雜的Pipeline,這常見於有多個輸出/輸入的Element(mux,demux,tee等)。

下面的命令通過tee創建了2個分支,分別用於不同的sink,在一個分支是Pipeline完成後(到達sink),我們可以使用“name加一個點號”重新創建一個分支。

$ gst-launch-1.0 videotestsrc ! videoconvert ! tee name=t ! queue ! autovideosink t. ! queue ! autovideosink

使用同樣的方式,我們也可以將多個分支合併為一個。下面的命令首先解碼文件,將視頻編碼為H.264,音頻編碼為MP3,最終再合併生成TS文件。注意dmux和mux Element的使用。

$ gst-launch-1.0 filesrc location=surround.mp4 ! decodebin name=dmux ! queue ! audioconvert ! lamemp3enc ! mux. \

dmux. ! queue ! x264enc ! mpegtsmux name=mux ! queue ! filesink location=out.ts


指定Element的Pad

某些情況下,我們希望自己指定某個Pad用於連接,我們可以指定已命名Element的Pad來實現。

$ gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! \

matroskademux name=d d.video_00 ! matroskamux ! filesink location=sintel_video.mkv

上面的命令會將sintel_trailer-480p.webm文件進行Demux,只選擇其中的視頻(video_00),再將其保留為mk文件,只保留了視頻部分。如果想只保留音頻部分,可以使用如下命令:

$ gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! \

matroskademux name=d d.audio_00 ! vorbisparse ! matroskamux ! filesink location=sintel_audio.mka

上面兩條命令均未對視頻進行解碼,只是將其從一個容器中拷入到另一個容器。


利用Caps Filter過濾碼流

當Element包含多個輸出Pad時,可能導致連接到下一個Element的Pad具有不確定性。在下一個Element支持當前Element所有的輸出類型,這時GStreamer會隨機選擇一個Pad用於連接。

例如:我們無法確定下面的Pipeline會使用video_00還是audio_00連接到filesink,因為filesink同時支持audio及video輸入。

$ gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! matroskademux ! filesink location=test

我們可以如上一節所說,顯式指定連接所用的Pad,或者使用Caps Filter:

$ gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! \

matroskademux ! video/x-vp8 ! matroskamux ! filesink location=sintel_video.mkv

Caps Filter表現為一個只接收指定數據類型的Element,並將數據傳遞到下一個Element,可以高效的解決二義性的問題。

我們可以使用gst-inspect查看Element的輸出Pad,以決定我們的Caps Filter需要添加何種參數。在gst-launch後加 -v 參數可以輸出Pipeline連接時所使用的Pad信息。

對於多個過濾條件,我們需要通過逗號隔開。

對於某些特殊的類型參數,GStreamer提供了相應的關鍵字來進行轉換:

  • i 或 int 表示整型或範圍;
  • f 或 float 表示浮點數及範圍;
  • 4 或 fourcc 表示4個字符的FOURCC 代碼;
  • b, bool, 或 boolean 表示布爾型數據;
  • s, str, 或 string 表示字符串;
  • fraction 表示分數(例如幀率, 像素寬高比);
  • l 或 list 表示列表。

用於發送和接收UDP RTP數據:

$ gst-launch-1.0 v4l2src ! \

video/x-raw-yuv,width=128,height=96,format='(fourcc)'UYVY ! \

videoconvert ! ffenc_h263 ! video/x-h263 ! rtph263ppay pt=96 ! \

udpsink host=192.168.1.1 port=5000 sync=false


$gst-launch-1.0 udpsrc port=5000 ! application/x-rtp, \

clock-rate=90000,payload=96 ! rtph263pdepay queue-delay=0 ! ffdec_h263 \

! xvimagesink

使用YUY2或YV12作為測試視頻格式,幀率為30幀/秒:

$ gst-launch-1.0 videotestsrc ! \

'video/x-raw-yuv,format=(fourcc)YUY2,framerate=30/1;video/x-raw-yuv,format=(fourcc)YV12,framerate=30/1' \

! xvimagesink


通過alsasrc錄製文件,限定採樣率及位寬:

$ gst-launch-1.0 alsasrc! \

'audio/x-raw-int,rate=[32000,64000],width=[16,32],depth={16,24,32},signed=(boolean)true' \

! wavenc ! filesink location=recording.wav


Reference

GStreamer基礎教程12 - 常用命令工具

沒有留言:

張貼留言