diff options
Diffstat (limited to 'libvo/video_out.c')
-rw-r--r-- | libvo/video_out.c | 394 |
1 files changed, 252 insertions, 142 deletions
diff --git a/libvo/video_out.c b/libvo/video_out.c index 0d2dc713e5..f8d857dfc5 100644 --- a/libvo/video_out.c +++ b/libvo/video_out.c @@ -21,40 +21,32 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <assert.h> +#include <stdbool.h> #include <unistd.h> //#include <sys/mman.h> #include "config.h" +#include "options.h" +#include "talloc.h" #include "video_out.h" #include "aspect.h" #include "geometry.h" +#include "old_vo_wrapper.h" #include "mp_msg.h" #include "help_mp.h" #include "osdep/shmem.h" - -//int vo_flags=0; +#ifdef CONFIG_X11 +#include "x11_common.h" +#endif int xinerama_screen = -1; int xinerama_x; int xinerama_y; -// currect resolution/bpp on screen: (should be autodetected by vo_init()) -int vo_depthonscreen=0; -int vo_screenwidth=0; -int vo_screenheight=0; - -int vo_config_count=0; - -// requested resolution/bpp: (-x -y -bpp options) -int vo_dx=0; -int vo_dy=0; -int vo_dwidth=0; -int vo_dheight=0; -int vo_dbpp=0; - int vo_nomouse_input = 0; int vo_grabpointer = 1; int vo_doublebuffering = 1; @@ -62,7 +54,6 @@ int vo_vsync = 0; int vo_fs = 0; int vo_fsmode = 0; float vo_panscan = 0.0f; -int vo_ontop = 0; int vo_adapter_num=0; int vo_refresh_rate=0; int vo_keepaspect=1; @@ -87,59 +78,59 @@ char *vo_wintitle; // // Externally visible list of all vo drivers // -extern vo_functions_t video_out_mga; -extern vo_functions_t video_out_xmga; -extern vo_functions_t video_out_x11; -extern vo_functions_t video_out_xover; -extern vo_functions_t video_out_xvmc; -extern vo_functions_t video_out_vdpau; -extern vo_functions_t video_out_xv; -extern vo_functions_t video_out_gl; -extern vo_functions_t video_out_gl2; -extern vo_functions_t video_out_matrixview; -extern vo_functions_t video_out_dga; -extern vo_functions_t video_out_sdl; -extern vo_functions_t video_out_3dfx; -extern vo_functions_t video_out_tdfxfb; -extern vo_functions_t video_out_s3fb; -extern vo_functions_t video_out_wii; -extern vo_functions_t video_out_null; -extern vo_functions_t video_out_zr; -extern vo_functions_t video_out_zr2; -extern vo_functions_t video_out_bl; -extern vo_functions_t video_out_fbdev; -extern vo_functions_t video_out_fbdev2; -extern vo_functions_t video_out_svga; -extern vo_functions_t video_out_png; -extern vo_functions_t video_out_ggi; -extern vo_functions_t video_out_aa; -extern vo_functions_t video_out_caca; -extern vo_functions_t video_out_mpegpes; -extern vo_functions_t video_out_yuv4mpeg; -extern vo_functions_t video_out_direct3d; -extern vo_functions_t video_out_directx; -extern vo_functions_t video_out_kva; -extern vo_functions_t video_out_dxr2; -extern vo_functions_t video_out_dxr3; -extern vo_functions_t video_out_ivtv; -extern vo_functions_t video_out_v4l2; -extern vo_functions_t video_out_jpeg; -extern vo_functions_t video_out_gif89a; -extern vo_functions_t video_out_vesa; -extern vo_functions_t video_out_directfb; -extern vo_functions_t video_out_dfbmga; -extern vo_functions_t video_out_xvidix; -extern vo_functions_t video_out_winvidix; -extern vo_functions_t video_out_cvidix; -extern vo_functions_t video_out_tdfx_vid; -extern vo_functions_t video_out_xvr100; -extern vo_functions_t video_out_tga; -extern vo_functions_t video_out_corevideo; -extern vo_functions_t video_out_quartz; -extern vo_functions_t video_out_pnm; -extern vo_functions_t video_out_md5sum; - -const vo_functions_t* const video_out_drivers[] = +extern struct vo_driver video_out_mga; +extern struct vo_driver video_out_xmga; +extern struct vo_driver video_out_x11; +extern struct vo_driver video_out_xover; +extern struct vo_driver video_out_xvmc; +extern struct vo_driver video_out_vdpau; +extern struct vo_driver video_out_xv; +extern struct vo_driver video_out_gl; +extern struct vo_driver video_out_gl2; +extern struct vo_driver video_out_matrixview; +extern struct vo_driver video_out_dga; +extern struct vo_driver video_out_sdl; +extern struct vo_driver video_out_3dfx; +extern struct vo_driver video_out_tdfxfb; +extern struct vo_driver video_out_s3fb; +extern struct vo_driver video_out_wii; +extern struct vo_driver video_out_null; +extern struct vo_driver video_out_zr; +extern struct vo_driver video_out_zr2; +extern struct vo_driver video_out_bl; +extern struct vo_driver video_out_fbdev; +extern struct vo_driver video_out_fbdev2; +extern struct vo_driver video_out_svga; +extern struct vo_driver video_out_png; +extern struct vo_driver video_out_ggi; +extern struct vo_driver video_out_aa; +extern struct vo_driver video_out_caca; +extern struct vo_driver video_out_mpegpes; +extern struct vo_driver video_out_yuv4mpeg; +extern struct vo_driver video_out_direct3d; +extern struct vo_driver video_out_directx; +extern struct vo_driver video_out_kva; +extern struct vo_driver video_out_dxr2; +extern struct vo_driver video_out_dxr3; +extern struct vo_driver video_out_ivtv; +extern struct vo_driver video_out_v4l2; +extern struct vo_driver video_out_jpeg; +extern struct vo_driver video_out_gif89a; +extern struct vo_driver video_out_vesa; +extern struct vo_driver video_out_directfb; +extern struct vo_driver video_out_dfbmga; +extern struct vo_driver video_out_xvidix; +extern struct vo_driver video_out_winvidix; +extern struct vo_driver video_out_cvidix; +extern struct vo_driver video_out_tdfx_vid; +extern struct vo_driver video_out_xvr100; +extern struct vo_driver video_out_tga; +extern struct vo_driver video_out_corevideo; +extern struct vo_driver video_out_quartz; +extern struct vo_driver video_out_pnm; +extern struct vo_driver video_out_md5sum; + +const struct vo_driver *video_out_drivers[] = { #ifdef CONFIG_XVR100 &video_out_xvr100, @@ -241,9 +232,6 @@ const vo_functions_t* const video_out_drivers[] = #ifdef CONFIG_VESA &video_out_vesa, #endif -#ifdef CONFIG_DIRECTFB - &video_out_directfb, -#endif #ifdef CONFIG_DFBMGA &video_out_dfbmga, #endif @@ -258,6 +246,10 @@ const vo_functions_t* const video_out_drivers[] = #endif &video_out_null, // should not be auto-selected +#ifdef CONFIG_DIRECTFB + // vo directfb can call exit() if initialization fails + &video_out_directfb, +#endif #if CONFIG_XVMC &video_out_xvmc, #endif @@ -286,79 +278,195 @@ const vo_functions_t* const video_out_drivers[] = NULL }; -void list_video_out(void){ - int i=0; - mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_AvailableVideoOutputDrivers); - mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_OUTPUTS\n"); - while (video_out_drivers[i]) { + +static int vo_preinit(struct vo *vo, const char *arg) +{ + return vo->driver->preinit(vo, arg); +} + +int vo_control(struct vo *vo, uint32_t request, void *data) +{ + return vo->driver->control(vo, request, data); +} + +// Return -1 if driver appears not to support a draw_image interface, +// 0 otherwise (whether the driver actually drew something or not). +int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts) +{ + if (!vo->config_ok) + return 0; + if (vo->driver->buffer_frames) { + vo->driver->draw_image(vo, mpi, pts); + return 0; + } + vo->frame_loaded = true; + vo->next_pts = pts; + if (vo_control(vo, VOCTRL_DRAW_IMAGE, mpi) == VO_NOTIMPL) + return -1; + return 0; +} + +int vo_get_buffered_frame(struct vo *vo, bool eof) +{ + if (!vo->config_ok) + return -1; + if (vo->frame_loaded) + return 0; + if (!vo->driver->buffer_frames) + return -1; + vo->driver->get_buffered_frame(vo, eof); + return vo->frame_loaded ? 0 : -1; +} + +int vo_draw_frame(struct vo *vo, uint8_t *src[]) +{ + assert(!vo->driver->is_new); + if (!vo->config_ok) + return 0; + return old_vo_draw_frame(vo, src); +} + +int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y) +{ + return vo->driver->draw_slice(vo, src, stride, w, h, x, y); +} + +void vo_draw_osd(struct vo *vo, struct osd_state *osd) +{ + if (!vo->config_ok) + return; + vo->driver->draw_osd(vo, osd); +} + +void vo_flip_page(struct vo *vo, unsigned int pts_us, int duration) +{ + if (!vo->config_ok) + return; + vo->frame_loaded = false; + vo->next_pts = MP_NOPTS_VALUE; + if (vo->driver->flip_page_timed) + vo->driver->flip_page_timed(vo, pts_us, duration); + else + vo->driver->flip_page(vo); +} + +void vo_check_events(struct vo *vo) +{ + if (!vo->config_ok) + return; + vo->driver->check_events(vo); +} + +void vo_seek_reset(struct vo *vo) +{ + vo_control(vo, VOCTRL_RESET, NULL); + vo->frame_loaded = false; +} + +void vo_destroy(struct vo *vo) +{ + vo->driver->uninit(vo); + talloc_free(vo); +} + +void list_video_out(void) +{ + int i = 0; + mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Available video output drivers:\n"); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_OUTPUTS\n"); + while (video_out_drivers[i]) { const vo_info_t *info = video_out_drivers[i++]->info; mp_msg(MSGT_GLOBAL, MSGL_INFO,"\t%s\t%s\n", info->short_name, info->name); - } - mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n"); + } + mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n"); } -const vo_functions_t* init_best_video_out(char** vo_list){ +struct vo *init_best_video_out(struct MPOpts *opts, struct vo_x11_state *x11, + struct mp_fifo *key_fifo, + struct input_ctx *input_ctx) +{ + char **vo_list = opts->video_driver_list; int i; + struct vo *vo = talloc_ptrtype(NULL, vo); + struct vo initial_values = { + .opts = opts, + .x11 = x11, + .key_fifo = key_fifo, + .input_ctx = input_ctx, + }; // first try the preferred drivers, with their optional subdevice param: - if(vo_list && vo_list[0]) - while(vo_list[0][0]){ - char* vo=strdup(vo_list[0]); - vo_subdevice=strchr(vo,':'); - if (!strcmp(vo, "pgm")) - mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_PGM_HasBeenReplaced); - if (!strcmp(vo, "md5")) - mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_MD5_HasBeenReplaced); - if(vo_subdevice){ - vo_subdevice[0]=0; - ++vo_subdevice; - } - for(i=0;video_out_drivers[i];i++){ - const vo_functions_t* video_driver=video_out_drivers[i]; - const vo_info_t *info = video_driver->info; - if(!strcmp(info->short_name,vo)){ - // name matches, try it - if(!video_driver->preinit(vo_subdevice)) - { - free(vo); - return video_driver; // success! + if (vo_list && vo_list[0]) + while (vo_list[0][0]) { + char *name = strdup(vo_list[0]); + vo_subdevice = strchr(name,':'); + if (!strcmp(name, "pgm")) + mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "The pgm video output driver has been replaced by -vo pnm:pgmyuv.\n"); + if (!strcmp(name, "md5")) + mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "The md5 video output driver has been replaced by -vo md5sum.\n"); + if (vo_subdevice) { + vo_subdevice[0] = 0; + ++vo_subdevice; + } + for (i = 0; video_out_drivers[i]; i++) { + const struct vo_driver *video_driver = video_out_drivers[i]; + const vo_info_t *info = video_driver->info; + if (!strcmp(info->short_name, name)) { + // name matches, try it + *vo = initial_values; + vo->driver = video_driver; + if (!vo_preinit(vo, vo_subdevice)) { + free(name); + return vo; // success! + } + talloc_free_children(vo); } } + // continue... + free(name); + ++vo_list; + if (!(vo_list[0])) + return NULL; // do NOT fallback to others } - // continue... - free(vo); - ++vo_list; - if(!(vo_list[0])) return NULL; // do NOT fallback to others - } // now try the rest... - vo_subdevice=NULL; - for(i=0;video_out_drivers[i];i++){ - const vo_functions_t* video_driver=video_out_drivers[i]; - if(!video_driver->preinit(vo_subdevice)) - return video_driver; // success! + vo_subdevice = NULL; + for (i = 0; video_out_drivers[i]; i++) { + const struct vo_driver *video_driver = video_out_drivers[i]; + *vo = initial_values; + vo->driver = video_driver; + if (!vo_preinit(vo, vo_subdevice)) + return vo; // success! + talloc_free_children(vo); } + free(vo); return NULL; } -int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height, +int vo_config(struct vo *vo, uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, - char *title, uint32_t format) { - panscan_init(); - aspect_save_orig(width,height); - aspect_save_prescale(d_width,d_height); - - if (vo->control(VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) { - aspect(&d_width,&d_height,A_NOZOOM); - vo_dx = (int)(vo_screenwidth - d_width) / 2; - vo_dy = (int)(vo_screenheight - d_height) / 2; - geometry(&vo_dx, &vo_dy, &d_width, &d_height, - vo_screenwidth, vo_screenheight); - vo_dx += xinerama_x; - vo_dy += xinerama_y; - vo_dwidth = d_width; - vo_dheight = d_height; - } + char *title, uint32_t format) +{ + struct MPOpts *opts = vo->opts; + panscan_init(vo); + aspect_save_orig(vo, width, height); + aspect_save_prescale(vo, d_width, d_height); + + if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) { + aspect(vo, &d_width, &d_height, A_NOZOOM); + vo->dx = (int)(opts->vo_screenwidth - d_width) / 2; + vo->dy = (int)(opts->vo_screenheight - d_height) / 2; + geometry(&vo->dx, &vo->dy, &d_width, &d_height, + opts->vo_screenwidth, opts->vo_screenheight); + vo->dx += xinerama_x; + vo->dy += xinerama_y; + vo->dwidth = d_width; + vo->dheight = d_height; + } - return vo->config(width, height, d_width, d_height, flags, title, format); + int ret = vo->driver->config(vo, width, height, d_width, d_height, flags, + title, format); + vo->config_ok = (ret == 0); + vo->config_count += vo->config_ok; + return ret; } /** @@ -403,8 +511,10 @@ static void src_dst_split_scaling(int src_size, int dst_size, int scaled_src_siz * \param borders the border values as e.g. EOSD (ASS) and properly placed DVD highlight support requires, * may be NULL and only left and top are currently valid. */ -void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, - struct vo_rect *borders, const struct vo_rect *crop) { +void calc_src_dst_rects(struct vo *vo, int src_width, int src_height, + struct vo_rect *src, struct vo_rect *dst, + struct vo_rect *borders, const struct vo_rect *crop) +{ static const struct vo_rect no_crop = {0, 0, 0, 0, 0, 0}; int scaled_width = 0; int scaled_height = 0; @@ -413,25 +523,25 @@ void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, stru src_height -= crop->top + crop->bottom; if (src_width < 2) src_width = 2; if (src_height < 2) src_height = 2; - dst->left = 0; dst->right = vo_dwidth; - dst->top = 0; dst->bottom = vo_dheight; + dst->left = 0; dst->right = vo->dwidth; + dst->top = 0; dst->bottom = vo->dheight; src->left = 0; src->right = src_width; src->top = 0; src->bottom = src_height; if (borders) { borders->left = 0; borders->top = 0; } if (aspect_scaling()) { - aspect(&scaled_width, &scaled_height, A_WINZOOM); - panscan_calc_windowed(); - scaled_width += vo_panscan_x; - scaled_height += vo_panscan_y; + aspect(vo, &scaled_width, &scaled_height, A_WINZOOM); + panscan_calc_windowed(vo); + scaled_width += vo->panscan_x; + scaled_height += vo->panscan_y; if (borders) { - borders->left = (vo_dwidth - scaled_width ) / 2; - borders->top = (vo_dheight - scaled_height) / 2; + borders->left = (vo->dwidth - scaled_width ) / 2; + borders->top = (vo->dheight - scaled_height) / 2; } - src_dst_split_scaling(src_width, vo_dwidth, scaled_width, + src_dst_split_scaling(src_width, vo->dwidth, scaled_width, &src->left, &src->right, &dst->left, &dst->right); - src_dst_split_scaling(src_height, vo_dheight, scaled_height, + src_dst_split_scaling(src_height, vo->dheight, scaled_height, &src->top, &src->bottom, &dst->top, &dst->bottom); } src->left += crop->left; src->right += crop->left; |