Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2259887
  • 博文数量: 218
  • 博客积分: 5767
  • 博客等级: 大校
  • 技术积分: 5883
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-01 14:44
文章存档

2012年(53)

2011年(131)

2009年(1)

2008年(33)

分类: LINUX

2008-05-15 11:24:45

mplayer video_out driver

在很多应用中的图形输出数据是存放在一些指定的内存区域的,
比如说我现在实现的基于minigui图形中间件的mplayer播放器的,在播放前需要告诉mplayer当前播放窗口所在的内存地址和当前的屏幕像素深度,bpp,窗口大小等等一系列的信息,这就有必要给mplayer写个自己的video_out driver了.

和大多数驱动一样,mplayer也提供了一个驱动函数结构体,其结构体定义如下(在libvo/video_out.h文件中定义):
typedef struct vo_functions_s
{

    /*
    * 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 函数和 uninit 函数):
当驱动初始化时将调用preinit ,退出时则调用uninit函数(注意:播放器在每播放一个媒体文件时都会初始化一次video驱动的).
在preinit函数里可以做我们一些初始化工作,比如指定存放音频的内存地址,当前设备支持的像素,窗口大小,和bpp(每像素点需要用多少bite存储)等工作。
而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->w
int dy = mpi->h
uint8_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结构体中,充分利用其它的几个接口来提高驱动的性能。

阅读(1640) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~