近來在搞Chromium的Media Player,本來想好好寫點東西,可是一直也沒有組織好如何寫,世事變遷,弄不好過些日子又去搞別點什麼了,即使是半成品也貼出來吧,總比什麼都沒有留下來強。
1 Overview
Chromium是由Google維護的一個瀏覽器項目,由於本文主要就是想記錄一下近期閱讀其媒體處理部分代碼的心得,所以其諸多長處也就沒有必要在這裏描述了。Chromium的整個代碼量非常龐大,使用VC++打開有600來個工程,完全編譯也需要耗時幾個小時,但是我感覺Google其實就是做了一個融合的工作,把很多優秀的開源項目及已有技術恰到好處的爲己所用,當然這需要有很豐富的經驗及架構能力。Chromium的媒體處理解碼用的是ffmpeg,其主要的代碼集中在src/media目錄下。
1.1 Run a Sample
Chromium支持hteml5,所以我們可以寫一個包含video標籤的html把Chromium中MediaPlayer運行起來看看效果,代碼如下:
|
由於版權等的問題從Chromium Project下載來的代碼在ffmpeg中只打開了對於ogv格式的支持,所以這裏使用ogv作爲video source,其中bear.ogv在Chromium的源碼目錄中可以找到。如果想支持更多格式可以自己配置ffmepg並重新編譯即可,ffmepg的代碼在src/Third_party/ffmpeg目錄下。上面的例子成功運行的效果如下:
2 Code Read
2.1 理解的邊界
對於複雜系統的理解我們一般需要設定一個邊界,只理解邊界以內的,這樣會使理解相對簡單,就像我們看由於工作的需要及理解的有限,我主要關注的是MediaPlayer的Video部分,對於Audio關注的比較少,但是在整體的框架上應該是相同的,使用Class Diagram和Sequence Diagram來說明MediaPlayer的整體結構及運行的邏輯。另外由於Chromium的代碼實在龐大且是個多進程多線程的系統,爲了實現解耦及可擴展性還包裝了很多層次,很多的任務調用都使用到了回調及狀態機等機制,對於一個調用要想完全的追根溯源有很大難度,而且由於我的關注點在MediaPlayer,所以很多時候把MediaPlayer以外的調用者就作爲Actor了,這樣在一定的Level上理解簡單一些。很多調用是由WebMediaPlayerClientImpl類發起的,所以把WebMediaPlayerClientImpl的方法作爲Actor。2.2 WebMediaPlay的邊界
上面這張圖體現的一些類應該屬於MediaPlayer整個框架的High Level,說明MediaPlayer與Chromium整體的一些關聯。其中WebMediaPlayerImpl是實現MediaPlayer的類,用戶對於MediaPlayer的操作最終都會分派到它去具體執行,之後就會具體的調用到Demux/ Decoder/ Renderer等。
下面是幾張Call stack