LIVE555研究之三:LIVE555基礎
LIVE555基礎
LIVE555是為流媒體提供解決方案的跨平臺C++開源專案。從今天起我們將正式開始深入LIVE555程式碼。
一、各庫簡要介紹
LIVE555下包含LiveMedia、UsageEnvironment、BasicUsageEnvironment、GroupSock庫,MediaServer簡單伺服器程式以及其他多個測試demo。
LiveMedia庫:包含一系列處理不同編碼格式和封裝格式的類,基類是Medium。
UsageEnvironment庫:環境類,用於錯誤資訊的輸出。LIVE555中多數類中均包含此類物件指標。其內部包含TaskSchedule抽象類的指標,該類用於任務排程,因此所有包含UsageEnvironment指標的類均可將自己加入到排程中。
BasicUsageEnvironment庫:包含具體環境類和具體TaskScheduler類。UsageEnvironment用於對錯誤資訊的處理,BasicUsageEnvironment類用於以控制檯方式輸出錯誤資訊。因此想要以其他方式輸出錯誤資訊的類,可以從UsageEnvironment派生。BasicTaskSchedule類繼承自TaskScheduler抽象類,用以定義具體的排程策略。任何基於LIVE555的應用程式均需要定義自己的BasicEnvironment和TaskScheduler庫。如果建立視窗應用程式,在重定義TaskScheduler時,需要與圖形環境自己的事件處理框架整合。BasicTaskSheduler使用select模型實現事件的獲取和處理。如果想使用更高效的IOCP模型,可以定義自己的BasicTaskScheduler類。BasicTaskScheduler內部有一個迴圈,迴圈讀取佇列中的訊息並處理。整個基於BasicTaskScheduler的程式只有一個執行緒驅動。
GroupSock庫:對各種socket操作的封裝,用於收發資料。主要面向組播,但也可以進行單播的收發資料,僅支援UDP,不支援TCP。
MediaServer 伺服器程式:該程式使用BasicUsageEnvironment庫實現,因此是一個控制檯程式。任務排程類是BasicTaskScheduler類,因此使用Select模型且僅有一個執行緒在迴圈處理各種事件。後期如果有時間會實現基於IOCP的MediaServer伺服器程式。
其他測試Demo:基於LIVE555實現的客戶端程式,會在需要的時候介紹。
二、涉及到的基本概念
1. Souce、Sink
Souce :翻譯為源、源頭。表示資料的提供者,比如通過RTP讀取資料,通過檔案讀取資料或者從記憶體讀取資料,這些均可以作為Souce。
Sink:翻譯為水槽。表示資料的流向、消費者。比如寫檔案、顯示到螢幕等。
Filter:翻譯為過濾器。在資料流從Souce流到Sink的過程中可以設定Filter,用於過濾或做進一步加工。
在整個LiveMedia中,資料都是從Souce,經過一個或多個Filter,最終流向Sink。在伺服器中資料流是從檔案或裝置流向網路,而在客戶端資料流是從網路流向檔案或螢幕。
MediaSouce是所有Souce的基類,MediaSink是所有Sink的基類。
從類數量和程式碼規模可以看到,LiveMedia類是整個LIVE555的核心,其內部包含數十個操作具體編碼和封裝格式的類。LiveMedia定義的各種Souce均是從檔案讀取,如果想實現從裝置獲得實時流的傳輸,可以定義自己的Souce。
2. ClientSession
對於每一個連線到伺服器的客戶端,伺服器會為其建立一個ClientSession物件,儲存該客戶端的socket、ip地址等。同時在該客戶端中定義了各種響應函式用以處理和回應客戶端的各種請求。新版(2014.7.4)的LIVE555增加了ClientConnection類。用於處理一些與正常播放無關的命令。如命令未找到、命令不支援或媒體檔案未找到等。在ClientConnection處理DESCRIBE命令時會建立ClientSession物件,其他命令在ClientSession中處理。
3. MediaSession、MediaSubsession、Track
LIVE555使用MediaSession管理一個包含音視訊的媒體檔案,每個MediaSession使用檔名唯一標識。
使用SubSession管理MediaSession中的一個音訊流或視訊流。為行文方便我們稱音訊或視訊均為一個媒體檔案中的媒體流。因此一個MediaSession可以有多個MediaSubsession,一個管理音訊流一個管理視訊流。
在上一篇介紹RTSP協議時,客戶端在給伺服器傳送DESCRIBE查詢某個檔案的SDP資訊時,伺服器會給客戶端返回該媒體檔案所包含的多個媒體流資訊。併為每個媒體流分配一個TrackID。如視訊流分配為Track1,音訊流分配為Track2。此後客戶端必須在URL指定要為那個Track傳送SETUP命令。
因此我們可以認為MediaSubsession代表Server端媒體檔案的一個Track,也即對應一個媒體流。MediaSession代表Server端一個媒體檔案。對於既包含音訊又包含視訊的媒體檔案,MediaSession內包含兩個MediaSubsession。
但MediaSession和MediaSubsession僅代表靜態資訊,若多個客戶端請求同一個檔案,伺服器僅會建立一個MediaSession。各個客戶端公用。為了區分各個MediaSession的狀態又定義了StreamState類,用來管理每個媒體流的狀態。在MediaSubsession中完成了Souce和Sink連線。Souce對指標象會被設定進sink。在Sink需要資料時,可以通過呼叫Souce的GetNextFrame來獲得。
LIVE555中大量使用簡單工廠模式,每個子類均有一個CreateNew靜態成員。該子類的建構函式被設定為Protected,因此在外部不能直接通過new來構造。同時,每個類的建構函式的引數中均有一個指向UsageEnvironment的指標,從而可以輸出錯誤資訊和將自己加入排程。
4. HashTable
LIVE555內部實現了一個簡單雜湊表類BasicHashTable。在LIVE555中,有很多地方需要用到該雜湊表類。如:媒體檔名與MediaSession的對映,SessionID與ClientSession的對映,UserName和Password的對映等。
5. SDP
SDP是Session Description Protocol的縮寫。是一個用來描述多媒體會話的應用層協議,它是基於文字的,用於會話建立過程中的媒體型別和編碼方案的協商等。客戶端會通過DESCRIBE命令請求查詢指定檔案的媒體資訊。有不明白的可以看下上一篇介紹RTSP、RTP、RTCP的文章。
6. LIVE555中的關鍵類繼承層次(均以對H264碼流的處理為例)
大家可以先混個臉熟,以後會詳細介紹。
Souce
H264VideoStreamFramer是真正的Souce,它用於從h264檔案中讀取資料,並組裝成幀。在Sink呼叫GetNextFrame時將幀資料返回給Sink。
Sink
H264VideoRTPSink是真正的Sink,用於完成幀資料的傳送。
SubSession
SubSession用於完成Souce和Sink的連線,同時用於管理每個媒體流。
對於H264碼流,資料流的流動方向為:
伺服器端:H264VideoStreamFramer ->H264Or5Fragmenter (Filter)r->H264VideoRTPSink
客戶端:H264RTPSouce ->Sink(不同客戶端實現不同)
LIVE555類之間關係很是複雜,類之間犬牙交錯的關係增大了學習LIVE555的難度,深入學習之前應先熟悉基本流程,對各類的大概功能有所瞭解,至於細節問題可暫時略過。
對於LIVE555的程式碼風格,本人不是很喜歡:一是成員變數命名方式。二是花括號({)緊跟在上一行的末尾,沒有上下對齊層次清晰。三是多句程式碼位於同一行,多見於if語句。當然這僅僅是是個人喜好。歡迎大家表達自己的見解。
文章的最後,讓我們來探討下LIVE555應該如何發音的問題。聽過不少人都讀成: [liv](力V555)。個人感覺不對。因為live作為動詞講時,確實是讀成:力V,但此時是居住、生存、經歷的意思。作為形容詞講時是活的、直播、生動的。此時應讀成:賴V。作為一個為流媒體提供解決方案的開源C++專案,應該離直播更近一些吧!個人認為應該讀成賴V555。更洋氣的讀法:賴V Triple Five!這都是個人想當然的讀法,沒有聽過老外如何讀,歡迎拍磚!
下節我們將從伺服器程式入手,開始介紹LIVE555原始碼。
2014.8.16於浙江杭州
相關文章
- LIVE555原始碼研究之四:MediaServer (一)原始碼Server
- Live555原始碼解析(4) - 魚兒上鉤來原始碼
- live555實現共享記憶體視訊直播記憶體
- android上live555獲取IP為0.0.0.0的問題Android
- live555學習筆記15-RTCPInstance類小結筆記TCP
- 通過live555實現H264 RTSP直播(Windows版)Windows
- Django基礎之三(類檢視)Django
- 用live555將內網攝像機視訊推送到外網伺服器,附原始碼內網伺服器原始碼
- oracle spatial之基礎知識之三Oracle
- JAVA基礎之三-介面和抽象類Java抽象
- 對live555封裝的比較好的一個類,網上找到的,覺得不錯,給大家共享封裝
- kubebuilder實戰之三:基礎知識速覽UI
- .NET基礎之三個導航控制元件控制元件
- java基礎學習之三:方法的過載和重寫Java
- Shell程式設計基礎學習之三:變數和test程式設計變數
- Java基礎:類的深入研究(轉)Java
- 搞基礎理論研究有什麼用?
- 遊戲基礎知識——“研究者”角色的設計遊戲
- WebLogic的研究之三--開發、部署EJB(1) (轉)Web
- WebLogic的研究之三--開發、部署EJB(2) (轉)Web
- WebLogic的研究之三--開發、部署EJB(3) (轉)Web
- 【JavaScript筆記 · 基礎篇(十)】物件導向程式設計之三:繼承機制JavaScript筆記物件程式設計繼承
- 【Unity基礎知識之三】Unity Assets目錄下的特殊資料夾名稱Unity
- 【基礎演算法】(07)五大常用演算法之三:貪心演算法演算法
- 【FPGA基礎】Latch基礎FPGA
- 資料中心基礎設施高可用提升研究與實踐
- Java併發基礎-Fork、Join方式的平行計算研究分析Java
- Nand Flash基礎知識與壞塊管理機制的研究NaN
- Java基礎-語法基礎Java
- Pandas 基礎 (2) - Dataframe 基礎
- 前端基礎之jQuery基礎前端jQuery
- [今日白學]元件的基礎的基礎的基礎元件
- 遷移學習的基礎研究問題及適用場景遷移學習
- Frost&Sullivan:中國IT基礎設施行業研究報告(附下載)ROS行業
- 最大的基礎資訊系統設計與實施方案研究
- 谷歌為何出售機器人公司:基礎研究仍不成熟谷歌機器人
- 【web前端基礎 | JS基礎】物件Web前端JS物件
- scala基礎語法-----Spark基礎Spark