本文編寫時(shí)基于
GStreamer v1.11.0版
治唤,文中提及所有目錄結(jié)構(gòu)、文件茉帅、模塊等信息也均以v1.11.0為標(biāo)準(zhǔn)。后續(xù)如GStreamer官方SDK有做較大變動(dòng)锭弊,請(qǐng)自行適配堪澎。
1. GStreamer Introduction
GStreamer是一個(gè)基于流水線的多媒體框架,其內(nèi)部基于GObject味滞,以C語言寫成(參見Wikipedia)樱蛤。GStreamer采用基于plugin和pipeline的體系機(jī)構(gòu),框架中所有的功能模塊都是可插拔的plugins剑鞍,可以很方便地安裝到任意pipeline上昨凡。
![](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/images/gstreamer-overview.png)
1.1 GStreamer 環(huán)境
通常,在運(yùn)行基于GStreamer開發(fā)的程序前蚁署,需要配置開發(fā)平臺(tái)所需環(huán)境便脊,建議直接下載已編譯的安裝包,實(shí)在有特定需求(如裁剪光戈、特定庫支持)時(shí)哪痰,再考慮手動(dòng)編譯SDK遂赠。
GStreamer最新版本(1.11.0)中支持的系統(tǒng)具體如下:
Linux
大部分Linux發(fā)行版均已提供GStreamer package,但部分發(fā)行版由于法律原因等會(huì)對(duì)GStreamer plugins進(jìn)一步切割晌杰,因此可能不會(huì)包含gst-plugins-bad跷睦、gst-plugins-ugly及gst-libav pacakgesOpenBSD
不同架構(gòu)的package都有支持-
Windows
提供相應(yīng)版本MSI安裝器,SDK共提供三種文件肋演,分別為:- Runtime:運(yùn)行GStreamer程序必需的文件抑诸,可能會(huì)隨程序一同發(fā)布
- Development:開發(fā)GStreamer程序額外所需的文件
- Merge Modules:為GStreamer程序部署SDK所需的額外文件
Mac OS X
提供相應(yīng)的框架Android
提供可被集成入Android NDK的GStreamer BinariesIOS
提供可被集成入XCode的GStreamer Binaries
1.2 GStreamer內(nèi)部模塊
依據(jù)plugins功能及實(shí)現(xiàn)算法性能的不同,GStreamer將其分為如下模塊:
- gstreamer
- gstreamer-plugins-base
- gstreamer-plugins-good
- gstreamer-plugins-ugly
- gstreamer-plugins-bad
- gst-libav
- ...其他模塊
2. Cerbero編譯系統(tǒng)
Cerbero是一個(gè)服務(wù)于開源項(xiàng)目的多平臺(tái)編譯系統(tǒng)爹殊,它為不同體系哼鬓、發(fā)行版的平臺(tái)編譯并創(chuàng)建本地化package。
2.1 Cerbero基礎(chǔ)環(huán)境搭建
雖然Cerbero已經(jīng)為各個(gè)平臺(tái)提供了bootstrap(啟動(dòng)引導(dǎo)項(xiàng))边灭,但仍需要一些基礎(chǔ)環(huán)境來支持bootstrap异希。
由于Cerbero使用Python2.x(>= 2.6)開發(fā)編譯腳本,因此不論是什么平臺(tái)都必須安裝Python绒瘦,本教程中安裝版本為v2.7称簿。除此之外,各平臺(tái)所需依賴項(xiàng)各有不同惰帽。具體如下:
2.1.1 OSX
在OSX上你需要安裝如下軟件:
- XCode
- CMake : Download
Note:
此次實(shí)際編譯并未涉及OSX平臺(tái)憨降,因此IOS及OSX相關(guān)部分編譯并未測(cè)試,如需編譯SDK该酗,可參照教程中通用部分或根據(jù)github自行完成授药。
2.1.2 Linux(以Ubuntu為例)
測(cè)試環(huán)境為Ubuntu 14.04,其他版本或發(fā)行版僅供參考呜魄。需確認(rèn)如下軟件是否安裝:
-
Git
如當(dāng)前環(huán)境中沒有g(shù)it工具悔叽,請(qǐng)先手動(dòng)安裝完成爵嗅。
安裝完成后,配置git信息趟庄。git config --global user.email "xxxx@xxx.com" git config --global user.name "xxxx"
-
Python 2.x
確認(rèn)所使用的發(fā)行版中python版本>= 2.6且已添加python的argparse模塊(Python2.7已默認(rèn)支持)伪很。
如出現(xiàn)正常安裝步驟報(bào)錯(cuò)時(shí)戚啥,請(qǐng)嘗試先手動(dòng)
sudo apt-get update && upgrade
完善系統(tǒng)后重試。
2.1.3 Windows
Windows中環(huán)境配置較為復(fù)雜锉试,編譯SDK通常也相對(duì)耗時(shí)較長猫十,但由于其中Directshow Plugins需使用到Directshow base classes,仍依賴Microsoft編譯器和SDK完成編譯,所以也無法通過Linux系統(tǒng)完美跨平臺(tái)編譯炫彩。
同時(shí)Cerbero默認(rèn)使用Makefile進(jìn)行所有項(xiàng)目的編譯匾七,類似Unix,因此如需在Windows中正常編譯江兢,必須首先配置Unix編譯環(huán)境昨忆。
具體需安裝項(xiàng)如下:
Python2.7 : Download
切記只能安裝2.7版本,3.x版本并不支持-
CMake : Download
下載的x86版本可同樣支持x64版本編譯杉允,安裝時(shí)勾選添加至環(huán)境變量邑贴。
-
Git : Download
安裝過程中選擇“Checkout as-is, commit as-is"選項(xiàng)念恍,其他保持默認(rèn)
安裝完成后垛耳,配置git信息口柳。git config --global user.email "xxxx@xxx.com" git config --global user.name "xxxx"
-
Msys/MinGW : Download
勾選"Basic Setup"所有項(xiàng)進(jìn)行安裝捻勉。此處選擇所有項(xiàng)為便捷做法,如有興趣揍堰,可嘗試去除如gcc-ada等項(xiàng)钠惩,以最小化安裝
Wix 3.5 :Download
Windows MSI打包工具秕狰,默認(rèn)安裝即可-
Microsoft SDK 7.1 : Download
安裝Win7.1 SDK GRMSDKX_EN_DVD.7z(帶X)鸣哀,只有該包中存在amd64.msi我衬,否則安裝時(shí)因找不到文件報(bào)錯(cuò)而安裝失敗。如安裝過程中報(bào)錯(cuò)不能安裝依賴于 .NET Framework 4的組件井仰,則請(qǐng)下載.NET 4并安裝后重試糕档。
Windows Driver Kit 7.1.0 : Download
安裝GRMWDK_EN_7600_1.iso
安裝完上述項(xiàng)后,由于Cerbero必須在MinGW shell中運(yùn)行尿背,因此必須為shell配置部分程序環(huán)境變量:
-
windows x86
echo 'export PATH="$PATH:/c/Python27:/c/Program Files(x86)/Git/bin:/c/MinGW/bin/
-
windows x64
echo 'export PATH="$PATH:/c/Python27:/c/Program Files/Git/bin:/c/MinGW/bin/"' > ~/.profile
Note:
如生成的“.profile”文件與shell不位于同一路徑下捶惜,請(qǐng)手動(dòng)拷貝至同一路徑下。并在shell中運(yùn)行python鹤竭、git臀稚、cmake命令確認(rèn)已生效三痰。
至此稚机,Cerbero基礎(chǔ)環(huán)境已搭建完成获搏。
2.2 Cerbero基礎(chǔ)編譯過程
此處以Windows平臺(tái)編譯為示例常熙,Linux可參照進(jìn)行症概,步驟一致,唯一區(qū)別為打包后文件格式不同诅蝶。
編譯之前调炬,需在shell中運(yùn)行如下命令行進(jìn)行版本庫克络峙荨:
git clone git://anongit.freedesktop.org/gstreamer/sdk/cerbero
clone成功后棘钞,目錄結(jié)構(gòu)(v1.11.0)如下圖所示:
此處最好將cerbero完整文件夾內(nèi)容拷貝值/home/usrxxx/下宜猜,以避免后面compile過程中出現(xiàn)完整路徑過長而導(dǎo)致失敗問題姨拥。具體可參造4.5小節(jié)內(nèi)容。
可以看到文件夾上有勾選標(biāo)號(hào)提示柴罐,這是ToriseGit的功能憨奸,Windows下平臺(tái)可以更加便捷直觀地查看git庫文件膀藐,在裁剪SDK時(shí)有較大幫助额各,建議安裝。當(dāng)然麻诀,不安裝也不影響后續(xù)操作蝇闭。
可以看到根目錄下存在 setup.py
文件呻引,而實(shí)際上cerbero編譯工具使用前并不需要安裝逻悠,只需要直接運(yùn)行cerbero-uninstalled
腳本及選項(xiàng)(可選)即可韭脊。
2.2.1 cerbero-uninstalled常用選項(xiàng)
編譯之前沪羔,先簡(jiǎn)單了解下cerbero-uninstalled
的常用選項(xiàng):
./cerbero-uninstalled --help
其輸出內(nèi)容為:
usage: cerbero-uninstalled [-h] [-c CONFIG]
{add-recipe,rdeps,tag,genxcconfig,genlibfiles,check,list-packages,show-config,add-package,build,genvsprops,shell,run,cleanone,packageinfo,bundle-source,buildone,wipe,debug-packages,package,bootstrap,list,checkpackage,deps,gensdkshell,fetch-package,fetch}
...
Build and package a set of modules to distribute them in a SDK
positional arguments:
{add-recipe,rdeps,tag,genxcconfig,genlibfiles,check,list-packages,show-config,add-package,build,genvsprops,shell,run,cleanone,packageinfo,bundle-source,buildone,wipe,debug-packages,package,bootstrap,list,checkpackage,deps,gensdkshell,fetch-package,fetch}
sub-command help
add-recipe Adds a new recipe
rdeps List the reverse dependencies of a recipe
tag Tag a git recipe or all git recipes using their
sdk-$version branch
genxcconfig Generate XCode config files to use the SDK from VS
genlibfiles Generate MSVC compatible library files (.lib)
check Run checks on a given recipe
list-packages List all the available packages
show-config Show configuration settings
add-package Adds a new package
build Build a recipe
genvsprops Generate Visual Studio property sheets to use the SDK
from VS
shell Starts a shell with the build environment
run Runs a command in the cerbero shell
cleanone Clean a single recipe without its dependencies
packageinfo Print information about this package
bundle-source Bundle Source code of recipes and Cerbero
buildone Build or rebuild a single recipe without its
dependencies
wipe Wipes everything to restore the build system
debug-packages Outputs debug information about package, like
duplicates files or files that do not belong to any
package
package Creates a distribution package
bootstrap Bootstrap the build system installing all the
dependencies
list List all the available recipes
checkpackage Run checks on a given package
deps List the dependencies of a recipe
gensdkshell Create a script with the shell environment for the SDK
fetch-package Fetch the recipes sources from a package
fetch Fetch the recipes sources
optional arguments:
-h, --help show this help message and exit
-c CONFIG, --config CONFIG
Configuration file used for the build
上面列出的命令實(shí)際上都定義于./cerbero/commands/
路徑下琅豆,以相應(yīng)名稱的python腳本文件形式存在趋距,如:
雖然cerbero-uninstalled
支持很多命令,但編譯相關(guān)的并不多摘盆,這里僅介紹如下常用選項(xiàng):
-
[-c CONFIG]
cerbero-unistalled編譯時(shí)孩擂,如未使用該選項(xiàng),則cerbero-unistalled使用默認(rèn)配置(等價(jià)于變量)進(jìn)行編譯狈邑;如指定cbc文件米苹,則使用指定配置完成編譯蘸嘶。可選擇的CONFIG文件位于/config路徑下训唱,如下圖所示:
-
list
列出所有可選的recipes况增;recipe用于指定某個(gè)模塊的源训挡、依賴項(xiàng)舍哄、編譯步驟、產(chǎn)出庫(動(dòng)態(tài)弥锄、靜態(tài))等編譯過程相關(guān)信息籽暇。可選擇的recipe文件位于/recipes目錄下戒悠,由于數(shù)量較多舟山,截取部分如下圖所示:
-
list-packages
列出所有可打包的packages;打包實(shí)質(zhì)上是將編譯過程中各模塊相關(guān)文件(頭文件突琳、庫等)符相,按照對(duì)應(yīng)的package文件內(nèi)容取出至指定路徑啊终,壓縮并打包為對(duì)應(yīng)平臺(tái)文件蓝牲。可選擇的package文件位于/packages路徑下,如下圖所示:
bootstrap
下載并安裝當(dāng)前環(huán)境下編譯時(shí)所需工具build
編譯某個(gè)recipe散怖,包括其依賴項(xiàng)buildone
編譯某個(gè)recipe镇眷,不包括其依賴項(xiàng)cleanone
清理某個(gè)recipepackage
打包某個(gè)package欠动,遞歸遍歷所有依賴項(xiàng)具伍。wipe
清理之前build過程中產(chǎn)生的所有文件人芽,慎用
2.2.2 cerbero-uninstalled基礎(chǔ)編譯
本節(jié)內(nèi)容閱讀默認(rèn)前面章節(jié)所述環(huán)境均已安裝配置完善萤厅,繼續(xù)閱讀前靴迫,請(qǐng)確認(rèn)均已完備玉锌。
選擇只簡(jiǎn)單指定.cbc
文件,而不修改配置文件(package禀倔、recipe、commands等)直接編譯剃袍,可能存在如下問題:
- 模塊依賴項(xiàng)多,打包操作內(nèi)部遍歷后整體所需編譯模塊較多憔维,造成編譯耗時(shí)長(虛擬機(jī)測(cè)試2天左右)
- 部分特定模塊打包時(shí)并未勾選业扒,造成安裝編譯后SDK無法提供相應(yīng)環(huán)境支持
如可接受上述問題,則可按照如下步驟進(jìn)行基礎(chǔ)編譯:
./cerbero-uninstalled -c config/xxx.cbc bootstrap
./cerbero-uninstalled -c config/xxx.cbc package gstreamer-1.0
編譯成功后蹭沛,將生成對(duì)應(yīng)平臺(tái)文件摊灭,如windows中msi
帚呼,linux下tar.bz2
文件等。
Note:
編譯過程中如出現(xiàn)錯(cuò)誤煤杀,可先跳轉(zhuǎn)至章節(jié) “4. 問題-解決方法匯總”查看是否已有記錄沈自。
3. Cerbero配置
Cerbero內(nèi)部使用了典型的oven-cookbook-recipe結(jié)構(gòu)枯途,結(jié)合其他功能命令柔袁、config等模塊構(gòu)建整個(gè)編譯系統(tǒng)捶索。
Projects通過recipes文件(.recipe)來定義灰瞻,文件中描述了需要編譯的項(xiàng)目信息,如name, version, license, sources和編譯方法璃弄。同時(shí)构回,還提供了一些用于后續(xù)打包的文件纤掸。
Packages通過packages文件(.package)來定義借跪,文件中描述了包信息,如name, version, license, maintainer和其他用于打包的內(nèi)容歇由。一個(gè)包內(nèi)部包含了一系列recipes沦泌,安裝時(shí)將進(jìn)行展開京腥。
3.1 定制編譯步驟
如前所述公浪,projects通過recipe文件來定義欠气,build過程中會(huì)根據(jù)recipe內(nèi)容進(jìn)行編譯预柒。編譯步驟實(shí)際上分為六步,分別為:
- Fetch
- Extract
- Configure
- Compile
- Install
- Post_install
第一次編譯時(shí)憔古,必須Fetch相關(guān)源以進(jìn)行后續(xù)步驟鸿市,但通常在編譯成功后焰情,我們將不再希望所有模塊每次編譯時(shí)都自動(dòng)更新為最新版本(穩(wěn)定性不可控)内舟,此時(shí)可以將Fetch步驟去除,之后的build便會(huì)基于已有的源包進(jìn)行編譯充岛。
./cerbero/build/recipe.py
3.2 指定模塊編譯版本
編譯時(shí)裸准,可能會(huì)出現(xiàn)某個(gè)模塊的最新或特定版本存在bug赔硫,此時(shí)可通過指定模塊編譯版本來解決爪膊。
3.2.1 SourceType.GIT
以libffi為例推盛, 修改下圖中標(biāo)示處:
其中commit等可從已clone下來的git版本庫中獲取耘成,需為對(duì)應(yīng)版本commit id瘪菌。修改完成后师妙,確認(rèn)是否有其他相關(guān)內(nèi)容需一并修改默穴,此處需自行調(diào)整蓄诽。
clean后重新build仑氛,測(cè)試通過调衰。
3.2.2 SourceType.TARBALL
此處以faad2為例,修改下圖中標(biāo)示處:
修改version米酬、url地址赃额,url地址需訪問鏈接進(jìn)行手動(dòng)確認(rèn)跳芳,方法通常為去除末端版本字段飞盆,如
faad2-2.7.tar.bz
后訪問吓歇。其他獲取方法請(qǐng)自行研究票腰。
3.2.3 SourceType.SVN
此處以Tremor為例杏慰,修改如下圖標(biāo)示處:
3.3 GStreamer SDK 裁剪
./cerbero-unistalled -c config/xxx.cbc package gstreamer-1.0
鍵入該命令行缘滥,可開始gstreamer-1.0 SDK
的package
動(dòng)作完域。
SDK實(shí)質(zhì)上是package所有recipe build后相關(guān)文件的產(chǎn)物凹耙,對(duì)應(yīng)編譯中參與的角色(總package肠仪、子package异旧、模塊),裁剪也分為如下三種:
3.3.1 總package裁剪-.package
gstreamer-1.0 的package文件位于路徑 ./packages/gstreamer-1.0/
下拌屏。
首先整體瀏覽下該package文件內(nèi)容:
# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python
class SDKPackage(package.SDKPackage):
name = "gstreamer-1.0"
shortdesc = "GStreamer 1.0"
longdesc = "GStreamer 1.0"
title = "GStreamer 1.0"
url = "http://gstreamer.freedesktop.org"
version = '1.9.0.1'
sdk_version = '1.0'
codename = 'Congo'
license = License.LGPL
uuid = 'b1b4b712-0d09-4a34-8117-8a69b6deecc2'
vendor = "GStreamer Project"
org = "org.freedesktop.gstreamer"
ignore_package_prefix = True
packages =[
# (name, required, selected)
('gstreamer-1.0-core', True, True),
#('gstreamer-1.0-system', False, True),
#('gstreamer-1.0-playback', False, True),
('gstreamer-1.0-codecs', False, True),
('gstreamer-1.0-effects', False, True),
#('gstreamer-1.0-net', False, True),
#('gstreamer-1.0-visualizers', False, True),
#('gstreamer-1.0-codecs-gpl', False, False),
('gstreamer-1.0-codecs-restricted', False, True),
#('gstreamer-1.0-net-restricted', False, False),
#('gstreamer-1.0-dvd', False, False),
#('gstreamer-1.0-libav', False, False),
#('gstreamer-1.0-encoding', False, False),
('gstreamer-1.0-capture', False, False),
#('gstreamer-1.0-editing', False, False),
('gstreamer-1.0-devtools', False, False),
]
platform_packages = {
Platform.WINDOWS: [
('vsintegration-1.0', True, False),
('gstreamer-1.0-vs-templates', True, False),
],
}
install_dir = {
Platform.WINDOWS: 'gstreamer',
Platform.LINUX: '/opt/gstreamer-1.0/',
Platform.DARWIN: '/Library/Frameworks/GStreamer.framework/',
Platform.IOS: '/Library/Developer/GStreamer/iPhone.sdk'
}
root_env_var = 'GSTREAMER_1_0_ROOT_%(arch)s'
wix_upgrade_code = {
PackageType.DEVEL: {
Architecture.X86 : 'c0c6126d-1f4a-4577-9598-e900f594fd06',
Architecture.X86_64: '49c4a3aa-249f-453c-b82e-ecd05fac0693',
},
PackageType.RUNTIME: {
Architecture.X86 : 'ebe0c791-d84e-4f7e-a4eb-18012a0e319d',
Architecture.X86_64: 'c20a66dc-b249-4e6d-a68a-d0f836b2b3cf',
},
}
osx_framework_library = ('GStreamer', 'lib/GStreamer')
ios_framework_library = ('GStreamer', 'lib/GStreamer')
def prepare(self):
if self.config.target_platform in [Platform.ANDROID, Platform.IOS]:
p = ['gstreamer-1.0-dvd']
self.packages = [ x for x in self.packages if x[0] not in p]
if self.config.target_platform == Platform.IOS:
self.resources_postinstall = 'post_install_ios'
#self.user_resources = ['share/gst-sdk/tutorials/xcode iOS']
從面的代碼中可以看出,裁剪過程中端圈,只需要關(guān)注gstreamer-1.0.package文件的如下字段:
- packages
- platform_packages
對(duì)于不需要的子package可以直接使用#
注釋掉以裁剪舱权。至于如何確認(rèn)是否需要宴倍,就要打開各子package
甚至更底層的模塊recipe
文件進(jìn)行確認(rèn)啊楚。
以gstreamer-1.0-codecs.package
為例浑彰,如下圖所示:
實(shí)際上,
子package
文件中也只是在deps涯保、files未荒、files_devel及志、platform_files這些字段中粗略列出相關(guān)模塊和庫速侈,如需最終確認(rèn)是否存在依賴或裁剪的空間,需進(jìn)一步打開所引入的模塊recipe文件冶共。
以gst-plugins-good-1.0
為例家卖,子package
gstreamer-1.0-codecs.package
中使用了其:plugins_codecs
和:plugins_codecs_devel
兩項(xiàng)內(nèi)容庙楚,因此我們只關(guān)注gst-plugins-good-1.0.recipe文件中的這兩部分醋奠。
:plugins_codecs_devel字段不存在
此時(shí)可以清晰地看到窜司,子package
中引入模塊字段處其實(shí)是包含了模塊中對(duì)應(yīng)字段所有l(wèi)ib塞祈。如無需將這些lib打包到SDK中议薪,則可在子package
中移除對(duì)該字段的引入斯议。
3.3.2 子package裁剪-.package
上節(jié)的裁剪是總package
級(jí)別的哼御,簡(jiǎn)單卻也也粗暴,只能以package為單位進(jìn)行裁剪看靠,控制精度很低挟炬。實(shí)際上谤祖,為提高精度泊脐,可以對(duì)子package做進(jìn)一步的裁剪容客。
以gstreamer-1.0-codecs.package
為例但两,可做如下裁剪(具體裁剪內(nèi)容根據(jù)需求決定):
3.3.3 模塊裁剪-.recipe
上節(jié)的子package
裁剪雖然已經(jīng)比總package
級(jí)別裁剪精密很多谨湘,但某些時(shí)候芥丧,我們可能只需要在最終SDK中包含某子package
所引入模塊字段
中的一個(gè)lib擅耽,其他lib都可以去除物遇,此時(shí)就需要進(jìn)行模塊
級(jí)別的裁剪询兴。
以gst-plugins-good-1.0.recipe
為例诗舰,可做如下裁剪示例(其他字段可參照進(jìn)行):
4. 問題-解決方法匯總
4.1 Git信息未配置
解決辦法為根據(jù)提示配置信息:
git config --global user.email "xxxx@xxx.com"
git config --global user.name "xxxx"
4.2 Download certificate 驗(yàn)證
將參數(shù)
check_cert=True
修改為check_cert=False
以關(guān)閉驗(yàn)證眶根。
4.3 Console Unicode
The most secure solution is this one: Go to your Registry key HKEY_CURRENT_USER\Software\Microsoft\Command Processor and add String value Autorun = chcp 65001.
4.4 GPLed program for Windows NT/...
msgfmt是gettext中的一部分汛闸,使用gettext0.19.5中發(fā)現(xiàn)該系列程序運(yùn)行會(huì)出錯(cuò),而在gettext0.18.2中并未出現(xiàn)該問題艺骂。目前采用的方法是恢復(fù)使用0.18.2系列msgfmt程序替代诸老。
Download
4.5 webrtc-audio-processing compile error
查找到根本問題為make過程中對(duì)應(yīng).o文件拼接后路徑過長
需cebero文件夾內(nèi)容直接放置在home/usrxx/目錄下以減少完整路徑長度。
4.6Ubuntu Android SDK libmad缺失
解決方法為去除對(duì)libmad項(xiàng)的依賴钳恕,需修改文件有:
-
./recipes/gst-plugins-ugly-1.0.recipe
-
./recipes/gst-plugins-ugly-1.0-static.recipe
-
./packages/gstreamer-1.0-codec-restricted.package