• 沒有找到結果。

第三章 MPlayer 程式

3.6 Video Path 資料傳遞

3.6.1 初始化

1.選擇最佳的 colorspace

(1)、影像解碼器在解出第一張frame之前,需要初始化影像輸出模組。透過呼叫外 部函式(mpcodecs_config_vo()),並且傳入影像的寬度、高度和colorspace。

(2)、mpcodecs_config_vo()從選定的video codec所支援的colorspace,一一詢問影像 解碼器、影像濾波器和影像輸出模組是否支援該colorspace。

影像解碼器模組(如ffmpeg)支援多種video codec,而這些video codec的基本資 訊,全部都存放在/etc/codecs.conf檔案中。當MPlayer開啟的時候,處理video codec 設定檔的函式將讀取設定值。這個函式會將codec支援的colorspace(存在設定檔特 定videocodec的名稱out,如圖3-37)透過查表方式,轉成特定的代碼。例如選擇 FFmpeg MPEG-4 codec,將會詢問YV12、I420和IYUV三個格式,而這三個格式 代碼分別為0x32315659、0x30323449和0x56555949。

圖3-37. ffodivx 的 codecs.conf 訊息

詢 問 影 像 濾 波 器 是 透 過 呼 叫 該 濾 波 器 的 函 式(query_format()),並且傳入 colorspace所對應的代碼,再利用查表的方式查詢是否支援。圖3-38的1,傳入要 詢問的影像濾波器的操作結構指標和colorspace的代碼,最後回傳所支援的旗標,

由於先前已經建立好video chain,所以在此會依序詢問linked list裡的影像濾波 器。每個濾波器被呼叫的時候,都是利用查表方式判斷是否支援傳入的colorspace 代碼,不支援就回傳0,支援就呼叫vf_next_query_format()。透過這個函式將會呼 叫下一個影像濾波器的query_format()。回傳的flags變數是所支援的旗標,而最重 要 的 旗 標 為 VFCAP_CSP_SUPPORTED( 支 援 該 colorspace) 和

VFCAP_CSP_SUPPORTED _BY_HW(colorspace不需要任何轉換)。

詢問影像輸出模組也是利用查表方式,這功能運作是呼叫該模組control()函式 的VOCTRL_QUERY_FORMAT旗標。該影像輸出模組的control()函式利用查表方 式執行旗標所對應的程式碼,然後該對應的程式碼又透過查表的方式查詢對 colorspace 支 援 與 否 。 影 像 解 碼 器 則 是 透 過 呼 叫 解 碼 器 的 control() 函 式 的 VDCTRL_QUERY_FORMAT,如圖3-38的2。

mpcodecs_config_vo()由VFCAP_CSP_SUPPORTED_BY_HW旗標找出影像解 碼器、影像濾波器和影像輸出模組的最佳colorspace。如果都沒有任何符合的 colorspace,將會嘗試插入“scale filter”在影像解碼器和第一個影像濾波器之間。

如果再沒有符合的colorspace,影片就不能播放。

圖3-38. mpcodec_config_vo()部分程式碼

2.影像濾波器、影像輸出模組 config

colorspace決定好了,再來就是要通知filter chain中所有模組在播放過程會收到 影像的寬度、高度和colorspace。並非每個濾波器會得到同一個參數,例如在

一個影像濾波器。這是由mpcodecs_config_vo()呼叫vf_config_wrapper()進行設 定,這函式將從filter chain第一個成員開始進行(呼叫該模組的config()),收到設定 參數的模組要負責傳遞參數到下一個影像濾波器,直到最後一個成員設定完成為 止。

3.取得 mpi 的圖像記憶體空間

(1)、取得影像解碼器的mpi記憶體空間:

在video chain 的 各 模 組 間 傳 遞 圖 像 資 料 是 利 用 MPlayer 的 特 殊 格 式 mp_image_t(簡稱mpi)結構。除了結構所需要的記憶體空間外,結構中有指向圖像 資料的指標。而影像解碼器會透過呼叫外部函式(mpcodecs_get_image())取得這些 圖像資料的記憶體空間。

如 果 這 些 圖 像 資 料 的 記 憶 體 空 間 不 是 由 影 像 解 碼 器 的 內 部 取 得 。 mpcodecs_get_image() 會 嘗 試 使 用 direct rendering , 這 將 呼 叫 影 像 濾 波 器 的 get_image()取得記憶體空間。如果成功MP_IMGFLAG_DIRECT旗標會被設定,

在影像解碼器傳遞圖像資料到影像濾波器時,將省去一次記憶體資料複製的動 作。

(2)、取得影像濾波器的mpi記憶體空間:

影像濾波器在做影像處理之前,需要取得mpi的圖像記憶體空間。這是用來存 放影像處理過後的圖像資料。透過呼叫外部函式(vf_get_image())取得新的mpi記 憶體空間。

vf_get_image()會嘗試使用direct rendering,這是透過呼叫下一個影像濾波器 (get_image())取得記憶體空間。如果失敗將會回到一般記憶體取得方式。