深入淺出,快速弄明白 gst-launch-1.0 PIPELINE-DESCRIPTION 管道描述語法

本文轉載自許野平的博客

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

他的博客有很多關於GStreamer的好文章,並非官網文檔翻譯,基本是按照他自己的理解來寫,適合理解

1

話說 gst-launch-1.0 這條命令老牛掰了,看是很複雜的媒體流,用這條命令,一行代碼就搞定了。看看下面這行代碼,區區幾十個字符,就建立了測試視頻流:

gst-launch-1.0 videotestsrc ! autovideosink
  • 1

運行後可以在屏幕上顯示視頻測試圖案,大概就是下面這個樣子:
在這裏插入圖片描述

那些包含視頻、音頻,甚至用戶定製信號的複雜媒體流,也能用 gst-launch-1.0 這樣子玩嗎?當然沒問題。我們接下來聊聊如何構建複雜媒體流管道。

2

在剛纔的例子中,我們的管道描述串是 videotestsrc ! autovideosink,它包括了三個部分:

  • 管道起始點: videotestsrc
  • 管道的終點: autovideosink
  • 起點和終點的連接:

這個管道描述串的意思是,把元素 videotestsrc 連接到元素 autovideosink 上。

說到這裏,很多人很納悶,不是說元素之間只能通過 Pad 鏈接嗎?這裏怎麼直接連接元素呢?實際上這是一個簡化用法,因爲 videotestsrc 只有一個輸出 Pad,autovideosink 也只有一個輸入 Pad,這種情況下,就不需要再說明怎麼樣用 Pad 連接了。不過,上面這個例子完整的說明應該如下:

gst-launch-1.0 videotestsrc name=a a.src ! b.sink autovideosink name=b
  • 1

看暈了吧?其實不復雜,聽我繼續道來…

3

gst-launch-1.0 的基本語法是

gst-launch-1.0 元素名稱 屬性=... 元素名稱 屬性=... ... 元素.SrcPad名稱 ! 元素.SinkPad名稱
  • 1

所以,根據我們上面的例子,可以寫出下面的命令行:

gst-launch-1.0 videotestsrc autovideosink 
  • 1

沒看錯吧?元素之間竟然沒有 符號。沒錯,命令行運行後並沒出現語法錯誤,只是這個管道並不會工作,因爲沒有鏈接。此時,管道描述符包含兩個部分:

  • 第一個元素:videotestsrc
  • 第二個元素:autovideosink

要建立連接,就需要給元素命名:

gst-launch-1.0 videotestsrc name=a autovideosink name=b
  • 1

當然,因爲還沒加入鏈接,當然還是不工作。此時,管道描述符仍然只包含兩個部分:

  • 第一個元素:videotestsrc name=a
  • 第二個元素:autovideosink name=b

下面加入鏈接:

gst-launch-1.0 videotestsrc name=a autovideosink name=b a.src ! b.sink
  • 1

運行一下,OK,很完美。

4

注意到沒有,這次連接的位置竟然與剛纔的例子不一樣。其實,gst-launch-1.0 不在乎排列順序。這個例子中,管道描述串包括三個部分:

  • 第一個元素:videotestsrc name=a
  • 第二個元素:autovideosink name=b
  • 連接:a.src ! b.sink

這三個部分可以任意排列。這三個部分之間並沒有標點符號,會不會弄混?仔細分析一下就能發現,不會。因爲元素名稱前後都是空格,沒有其他符號。元素的屬性賦值(比如 name=a)有等號連接,連接描述有感嘆號連接。所以,儘管描述串很複雜,而且無序,但不會弄錯。

所以,前面看到的那個例子,管道描述串中也是由上面三個部分構成,只是順序調整了一下,讓人覺得很神的樣子。你看一下能分出來三個部分嗎?

gst-launch-1.0 videotestsrc name=a a.src ! b.sink autovideosink name=b
  • 1

5

