• 沒有找到結果。

Video Output 模組

第三章 MPlayer 程式

3.4 Video Output 模組

MPlayer 內建許多影像輸出模組,使用者可以依需求選擇模組,例如使用 JPEG file 的輸出模組,可以將畫面存成一張張的JPEG 圖檔;或是使用 animated GIF ouput 的輸 出模組,可以將畫面存成 GIF 動畫圖檔。MPlayer 為了要操作影像輸出模組,定義了 vo_functions_t 結構。所有的影像輸出模組都要這些結構成員,這些結構成員包含許多函 式指標,而這些函式指標指向模組內特定函式,程式開發者可以針對每個函式撰寫對應 的程式碼。MPlayer 1.0rc2-4.1.2 內建 X11 ( XImage/Shm )、PNG file、JPEG file、animated GIF output…等。表 3-11 為 vo_functions_t 結構所包含的成員。這節將這些結構成員的函 式,做詳加說明與介紹。

影像輸出模組的 vo_functions_t 結構和影像濾波器的 vf_instance_t 結構的差別,前 者在模組內宣告指定所有結構成員的資料,後者是在模組開啟的時候才去指定結構成員 的資料。圖3-19 和圖 3-20 為影像輸出模組利用巨集的方式指定結構成員的資料。

圖3-19. x11 模組指定 vo_functions_t 結構成員資料

圖3-20.利用巨集指定 vo_functions_t 結構成員資料

表3-11. vo_functions_t 結構成員

變數 型態 回傳型態

info vo_info_t * -

preinit() 函式指標 int config() 函式指標 int control() 函式指標 int draw_frame() 函式指標 void draw_slice() 函式指標 int draw_osd() 函式指標 void flip_page() 函式指標 void check_events() 函式指標 void uninit() 函式指標 void

info:影像輸出模組的基本資訊,模組名稱(name)、模組簡稱(short_name)、模組撰 寫 作 者(author) 和 建 議 事 項 (comment) 。 模 組 名 稱 為 完 整 全 名 , 如 X11 ( XImage/Shm )。模組簡稱為開啟模組代碼,如 X11 ( XImage/Shm )為 x11。

x11 為模組的簡稱

表3-12. vo_info_t 結構成員

變數 型態

name const char * short_name const char * author const char * 能在config()前被呼叫,但是永遠在 preinit()和 uninit()之前執行。下面三個為最 重要的旗標,所有模組都要回傳支援與否。

VFCAP_CSP_SUPPORTED 支援該影像格式的 colorspace VFCAP_CSP_SUPPORTED_BY_HW colorspace 由硬體轉換 VFCAP_TIMER 由硬體控制時間同步

VOCTRL_GET_IMAGE

直接渲染介面(Direct Rendering Interface)模式,需要更新 mpi 結構。

VOCTRL_DRAW_IMAGE

取代 draw_slice()/draw_frame()函式。如果沒有實現該功能,draw_slice()

VOCTRL_RESET

設定播放視窗無邊框,僅支援Wiindows 的 directx。

draw_frame():只支援包裝(packed)的 YUY2, RGB/BGR 格式。只支援更新全部圖 像。如果有完成VOCTRL_DRAW_IMAGE 功能,這個函式可以不用實現。

draw_slice():支援平面(planar)格式,傳入 YUV 三個圖像的指標。如 YV12 格式,

一個完整大小的Y 和四分之一大小的 U,V。支援圖像部分更新。

draw_osd():繪製字幕或 OSD 到影像緩衝器。

flip_page():顯示緩衝器裡面的影像。如 x11 模組下,這個函式是將緩衝器的圖像 資料,透過Xlib 的 XPutImage()函式貼到畫面上。

check_events():擷取播放視窗上的鍵盤和滑鼠控制訊息。

uninit():關閉影像輸出系統,將系統回復到原先狀態。

3.4.1 vo Video Filter

MPlayer 1.0rc2-4.1.2 內建了許多影像濾波器,唯一比較特殊的是 libvo wrapper 這個 模組(簡稱 vo 影像濾波器)。這個模組一定要開啟使用,它並沒有任何影像處理的功能而 是用來連結影像濾波器和影像輸出模組。MPlayer 支援使用多個影像濾波器,這些多個 影像濾波器開啟串接後,形成filter chain。MPlayer 操作影像濾波器是使用 vf_instance_t 結構,並且利用 linked list 將開啟的影像濾波器的 vf_instance_t 串在一起。如此可以將 影像做適當處理並將資料傳到下一個影像濾波器。而影像濾波器使用的vf_instance_t 結 構和影像輸出模組的vo_functions_t 結構不同,所以 filter chain 的最後一個就是 vo 影像 濾波器,最後將資料傳遞給影像輸出模組。

圖3-22 為 vo 影像濾波器的 open()函式,除了指定 vf_instance_t 的結構成員,最重 要是傳入選定的影像輸出模組的vo_functions_t 結構的指標。並且將 vo_functions_t 指定 到vf->priv->vo 的指標變數(video_out 和 vf->priv->vo 是同一個變數)。如此 vo 影像濾波 器才可以利用vo_functions_t 的結構指標操作使用選定的影像輸出模組。

圖3-22. vo 影像濾波器的 open()函式

我們就vo 影像濾波器 query_format()、get_image()和 put_image()函式,說明如何透 過這個模組和選定的影像輸出模組連結。當 query_format()函式被呼叫,這個函式再呼 叫影像濾波器的control()函式並且傳入對應的操作旗標 VOCTRL_QUERY_FORMAT 和 變數fmt(colorspace 的代碼),如圖 3-23。而 get_image()函式則是呼叫影像濾波器的 control() 函式並且傳入對應的操作旗標VOCTRL_GET_IMAGE 和變數 mpi,如圖 3-24。

args 存放的是選定影像輸出模組的 vo_function_t 的結構指標

vf->priv->vo 指定為選定影像輸出 模組的vo_function_t 的結構指標

圖3-23. vo 模組的 query_format()函式

圖3-24. vo 模組的 get_image()函式

put_image()函式在影像濾波器中是影像處理函式,但是在 vo 影像濾波器並不做影 像處理,而是將圖像資料傳給影像輸出模組。圖3-25,傳遞圖像資料有三個函式可以使 用,但是只有一個函式會被執行,這必須看影像輸出模組是如何實現這部份的功能。第 一種,影像輸出模組的 control()函式並傳入操作旗標 VOCTRL_DRAW_IMAGE 和變數 mpi。所以影像輸出模組可以得到 mpi 整個結構的資料。第二種,影像輸出模組的 draw_slice()並傳入圖像資料的指標、圖像寬度和高度。第三種,影像輸出模組的 draw_frame()並傳入圖像資料的指標。

圖3-25. vo 模組的 put_image()函式

除了我們介紹的 query_format()、get_image()和 put_image(),還有其他對應的函式 如表3-13。uninit()函式並沒有任何對應函式,這是因為影像濾波器和影像輸出模組是分 開關閉。

表3-13. vo 影像濾波器函式對應表 vo 影像濾波器 影像輸出模組

config() config() control() control()

query_format() control()的 VOCTRL_QUERY_FORMAT 旗標 get_image() control()的 VOCTRL_GET_IMAGE 旗標 put_image() control()的 VOCTRL_DRAW_IMAGE 旗標

或draw_slice()或 draw_frame()

start_slice() control()的 VOCTRL_START_SLICE 旗標 draw_slice() draw_slice()

uninit() 無