GStreamer系列-基礎(chǔ)概念
目錄:
一、什么是 GStreamer 二、GStreamer 架構(gòu) 1. app 層 2. core framework層 3. plugin 層 三、GStreamer基礎(chǔ)概念 1. element 和 pipeline 2. pads 和 capabilities 3. bins 4. bus
一、什么是 GStreamer?
參考:
What is GStreamer[1]cnblogs-John[2]
-
一個(gè) C 語言編寫的支持 Windows/Linux/Android/iOS 的跨平臺(tái)的多媒體框架;
-
幾乎可用來開發(fā)任何與多媒體相關(guān)的應(yīng)用,例如媒體播放器、流媒體服務(wù)器、音視頻編輯應(yīng)用等;
-
基于 plugin (插件)和 pipeline (管道),這里說的pipeline跟Linux系統(tǒng)下的管道是同一個(gè)概念,UNIX系統(tǒng)里經(jīng)久不衰的設(shè)計(jì)哲學(xué);
-
plugin 負(fù)責(zé)實(shí)現(xiàn)音視頻傳輸協(xié)議、音視頻輸入輸出源、音視頻編解轉(zhuǎn)碼等真實(shí)的媒體處理功能,而 plugin 之間通過 pipeline 關(guān)聯(lián)在一起, pipeline 負(fù)責(zé)將上一個(gè) plugin 的數(shù)據(jù)流(data flow) 傳輸給下一個(gè) plugin ,最終形成一個(gè)完整的多媒體處理應(yīng)用;
-
狹義上的 GStreamer 是指 GStreamer core,它負(fù)責(zé)統(tǒng)籌管理 plugin、data flow、media type negotiation (媒體類型協(xié)商)等核心功能;
二、GStreamer 架構(gòu)
框架圖:
劃分為3層:
- app 層(包括 gstreamer tools + multimedia applications)
- core 層;
- plugin 層;
1. app 層
參考:
GStreamer tools[3]
app 層包括 GStreamer自帶的 GStreamer tools 和 app 開發(fā)者編寫的各種多媒體應(yīng)用。
GStreamer tools 是GStreamer自帶的命令行工具集,它是 app 開發(fā)者用于快速驗(yàn)證原型和調(diào)試程序的瑞士軍刀。
對(duì)于GStreamer 初學(xué)者,我們不用第一時(shí)間就去學(xué)習(xí)如何使用 GStreamer API 來編寫 multimedia app,取而代之的是,先學(xué)習(xí)使用 GStreamer tools 將是一個(gè)更好的入門選擇。
GStreamer tools 包括:
- gst-launch-1.0: 命令行建立和運(yùn)行 pipeline, 不用編寫C代碼;
- gst-inspect-1.0: 查看可用的插件和它們的相關(guān)信息;
- gst-discoverer-1.0: 查看媒體文件的內(nèi)部結(jié)構(gòu);
gst-launch-1.0 舉例:
$ gst-launch-1.0 videotestsrc ! autovideosink
建立了一個(gè)基于videotestsrc 和 autovideosink 的pipeline,videotestsrc 用于提供測(cè)試視頻輸入流,autovideosink 則會(huì)自動(dòng)選擇輸出流的目的地,感嘆號(hào)!的作用類似Linux系統(tǒng)下的|,即管道符;
gst-inspect-1.0 舉例:
$ gst-inspect-1.0 videotestsrc Plugin Details: Name videotestsrc Description Creates a test video stream Filename /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvideotestsrc.so Version 1.8.3 License LGPL Source module gst-plugins-base Source release date 2016-08-19 Binary package GStreamer Base Plugins (Ubuntu) Origin URL https://launchpad.net/distros/ubuntu/+source/gst-plugins-base1.0 ...
上述命令打印了 videotestsrc 這個(gè)插件的全部信息,上面只截取了部分輸出。如果不跟任何參數(shù),gst-inspect-1.0會(huì)列出當(dāng)前系統(tǒng)gstreamer所能查找到的所有插件。
gst-discoverer-1.0 舉例:
$ gst-discoverer-1.0 /root/Desktop/video.mp4 Topology: container: Quicktime audio: MPEG-4 AAC video: MPEG-4 Video (Simple Profile) Properties: Duration: 0:00:42.576000000 Seekable: yes Tags: audio codec: MPEG-4 AAC audio maximum bitrate: 64000 datetime: 1970-01-01T00:00:00Z encoder: Lavf52.61.0 container format: ISO MP4/M4A bitrate: 9562 video codec: MPEG-4 video
打印出GStreamer 能提取出的關(guān)于該多媒體文件的所有信息,核心信息就是container 和 codecs,了解這些信息有助于我們確定如何創(chuàng)建pipeline。
2. core framework層
主要提供了:
-
編寫 multimedia app 需要調(diào)用的 API;
-
plugin 框架,即如何初始化、卸載、調(diào)用 plugin;
-
pipeline 框架,即如何創(chuàng)建和使用 pipeline;
-
media type 的處理/協(xié)商機(jī)制;
-
數(shù)據(jù)傳輸;
-
基于Gstreamer bus的消息傳遞機(jī)制;
3. plugin 層
最下層為各種插件,實(shí)現(xiàn)具體的數(shù)據(jù)處理及音視頻輸出,應(yīng)用不需要關(guān)注插件的細(xì)節(jié),會(huì)由 core framework 層負(fù)責(zé)插件的加載及管理。
GStreamer 有哪些類型的plugin?
-
Protocols:負(fù)責(zé)各種協(xié)議的處理,file,http,rtsp等。
-
Sources:負(fù)責(zé)數(shù)據(jù)源的處理,alsa,v4l2,tcp/udp等。
-
Formats:負(fù)責(zé)媒體容器的處理,avi,mp4,ogg等。
-
Codecs:負(fù)責(zé)媒體的編解碼,mp3,vorbis等。
-
Filters:負(fù)責(zé)媒體流的處理,converters,mixers,effects等。
-
Sinks:負(fù)責(zé)媒體流輸出到指定設(shè)備或目的地,alsa,xvideo,tcp/udp等。
GStreamer 根據(jù)各個(gè)模塊的成熟度以及所使用的開源協(xié)議,將 core 及 plugin 置于不同的源碼包中:
-
gstreamer:核心軟件包
-
gst-plugins-base:包含基本的示例性element的源碼包;
-
gst-plugins-good:包含了LGPL 協(xié)議下的一組高質(zhì)量插件的源碼包;
-
gst-plugins-ugly:包含了一組高質(zhì)量的插件,但是可能會(huì)引起發(fā)行問題的源碼包;
-
gst-plugins-bad:包含了一組需要提升質(zhì)量的插件的源碼包;
-
gst-libav:包含了一組封裝了 libav 的插件的源碼包;
-
另外還有一些源碼包沒有列舉出來。
三、Gstreamer基礎(chǔ)概念
參考:
GStreamer Foundations[4]
1. elements 和 pipeline
參考:
GStreamer Elements[5]
Element 是 Gstreamer 中最重要的對(duì)象類型之一;
一個(gè) Element 實(shí)現(xiàn)一個(gè)功能,大致可分為3個(gè)類型:
-
輸入型:source element,例如 videotestsrc ;
-
處理型:filter element,例如 videoconvert ;
-
輸出型:sink elements,例如autovideosink
$ gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink
上面3個(gè) element 就構(gòu)成了一條 pipeline;
Element 的狀態(tài):
- GST_STATE_NULL,初始狀態(tài)
- GST_STATE_READY,
- GST_STATE_PAUSED
- GST_STATE_PLAYING
相關(guān) API:
GstElement *source; source= gst_element_factory_make ("videotestsrc", "source"); // 創(chuàng)建 element gst_bin_add_many (GST_BIN (pipeline), source, filter, sink, NULL); // 將element添加到 pipeline gst_element_link_many (source, filter, sink, NULL);// 將element 連成一條 pipeline
2. pads 和 capabilities
參考:
GStreamer Pads[6]
pad 是一個(gè) element 的輸入/輸出接口,分為src pad(生產(chǎn)數(shù)據(jù))和sink pad(消費(fèi)數(shù)據(jù))兩種。
兩個(gè)element 想要連接在一起時(shí)需要使用到 pad ,pad 擁有當(dāng)前 element 能處理數(shù)據(jù)類型的能力(capabilities,簡(jiǎn)稱 caps),會(huì)在連接時(shí)通過比較 src pad 和 sink pad中 所支持的能力,以選擇一種數(shù)據(jù)類型用于傳輸,如果沒有可用的數(shù)據(jù)類型,則無法連接 element。
在 element 通過 pad 連接成功后,數(shù)據(jù)會(huì)從上一個(gè) element 的 src pad 傳到下一個(gè) element的 sink pad 。
當(dāng) element 支持多種數(shù)據(jù)處理能力時(shí),我們可以明確指定使用哪種 cap 以決定數(shù)據(jù)傳輸?shù)念愋?,例如?
$ gst-launch-1.0 videotestsrc ! video/x-raw,width=320,height=120 ! autovideosink
上述命令明確指出了使用“video/x-raw,width=320,height=120”這種 cap 來傳輸數(shù)據(jù),如果沒有明確指出使用哪種 cap,則 GStreamer 會(huì)選擇遍歷所有的caps 選出一種可用的cap。
查看element的 pad 和 cap:
$ gst-inspect-1.0 videotestsrc Pad Templates: SRC template: 'src' Availability: Always Capabilities: video/x-raw format: {... } width: [ 1, 2147483647 ] height: [ 1, 2147483647 ] framerate: [ 0/1, 2147483647/1 ] video/x-bayer format: { bggr, rggb, grbg, gbrg } width: [ 1, 2147483647 ] height: [ 1, 2147483647 ] framerate: [ 0/1, 2147483647/1 ]
可以看出v videotestsrc 只有一個(gè) src pad,在這個(gè)src pad下有2個(gè) Capabilities
Properties 用于描述 cap 的額外信息,它的形式是“key=value”,例如:
$ gst-launch-1.0 videotestsrc ! videobox left=-100 ! autovideosink
left 就是 videobox的其中一個(gè) property。
Properties的類型包括:
G_TYPE_INT G_TYPE_BOOLEAN G_TYPE_FLOAT G_TYPE_STRING GST_TYPE_FRACTION
相關(guān) API:
GstPad *pad; pad = gst_element_get_request_pad (); GstCaps *caps; caps = gst_caps_new_simple(); // 創(chuàng)建caps gst_element_link_filtered (element1, element2, caps); // 設(shè)置element 間的caps
3. Bins
參考:
GStreamer Bins[7]
什么是Bins ?
- Bins 是element的容器;
- Bins 可以包含一組連接在一起的element;
- Bins 可以被認(rèn)為是邏輯上的element/pipeline;
- Bins會(huì)統(tǒng)一內(nèi)部element的狀態(tài), 統(tǒng)一接收/轉(zhuǎn)發(fā)消息;
相關(guān) API:
bin = gst_bin_new ("my_bin");gst_bin_add (GST_BIN (pipeline), bin);
4. Bus
參考:
GStreamer Bus[8]
在 pipeline 運(yùn)行的過程中,各個(gè) element 以及應(yīng)用之間不可避免的需要進(jìn)行數(shù)據(jù)消息的傳輸,gstreamer 提供了 bus 系統(tǒng)以及多種數(shù)據(jù)類型(Buffers、Events、Messages,Queries)來達(dá)到此目的:
每一個(gè) pipeline 默認(rèn)都會(huì)帶有一個(gè)bus,應(yīng)用無需手動(dòng)創(chuàng)建,只需要往 bus 里注冊(cè) message handler,bus 會(huì)定期的檢查是否有新的 message,有則調(diào)用 handler。
結(jié)尾
到此,已經(jīng)介紹了不少 GStreamer 的基礎(chǔ)概念了,這些概念已經(jīng)足夠讓我們完成接下來要研究的第一個(gè)GStreamer helloworld 示例程序了。
你和我各有一個(gè)蘋果,如果我們交換蘋果的話,我們還是只有一個(gè)蘋果。但當(dāng)你和我各有一個(gè)想法,我們交換想法的話,我們就都有兩個(gè)想法了。如果你也對(duì)嵌入式系統(tǒng)開發(fā)有興趣,并且想和更多人互相交流學(xué)習(xí)的話,請(qǐng)關(guān)注我的公眾號(hào):ESexpert,一起來學(xué)習(xí)吧,歡迎各種收藏/轉(zhuǎn)發(fā)/批評(píng),小小的轉(zhuǎn)發(fā)一下對(duì)我來說是極大的幫助,Thank You!
參考資料
[1]What is GStreamer: https://gstreamer.freedesktop.org/documentation/application-development/introduction/gstreamer.html?gi-language=c
[2]cnblogs-John: https://www.cnblogs.com/xleng/p/10948838.html
[3]GStreamer tools: https://gstreamer.freedesktop.org/documentation/tutorials/basic/gstreamer-tools.html?gi-language=c
[4]GStreamer Foundations: https://gstreamer.freedesktop.org/documentation/application-development/introduction/basics.html?gi-language=c
[5]GStreamer Elements: https://gstreamer.freedesktop.org/documentation/application-development/basics/elements.html?gi-language=c
[6]GStreamer Pads: https://gstreamer.freedesktop.org/documentation/application-development/basics/pads.html?gi-language=c
[7]GStreamer Bins: https://gstreamer.freedesktop.org/documentation/application-development/basics/bins.html?gi-language=c
[8]GStreamer Bus: https://gstreamer.freedesktop.org/documentation/application-development/basics/bus.html?gi-language=c
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!