我們怎麼能知道 videotestsrc 的 Pad 名稱是 src?這個不難,用命令 gst-inspect-1.0 videotestsrc 查看即可。gst-inspect-1.0 是研究插件庫的好工具,一定要用好!

使用 gst-inspect-1.0 我們發現, videotestsrc 有一個叫做 pattern 的屬性,默認值是 0,最大值可以取到 24。接下來我們改成 1 看看:

gst-launch-1.0 videotestsrc pattern=1 ! autovideosink
  • 1

gst-launch-1.0 videotestsrc pattern=1 ! autovideosink

正如 gst-inspect-1.0 說的那樣,這個是雪花 snow 模式!

6

剛纔的例子,分辨率太低了,能不能轉換成高清視頻?當然沒問題,我們利用 CAPS 轉換,強迫 Pad 之間的連接通過我們指定的 CAPS 進行。看下面的例子:

gst-launch-1.0 videotestsrc ! video/x-raw, width=1920, height=1080 ! autovideosink
  • 1

也可以:

gst-launch-1.0 videotestsrc name=a autovideosink name=b a.src ! video/x-raw, width=1920, height=1080 ! b.sink
  • 1

需要注意兩點:

  • a.src ! video/x-raw, width=1920, height=1080 ! b.sink 是一個鏈接,不可亂序
  • video/x-raw, width=1920, height=1080 是 CAPS 說明,其中的屬性之間用逗號隔開。這個表示方法與元素是不一樣的,元素的屬性是用空格隔開的。

7

因爲 CAPS 的屬性可能很複雜,比如 video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12 這種裏面帶括號的,無法直接放到 gst-launch-1.0。另外,CAPS標識如果太簡單也可能與元素無法區別。於是,這類 CAPS 必須用單引號或雙引號括起來,明確告訴 gst-launch-1.0 這是一個 CAPS 說明。所以下面的例子也是合法的:

gst-launch-1.0 videotestsrc ! 'video/x-raw, width=1920, height=1080' ! autovideosink
gst-launch-1.0 videotestsrc ! "video/x-raw, width=1920, height=1080" ! autovideosink
  • 1
  • 2

到此爲止,我覺得建立管道描述串的知識應該夠用了,我不能再講了,否則你知道的就太多了,哈哈哈哈!

謝謝閱讀,如果有用,請點贊收藏,如有問題,歡迎留言!

================

補充知識:GStreamer 插件體系簡介

GStreamer 系統一個很重要的想法就是把媒體流拆解成了插件,插件通過連接組合,構造出複雜的媒體流管道。

GStreamer 的插件是以動態庫,也就是 .so 形式發佈,原則上我們不需要其源代碼。這些插件在 GStreamer 系統中註冊以後,我們就可以通過其註冊名稱找到它們,也可以通過其名稱加載 .so 庫代碼,並調用相關功能。

建立一個這樣的註冊體系是一個很複雜的事情,但是我們用起來卻省了很多事。我們可以在沒有這些插件源代碼的情況下,靈活運用這些插件。用一個簡單的字符串,構造出通常需要成千上萬行代碼才能寫出的系統。前面的那一條例子,如果用 C 語言寫代碼實現的話,即使同樣利用這些插件,也需要幾十行甚至數百行代碼才能實現。

所以, gst-launch-1.0 這條命令,實際上扮演了一個解釋程序的角色,可以把管道描述字符串翻譯成複雜的代碼,最終按照要求爲我們構建的媒體流管道。

在我開發用的 Jetson Nano 上,GStreamer 的插件安裝在目錄 /usr/lib/aarch64-linux-gnu/gstreamer-1.0 下,文件名是:libgstvideotestsrc.so。參見下面的截圖:

在這裏插入圖片描述

可以用 gst-inspect-1.0 命令查看 GStreamer 系統註冊的插件。當然,我們也可以自己編寫插件,最基本的入門參見:


參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章