summaryrefslogtreecommitdiffstats
path: root/libvo/video_out.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvo/video_out.c')
-rw-r--r--libvo/video_out.c396
1 files changed, 253 insertions, 143 deletions
diff --git a/libvo/video_out.c b/libvo/video_out.c
index 8fca2b85c2..08e59fcb0c 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,60 +78,60 @@ 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_nosw;
-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_nosw;
+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,
@@ -245,9 +236,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
@@ -262,6 +250,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
@@ -290,79 +282,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;
}
/**
@@ -407,8 +515,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;
@@ -417,25 +527,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;