2010年5月26日 星期三

mplayer video out driver (轉載)

在很多應用中的圖形輸出數據是存放在一些指定的內存區域的,比如說我現在實現的基於 minigui圖形中間件的mplayer播放器的,在播放前需要告訴mplayer當前播放窗口所在的內存地址和當前的屏幕像素深度,bpp,窗口大小等 等一系列的信息,這就有必要給mplayer寫個自己的video_out driver了。和大 多數驅動一樣,mplayer也提供了一個驅動函數結構體,其結構體定義如下(在libvo/video_out.h文件中定義):
typedef struct vo_functions_s{
 
vo_info_t *info;
 
/*
  
* Preinitializes driver (real INITIALIZATION)
  
* arg - currently it's vo_subdevice
  
* returns: zero on successful initialization, non-zero on error.
  
*/
 
int (*preinit)(const char *arg);
 
/*
 
* Initialize (means CONFIGURE) the display driver.
  
* params:
  
* width,height: image source size
  
* d_width,d_height: size of the requested window size, just a hint
  
* fullscreen: flag, 0=windowd 1=fullscreen, just a hint
  
* title: window title, if available
  
* format: fourcc of pixel format
  
* returns : zero on successful initialization, non-zero on error.
  
*/
 
int (*config)(uint32_t width, uint32_t height, uint32_t d_width,
 
uint32_t d_height, uint32_t fullscreen, char *title,
 
uint32_t format);

 
/*
  
* Control interface
  
*/
 
int (*control)(uint32_t request, void *data, ...);

 
/*
 
* Display a new RGB/BGR frame of the video to the screen.
 
* params:
 
* src[0] - pointer to the image
 
*/
 
int (*draw_frame)(uint8_t *src[]);

 
/*
  
* Draw a planar YUV slice to the buffer:
  
* params:
  
* src[3] = source image planes (Y,U,V)
  
* stride[3] = source image planes line widths (in bytes)
  
* w,h = width*height of area to be copied (in Y pixels)
  
* x,y = position at the destination image (in Y pixels)
  
*/
  
int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y);

  
/*
   
* Draws OSD to the screen buffer
   
*/
  
void (*draw_osd)(void);

  
/*
  
* Blit/Flip buffer to the screen. Must be called after each frame!
  
*/
  
void (*flip_page)(void);

  
/*
   
* This func is called after every frames to handle keyboard and
   
* other events. It's called in PAUSE mode too!
   
*/
   
void (*check_events)(void);

   
/*
    
* Closes driver. Should restore the original state of the system.
    
*/
   
void (*uninit)(void);
} vo_functions_t;
1:初始化驅動(preinit 函數、config函數和uninit 函數):當驅動初始化時將調用preinit ,退出時則調用uninit函數(注意:播放器在每播放一個媒體文件時都會初始化一次video驅動的)。在preinit函數和config函數里可以做我們一些初始化工作,比如指定存放音頻的內存地址,當前設備支持的像素,窗口大小,和 bpp(每像素點需要用多少bit存儲))等工作。而uninit 函數則可以做些收尾工作了....
2:告訴mplayer設備支持的圖形顯示格式在mplayer調用完preinit 函數後, 它就要開始輸出數據啦。它在輸出前 會去查詢下驅動支持的像素格式等一些大小,這時候它將調用驅動的control函數,並且傳遞VOCTRL_QUERY_FORMAT參數, 這時候我們就應該把preinit函數中設置的參數告訴mplayer,然後mplayer就按設備支持的 格式輸出數據,
3:獲取 mplayer圖形數據:獲取mplayer數據有很多種方法,這些方法可以根據設備來選擇,這裡我們只使用最簡單的方法VOCTRL_DRAW_IMAGE。同樣還是在control函數中,當mplayer輸出數據將會調用control函數並傳遞VOCTRL_DRAW_IMAGE參 數和mp_image_t指針,我們可以通過mp_image_t指針來獲取圖像數據的大小,存放的位置等必要信息,然後將這些存放在顯示內存中顯示出來...int dx = mpi->wint dy = mpi->huint8_t *buf = mpi->planes[0]int stride = mpi->stride[0]
4:其它:config 函數:mplayer將調用config函數來通知驅 動,mplayer顯示圖形的原始大小,和播放的最佳大小,和影片標題等信息,這些信息只是給驅動提供參考值的.還有其它draw_frame,draw_slice,draw_osd,flip_page等接口可以按需使用,充分利用 mplayer提供的接口可以打造一個性能較優的video_out驅動的。
5:結尾現在只是使用了簡單的mplayer驅動的方法,其實還有很多點可以去優化的,比如說讓mplayer直接將數據寫到顯示內存中,而 不再先放入mp_image_t結構體中,充分利用其它的幾個接口來提高驅動的性能。

沒有留言:

張貼留言