Gecko 多彩多姿多媒體

作者:
瀏覽:234

自從個人電腦愈來愈普及之後,影音娛樂的應用一直是大家關注的焦點之一。在其中,多媒體的播放功能已經變成基本功能中的基本功能。為了能處理各式各樣的多媒體功能(諸如:錄製、播放、串流、轉換格式、後製處理等),每個平台上幾乎都有設計出一套多媒體框架用來應付各種的需求,像是 Windows 上有 DirectShowMedia Foundation 、 Linux 上有 GStreamer 、 Mac OS 上有 QuickTime 、 Android 上有 StageFright 。至於多媒體檔案在 Gecko 裡是如何被播放的呢?我們現在就來談談。

在 Gecko 裡的影音處理大致上可以分成兩大類。一種是播放現成的檔案,例如播放本地端的影像檔或聲音檔,或是透過 HTTP 或 RTSP 連到遠端的伺服器抓資料;這類的資料都可以利用  元素跟  元素裡的 src 屬性或是  元素指定資料來源[註*];這是目前大多數人的使用情境,也是今天所要講的主題。另一種是處理即時產生的資料,例如從相機與麥克風來的即時影像,或是直接操作音頻內容產生新的音效,或是跟遠端的電腦互傳即時影音資料。這類的資料是透過 MediaStreamGraph 的機制去做處理,有興趣的朋友可以自行先去了解,今天會略過這個部份。

Gecko 多彩多姿多媒體

Gecko’s Media Framework

跟大部份的多媒體框架一樣, Gecko 利用許多模組化的類別完成多媒體的播放;比較特別的是, Gecko 的模組化有部份是為了能夠利用各平台現成的解碼元件而設計。如上圖,當 HTMLMediaElement 需要執行播放功能的時候, MediaDecoder 會負起播放多媒體資料的任務。如果資料來源是檔案或是一般的 URI [註**] , MediaDecoder 會利用圖中的 MediaResource 、 MediaReader 、 VideoFrameContainer 、 AudioStream 、 MediaDecoderStateMachine 來執行播放動作。其中 MediaResource 是用來把多媒體資料包裝成具有隨機存取功能的類別,諸如檔案、 HTTP 、 RTSP 等資料來源,都分別有不同的子類別提供實作。 MediaReader 是用來把從 MediaResource 拿到的多媒體資料分流出尚未解碼的影像資料與音訊資料,然後再利用解碼器轉成解碼後的影像與音訊;為了能夠利用各平台現有的解碼元件,以及支援不同格式的檔案, Gecko 對於不同的多媒體框架多媒體封裝格式都分別客製化了不同的 MediaReader 子類別,達成分流與解碼的任務。 VideoFrameContainer 是用來把解碼後的影像轉傳到螢幕畫面上的類別。 AudioStream 是用來把解壓縮之後的音訊轉傳到聲音輸出裝置的類別。 MediaDecoderStateMachine 則是用來監控與記錄解碼的狀態,控制影像與音訊的同步,同時也是管理整個資料流流動的主要角色。

在上圖中,連結各物件的箭頭代表的是多媒體資料流動的方向,不同的顏色分別代表的是驅動資料流動的不同執行緒;值得一提的是,圖上所有的執行緒通通都是 MediaDecoderStateMachine 在掌控生命週期的。 “Media Decode” 執行緒是負責驅動 MediaReader 從 MediaResource 抓取資料進行解碼,並且把解碼過的影像資料與音訊資料分別放在各自的佇列裡。 “Media Audio” 執行緒是負責把解碼過的音訊資料從 MediaReader 裡的音訊佇列抓取音訊資料進 AudioStream 播放聲音。 “Media State” 執行緒會定期檢查當前的解碼狀態,決定資料流是否該繼續流動,例如佇列滿了就先停止解碼的執行緒,或是在使用者要停止播放的時候停止音訊播放的執行緒;這隻執行緒還會定期檢查影像資料與音訊資料的播放時間,在需要更新影像資料的時候,從 MediaReader 裡的影像佇列抓取符合播放時間點的影像資料進 VideoFrameContainer 播放畫面。

以上就是 Gecko 如何利用

[註*]: Gecko 能播放的檔案格式請參考這裡這裡
[註**]:利用 JavaScript 程式碼其實也可以指定一個 MediaStream 物件到