diff options
Diffstat (limited to 'libvo')
80 files changed, 3891 insertions, 3425 deletions
diff --git a/libvo/aclib_template.c b/libvo/aclib_template.c index aa02c81a21..d7b2201944 100644 --- a/libvo/aclib_template.c +++ b/libvo/aclib_template.c @@ -458,4 +458,3 @@ static void * RENAME(mem2agpcpy)(void * to, const void * from, size_t len) if(len) small_memcpy(to, from, len); return retval; } - diff --git a/libvo/aspect.c b/libvo/aspect.c index 9ddc105aee..1b1e5857f3 100644 --- a/libvo/aspect.c +++ b/libvo/aspect.c @@ -19,9 +19,11 @@ /* Stuff for correct aspect scaling. */ #include "aspect.h" #include "geometry.h" +#include "video_out.h" //#ifndef ASPECT_TEST #include "mp_msg.h" #include "help_mp.h" +#include "options.h" //#endif //#define ASPECT_DEBUG @@ -30,157 +32,147 @@ #include <stdio.h> #endif -int vo_panscan_x = 0; -int vo_panscan_y = 0; -float vo_panscan_amount = 0; -float vo_panscanrange = 1.0; - #include "video_out.h" -float force_monitor_aspect=0; -float monitor_aspect=0; -float monitor_pixel_aspect=1; - -static struct { - int orgw; // real width - int orgh; // real height - int prew; // prescaled width - int preh; // prescaled height - int scrw; // horizontal resolution - int scrh; // vertical resolution - float asp; -} aspdat; - -void aspect_save_orig(int orgw, int orgh){ +void aspect_save_orig(struct vo *vo, int orgw, int orgh) +{ #ifdef ASPECT_DEBUG printf("aspect_save_orig %dx%d \n",orgw,orgh); #endif - aspdat.orgw = orgw; - aspdat.orgh = orgh; + vo->aspdat.orgw = orgw; + vo->aspdat.orgh = orgh; } -void aspect_save_prescale(int prew, int preh){ +void aspect_save_prescale(struct vo *vo, int prew, int preh) +{ #ifdef ASPECT_DEBUG printf("aspect_save_prescale %dx%d \n",prew,preh); #endif - aspdat.prew = prew; - aspdat.preh = preh; + vo->aspdat.prew = prew; + vo->aspdat.preh = preh; } -void aspect_save_screenres(int scrw, int scrh){ +void aspect_save_screenres(struct vo *vo, int scrw, int scrh) +{ #ifdef ASPECT_DEBUG printf("aspect_save_screenres %dx%d \n",scrw,scrh); #endif - aspdat.scrw = scrw; - aspdat.scrh = scrh; - if (force_monitor_aspect) - monitor_aspect = force_monitor_aspect; - else - monitor_aspect = monitor_pixel_aspect * scrw / scrh; + struct MPOpts *opts = vo->opts; + vo->aspdat.scrw = scrw; + vo->aspdat.scrh = scrh; + if (opts->force_monitor_aspect) + vo->monitor_aspect = opts->force_monitor_aspect; + else + vo->monitor_aspect = opts->monitor_pixel_aspect * scrw / scrh; } /* aspect is called with the source resolution and the * resolution, that the scaled image should fit into */ -void aspect_fit(int *srcw, int *srch, int fitw, int fith){ +void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith) +{ + struct aspect_data *aspdat = &vo->aspdat; int tmpw; #ifdef ASPECT_DEBUG - printf("aspect(0) fitin: %dx%d screenaspect: %.2f\n",aspdat.scrw,aspdat.scrh, + printf("aspect(0) fitin: %dx%d screenaspect: %.2f\n",aspdat->scrw,aspdat->scrh, monitor_aspect); - printf("aspect(1) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh); + printf("aspect(1) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh); #endif *srcw = fitw; - *srch = (int)(((float)fitw / (float)aspdat.prew * (float)aspdat.preh) - * ((float)aspdat.scrh / ((float)aspdat.scrw / monitor_aspect))); + *srch = (int)(((float)fitw / (float)aspdat->prew * (float)aspdat->preh) + * ((float)aspdat->scrh / ((float)aspdat->scrw / vo->monitor_aspect))); *srch+= *srch%2; // round #ifdef ASPECT_DEBUG - printf("aspect(2) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh); + printf("aspect(2) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh); #endif - if(*srch>fith || *srch<aspdat.orgh){ - tmpw = (int)(((float)fith / (float)aspdat.preh * (float)aspdat.prew) - * ((float)aspdat.scrw / ((float)aspdat.scrh / (1.0/monitor_aspect)))); + if(*srch>fith || *srch<aspdat->orgh){ + tmpw = (int)(((float)fith / (float)aspdat->preh * (float)aspdat->prew) + * ((float)aspdat->scrw / ((float)aspdat->scrh / (1.0/vo->monitor_aspect)))); tmpw+= tmpw%2; // round - if(tmpw<=fitw /*&& tmpw>=aspdat.orgw*/){ + if(tmpw<=fitw /*&& tmpw>=aspdat->orgw*/){ *srch = fith; *srcw = tmpw; }else{ #ifndef ASPECT_TEST - mp_msg(MSGT_VO,MSGL_WARN,MSGTR_LIBVO_ASPECT_NoSuitableNewResFound); + mp_tmsg(MSGT_VO,MSGL_WARN,"[ASPECT] Warning: No suitable new res found!\n"); #else - mp_msg(MSGT_VO,MSGL_WARN,MSGTR_LIBVO_ASPECT_NoNewSizeFoundThatFitsIntoRes); + mp_tmsg(MSGT_VO,MSGL_WARN,"[ASPECT] Error: No new size found that fits into res!\n"); #endif } } - aspdat.asp=*srcw / (float)*srch; + aspdat->asp=*srcw / (float)*srch; #ifdef ASPECT_DEBUG - printf("aspect(3) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh); + printf("aspect(3) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh); #endif } -static void get_max_dims(int *w, int *h, int zoom) +static void get_max_dims(struct vo *vo, int *w, int *h, int zoom) { - *w = zoom ? aspdat.scrw : aspdat.prew; - *h = zoom ? aspdat.scrh : aspdat.preh; + struct aspect_data *aspdat = &vo->aspdat; + *w = zoom ? aspdat->scrw : aspdat->prew; + *h = zoom ? aspdat->scrh : aspdat->preh; if (zoom && WinID >= 0) zoom = A_WINZOOM; if (zoom == A_WINZOOM) { - *w = vo_dwidth; - *h = vo_dheight; + *w = vo->dwidth; + *h = vo->dheight; } } -void aspect(int *srcw, int *srch, int zoom){ +void aspect(struct vo *vo, int *srcw, int *srch, int zoom) +{ int fitw; int fith; - get_max_dims(&fitw, &fith, zoom); + get_max_dims(vo, &fitw, &fith, zoom); if( !zoom && geometry_wh_changed ) { #ifdef ASPECT_DEBUG printf("aspect(0) no aspect forced!\n"); #endif return; // the user doesn't want to fix aspect } - aspect_fit(srcw, srch, fitw, fith); + aspect_fit(vo, srcw, srch, fitw, fith); } -void panscan_init( void ) +void panscan_init(struct vo *vo) { - vo_panscan_x=0; - vo_panscan_y=0; - vo_panscan_amount=0.0f; + vo->panscan_x = 0; + vo->panscan_y = 0; + vo->panscan_amount = 0.0f; } -static void panscan_calc_internal(int zoom) +static void panscan_calc_internal(struct vo *vo, int zoom) { int fwidth,fheight; int vo_panscan_area; int max_w, max_h; - get_max_dims(&max_w, &max_h, zoom); - - if (vo_panscanrange > 0) { - aspect(&fwidth,&fheight,zoom); - vo_panscan_area = max_h - fheight; - if (!vo_panscan_area) - vo_panscan_area = max_w - fwidth; - vo_panscan_area *= vo_panscanrange; - } else - vo_panscan_area = -vo_panscanrange * max_h; - - vo_panscan_amount = vo_fs || zoom == A_WINZOOM ? vo_panscan : 0; - vo_panscan_x = vo_panscan_area * vo_panscan_amount * aspdat.asp; - vo_panscan_y = vo_panscan_area * vo_panscan_amount; + get_max_dims(vo, &max_w, &max_h, zoom); + struct MPOpts *opts = vo->opts; + + if (opts->vo_panscanrange > 0) { + aspect(vo, &fwidth, &fheight, zoom); + vo_panscan_area = max_h - fheight; + if (!vo_panscan_area) + vo_panscan_area = max_w - fwidth; + vo_panscan_area *= opts->vo_panscanrange; + } else + vo_panscan_area = -opts->vo_panscanrange * max_h; + + vo->panscan_amount = vo_fs || zoom == A_WINZOOM ? vo_panscan : 0; + vo->panscan_x = vo_panscan_area * vo->panscan_amount * vo->aspdat.asp; + vo->panscan_y = vo_panscan_area * vo->panscan_amount; } -void panscan_calc(void) +void panscan_calc(struct vo *vo) { - panscan_calc_internal(A_ZOOM); + panscan_calc_internal(vo, A_ZOOM); } /** * vos that set vo_dwidth and v_dheight correctly should call this to update * vo_panscan_x and vo_panscan_y */ -void panscan_calc_windowed(void) +void panscan_calc_windowed(struct vo *vo) { - panscan_calc_internal(A_WINZOOM); + panscan_calc_internal(vo, A_WINZOOM); } diff --git a/libvo/aspect.h b/libvo/aspect.h index 0654d86c9f..07f928a9ff 100644 --- a/libvo/aspect.h +++ b/libvo/aspect.h @@ -20,25 +20,38 @@ #define MPLAYER_ASPECT_H /* Stuff for correct aspect scaling. */ -extern int vo_panscan_x; -extern int vo_panscan_y; -extern float vo_panscan_amount; +struct vo; +void panscan_init(struct vo *vo); +void panscan_calc(struct vo *vo); +void panscan_calc_windowed(struct vo *vo); -void panscan_init(void); -void panscan_calc(void); -void panscan_calc_windowed(void); +void aspect_save_orig(struct vo *vo, int orgw, int orgh); -void aspect_save_orig(int orgw, int orgh); +void aspect_save_prescale(struct vo *vo, int prew, int preh); -void aspect_save_prescale(int prew, int preh); - -void aspect_save_screenres(int scrw, int scrh); +void aspect_save_screenres(struct vo *vo, int scrw, int scrh); #define A_WINZOOM 2 ///< zoom to fill window size #define A_ZOOM 1 #define A_NOZOOM 0 -void aspect(int *srcw, int *srch, int zoom); -void aspect_fit(int *srcw, int *srch, int fitw, int fith); +void aspect(struct vo *vo, int *srcw, int *srch, int zoom); +void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith); + + +#ifdef IS_OLD_VO +#define vo_panscan_x global_vo->panscan_x +#define vo_panscan_y global_vo->panscan_y +#define vo_panscan_amount global_vo->panscan_amount +#define monitor_aspect global_vo->monitor_aspect + +#define panscan_init() panscan_init(global_vo) +#define panscan_calc() panscan_calc(global_vo) +#define panscan_calc_windowed() panscan_calc_windowed(global_vo) +#define aspect_save_orig(...) aspect_save_orig(global_vo, __VA_ARGS__) +#define aspect_save_prescale(...) aspect_save_prescale(global_vo, __VA_ARGS__) +#define aspect_save_screenres(...) aspect_save_screenres(global_vo, __VA_ARGS__) +#define aspect(...) aspect(global_vo, __VA_ARGS__) +#endif #endif /* MPLAYER_ASPECT_H */ diff --git a/libvo/aspecttest.c b/libvo/aspecttest.c index fcd912bb28..b73e8c589c 100644 --- a/libvo/aspecttest.c +++ b/libvo/aspecttest.c @@ -63,4 +63,3 @@ int main(int argc, char *argv[]) { printf("new size: %dx%d\n",w,h); return 0; } - diff --git a/libvo/font_load.h b/libvo/font_load.h index 8dd494b941..4776ff135d 100644 --- a/libvo/font_load.h +++ b/libvo/font_load.h @@ -80,7 +80,6 @@ typedef struct font_desc { } font_desc_t; extern font_desc_t* vo_font; -extern font_desc_t* sub_font; extern char *subtitle_font_encoding; extern float text_font_scale_factor; diff --git a/libvo/font_load_ft.c b/libvo/font_load_ft.c index fe3845f7a9..ae2c6cc2ba 100644 --- a/libvo/font_load_ft.c +++ b/libvo/font_load_ft.c @@ -84,13 +84,13 @@ static FT_Library library; #define OSD_CHARSET_SIZE 15 -static FT_ULong osd_charset[OSD_CHARSET_SIZE] = +static const FT_ULong osd_charset[OSD_CHARSET_SIZE] = { 0xe001, 0xe002, 0xe003, 0xe004, 0xe005, 0xe006, 0xe007, 0xe008, 0xe009, 0xe00a, 0xe00b, 0xe010, 0xe011, 0xe012, 0xe013 }; -static FT_ULong osd_charcodes[OSD_CHARSET_SIZE] = +static const FT_ULong osd_charcodes[OSD_CHARSET_SIZE] = { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x0b,0x10,0x11,0x12,0x13 @@ -920,7 +920,7 @@ static int load_sub_face(const char *name, int face_index, FT_Face *face) if (err) { err = FT_New_Face(library, MPLAYER_DATADIR "/subfont.ttf", 0, face); if (err) { - mp_msg(MSGT_OSD, MSGL_ERR, MSGTR_LIBVO_FONT_LOAD_FT_NewFaceFailed); + mp_tmsg(MSGT_OSD, MSGL_ERR, "New_Face failed. Maybe the font path is wrong.\nPlease supply the text font file (~/.mplayer/subfont.ttf).\n"); return -1; } } @@ -931,7 +931,7 @@ static int load_sub_face(const char *name, int face_index, FT_Face *face) static int load_osd_face(FT_Face *face) { if ( FT_New_Memory_Face(library, osd_font_pfb, sizeof(osd_font_pfb), 0, face) ) { - mp_msg(MSGT_OSD, MSGL_ERR, MSGTR_LIBVO_FONT_LOAD_FT_NewMemoryFaceFailed); + mp_tmsg(MSGT_OSD, MSGL_ERR, "New_Memory_Face failed..\n"); return -1; } return 0; @@ -1018,7 +1018,7 @@ font_desc_t* read_font_desc_ft(const char *fname, int face_index, int movie_widt /* generate the subtitle font */ err = load_sub_face(fname, face_index, &face); if (err) { - mp_msg(MSGT_OSD, MSGL_WARN, MSGTR_LIBVO_FONT_LOAD_FT_SubFaceFailed); + mp_tmsg(MSGT_OSD, MSGL_WARN, "subtitle font: load_sub_face failed.\n"); goto gen_osd; } desc->face_cnt++; @@ -1035,7 +1035,7 @@ font_desc_t* read_font_desc_ft(const char *fname, int face_index, int movie_widt } if (charset_size < 0) { - mp_msg(MSGT_OSD, MSGL_ERR, MSGTR_LIBVO_FONT_LOAD_FT_SubFontCharsetFailed); + mp_tmsg(MSGT_OSD, MSGL_ERR, "subtitle font: prepare_charset failed.\n"); goto err_out; } #else @@ -1049,7 +1049,7 @@ font_desc_t* read_font_desc_ft(const char *fname, int face_index, int movie_widt subtitle_font_thickness, subtitle_font_radius); if (err) { - mp_msg(MSGT_OSD, MSGL_ERR, MSGTR_LIBVO_FONT_LOAD_FT_CannotPrepareSubtitleFont); + mp_tmsg(MSGT_OSD, MSGL_ERR, "Cannot prepare subtitle font.\n"); goto err_out; } @@ -1067,14 +1067,14 @@ gen_osd: subtitle_font_thickness, subtitle_font_radius); if (err) { - mp_msg(MSGT_OSD, MSGL_ERR, MSGTR_LIBVO_FONT_LOAD_FT_CannotPrepareOSDFont); + mp_tmsg(MSGT_OSD, MSGL_ERR, "Cannot prepare OSD font.\n"); goto err_out; } err = generate_tables(desc, subtitle_font_thickness, subtitle_font_radius); if (err) { - mp_msg(MSGT_OSD, MSGL_ERR, MSGTR_LIBVO_FONT_LOAD_FT_CannotGenerateTables); + mp_tmsg(MSGT_OSD, MSGL_ERR, "Cannot generate tables.\n"); goto err_out; } @@ -1129,7 +1129,7 @@ int done_freetype(void) err = FT_Done_FreeType(library); if (err) { - mp_msg(MSGT_OSD, MSGL_ERR, MSGTR_LIBVO_FONT_LOAD_FT_DoneFreeTypeFailed); + mp_tmsg(MSGT_OSD, MSGL_ERR, "FT_Done_FreeType failed.\n"); return -1; } diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 1bf8c906c3..f827771a97 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -32,6 +32,7 @@ #include <string.h> #include <ctype.h> #include <math.h> +#include "old_vo_defines.h" #include "gl_common.h" #include "libavutil/common.h" @@ -1686,4 +1687,3 @@ void swapGlBuffers(void) { glXSwapBuffers(mDisplay, vo_window); } #endif - diff --git a/libvo/gl_common.h b/libvo/gl_common.h index 8f9ce55dab..56fcbba0e3 100644 --- a/libvo/gl_common.h +++ b/libvo/gl_common.h @@ -353,18 +353,18 @@ void glDisableYUVConversion(GLenum target, int type); /** \} */ #ifdef GL_WIN32 -#define vo_border() vo_w32_border() +#define vo_gl_border(vo) vo_w32_border() #define vo_check_events() vo_w32_check_events() #define vo_fullscreen() vo_w32_fullscreen() -#define vo_ontop() vo_w32_ontop() +#define vo_gl_ontop() vo_w32_ontop() #define vo_uninit() vo_w32_uninit() int setGlWindow(int *vinfo, HGLRC *context, HWND win); void releaseGlContext(int *vinfo, HGLRC *context); #else -#define vo_border() vo_x11_border() +#define vo_gl_border(vo) vo_x11_border(vo) #define vo_check_events() vo_x11_check_events(mDisplay) #define vo_fullscreen() vo_x11_fullscreen() -#define vo_ontop() vo_x11_ontop() +#define vo_gl_ontop() vo_x11_ontop() #define vo_uninit() vo_x11_uninit() int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win); void releaseGlContext(XVisualInfo **vinfo, GLXContext *context); diff --git a/libvo/gtf.c b/libvo/gtf.c index ce82d39a70..6dd64a57c8 100644 --- a/libvo/gtf.c +++ b/libvo/gtf.c @@ -302,5 +302,3 @@ void GTF_calcTimings(double X,double Y,double freq, int type, result-> RefreshRate = actual_V_frame_freq*100;/* Refresh rate in units of 0.01 Hz*/ } - - diff --git a/libvo/mga_common.c b/libvo/mga_common.c index 13b73d1b45..9a173b3ded 100644 --- a/libvo/mga_common.c +++ b/libvo/mga_common.c @@ -23,6 +23,7 @@ #include "libmpcodecs/vf_scale.h" #include "mp_msg.h" #include "help_mp.h" +#include "old_vo_wrapper.h" // mga_vid drawing functions static void set_window( void ); /* forward declaration to kill warnings */ @@ -242,11 +243,11 @@ static void mga_fullscreen(void) mga_vid_config.x_org=(vo_screenwidth-w)/2; mga_vid_config.y_org=(vo_screenheight-h)/2; if ( ioctl( f,MGA_VID_CONFIG,&mga_vid_config ) ) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_ErrorInConfigIoctl ); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] error in mga_vid_config ioctl (wrong mga_vid.o version?)" ); } #endif -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -257,36 +258,35 @@ static int control(uint32_t request, void *data, ...) return draw_image(data); case VOCTRL_SET_EQUALIZER: { - va_list ap; short value; uint32_t luma,prev; + struct voctrl_set_equalizer_args *args = data; - if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE; + if (strcmp(args->name, "brightness") && strcmp(args->name, "contrast")) + return VO_FALSE; if (ioctl(f,MGA_VID_GET_LUMA,&prev)) { perror("Error in mga_vid_config ioctl()"); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_CouldNotGetLumaValuesFromTheKernelModule); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] Could not get luma values from the kernel module!\n"); return VO_FALSE; } // printf("GET: 0x%4X 0x%4X \n",(prev>>16),(prev&0xffff)); - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); + value = args->value; // printf("value: %d -> ",value); value=((value+100)*255)/200-128; // maps -100=>-128 and +100=>127 // printf("%d \n",value); - if(!strcmp(data,"contrast")) + if (!strcmp(args->name, "contrast")) luma = (prev&0xFFFF0000)|(value&0xFFFF); else luma = (prev&0xFFFF)|(value<<16); if (ioctl(f,MGA_VID_SET_LUMA,luma)) { perror("Error in mga_vid_config ioctl()"); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_CouldNotSetLumaValuesFromTheKernelModule); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] Could not set luma values from the kernel module!\n"); return VO_FALSE; } @@ -295,29 +295,25 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_GET_EQUALIZER: { - va_list ap; - int * value; short val; uint32_t luma; + struct voctrl_get_equalizer_args *args = data; - if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE; + if (strcmp(args->name, "brightness") && strcmp(args->name, "contrast")) + return VO_FALSE; if (ioctl(f,MGA_VID_GET_LUMA,&luma)) { perror("Error in mga_vid_config ioctl()"); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_CouldNotGetLumaValuesFromTheKernelModule); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] Could not get luma values from the kernel module!\n"); return VO_FALSE; } - if ( !strcmp( data,"contrast" ) ) + if (!strcmp(args->name, "contrast")) val=(luma & 0xFFFF); else val=(luma >> 16); - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - *value = (val*200)/255; + *args->valueptr = (val*200)/255; return VO_TRUE; } @@ -327,18 +323,13 @@ static int control(uint32_t request, void *data, ...) if (vo_screenwidth && vo_screenheight) mga_fullscreen(); else - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_ScreenWidthHeightUnknown); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] Screen width/height unknown!\n"); return VO_TRUE; case VOCTRL_GET_PANSCAN: if ( !vo_fs ) return VO_FALSE; return VO_TRUE; #endif -#if defined(VO_XMGA) && defined(CONFIG_GUI) - case VOCTRL_GUISUPPORT: - return VO_TRUE; -#endif - #ifdef VO_XMGA case VOCTRL_ONTOP: vo_x11_ontop(); @@ -384,7 +375,7 @@ static int mga_init(int width,int height,unsigned int format){ mga_vid_config.frame_size = ((width + 31) & ~31) * height * 2; mga_vid_config.format=MGA_VID_FORMAT_UYVY; break; default: - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_InvalidOutputFormat,format); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] invalid output format %0X\n",format); return -1; } @@ -402,7 +393,7 @@ static int mga_init(int width,int height,unsigned int format){ if(width > 1024 && height > 1024) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_MGA_ResolutionTooHigh); + mp_tmsg(MSGT_VO,MSGL_ERR, "[MGA] Source resolution exceeds 1023x1023 in at least one dimension.\n[MGA] Rescale in software or use -lavdopts lowres=1.\n"); return -1; } else if(height <= 1024) { @@ -413,13 +404,13 @@ static int mga_init(int width,int height,unsigned int format){ if(mga_vid_config.card_type != MGA_G550) { // we don't have a G550, so our resolution is too high - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_MGA_ResolutionTooHigh); + mp_tmsg(MSGT_VO,MSGL_ERR, "[MGA] Source resolution exceeds 1023x1023 in at least one dimension.\n[MGA] Rescale in software or use -lavdopts lowres=1.\n"); return -1; } else { // there is a deeper problem // we have a G550, but still couldn't configure mga_vid perror("Error in mga_vid_config ioctl()"); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_IncompatibleDriverVersion); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] Your mga_vid driver version is incompatible with this MPlayer version!\n"); return -1; } // if we arrived here, then we could successfully configure mga_vid @@ -430,7 +421,7 @@ static int mga_init(int width,int height,unsigned int format){ if (ioctl(f,MGA_VID_CONFIG,&mga_vid_config)) { perror("Error in mga_vid_config ioctl()"); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_IncompatibleDriverVersion); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] Your mga_vid driver version is incompatible with this MPlayer version!\n"); return -1; } } @@ -474,7 +465,7 @@ static int preinit(const char *vo_subdevice) if(f == -1) { perror("open"); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_CouldntOpen,devname); + mp_tmsg(MSGT_VO,MSGL_WARN, "[MGA] Couldn't open: %s\n",devname); return -1; } @@ -484,7 +475,7 @@ static int preinit(const char *vo_subdevice) ioctl(f,MGA_VID_GET_VERSION,&ver); if(MGA_VID_VERSION != ver) { - mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_MGA_mgavidVersionMismatch, ver, MGA_VID_VERSION); + mp_tmsg(MSGT_VO, MSGL_ERR, "[MGA] mismatch between kernel (%u) and MPlayer (%u) mga_vid driver versions\n", ver, MGA_VID_VERSION); return -1; } diff --git a/libvo/old_vo_defines.h b/libvo/old_vo_defines.h new file mode 100644 index 0000000000..feded12d5b --- /dev/null +++ b/libvo/old_vo_defines.h @@ -0,0 +1,24 @@ +#ifndef MPLAYER_OLD_VO_DEFINES_H +#define MPLAYER_OLD_VO_DEFINES_H + +#include "options.h" +#include "video_out.h" +#include "old_vo_wrapper.h" + +// Triggers more defines in x11_common.h +#define IS_OLD_VO 1 + +#define vo_ontop global_vo->opts->vo_ontop +#define vo_config_count global_vo->config_count +#define vo_dx global_vo->dx +#define vo_dy global_vo->dy +#define vo_dwidth global_vo->dwidth +#define vo_dheight global_vo->dheight +#define vo_dbpp global_vo->opts->vo_dbpp +#define vo_screenwidth global_vo->opts->vo_screenwidth +#define vo_screenheight global_vo->opts->vo_screenheight +#define vidmode global_vo->opts->vidmode +#define movie_aspect global_vo->opts->movie_aspect + +#define calc_src_dst_rects(...) calc_src_dst_rects(global_vo, __VA_ARGS__) +#endif diff --git a/libvo/old_vo_wrapper.c b/libvo/old_vo_wrapper.c new file mode 100644 index 0000000000..bdbc8b8349 --- /dev/null +++ b/libvo/old_vo_wrapper.c @@ -0,0 +1,116 @@ +/* + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#include <stdint.h> +#include "old_vo_wrapper.h" +#include "video_out.h" +#include "sub.h" + +struct vo *global_vo; +struct osd_state *global_osd; + +int old_vo_preinit(struct vo *vo, const char *arg) +{ + global_vo = vo; + return vo->driver->old_functions->preinit(arg); +} + + +int old_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) +{ + return vo->driver->old_functions->config(width, height, d_width, + d_height, flags, title, format); +} + + +int old_vo_control(struct vo *vo, uint32_t request, void *data) +{ + return vo->driver->old_functions->control(request, data); +} + + +int old_vo_draw_frame(struct vo *vo, uint8_t *src[]) +{ + return vo->driver->old_functions->draw_frame(src); +} + + +int old_vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], + int w, int h, int x, int y) +{ + return vo->driver->old_functions->draw_slice(src, stride, w, h, x, y); +} + + +void old_vo_draw_osd(struct vo *vo, struct osd_state *osd) +{ + global_osd = osd; + vo->driver->old_functions->draw_osd(); +} + + +void old_vo_flip_page(struct vo *vo) +{ + vo->driver->old_functions->flip_page(); +} + + +void old_vo_check_events(struct vo *vo) +{ + vo->driver->old_functions->check_events(); +} + + +void old_vo_uninit(struct vo *vo) +{ + vo->driver->old_functions->uninit(); +} + + +static void draw_alpha_wrapper(void *ctx, int x0, int y0, int w, int h, + unsigned char *src, unsigned char *srca, + int stride) +{ + void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride) = ctx; + draw_alpha(x0, y0, w, h, src, srca, stride); +} + + +void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) +{ + osd_draw_text(global_osd, dxs, dys, draw_alpha_wrapper, draw_alpha); +} + +void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, + int right_border, int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(int x0, int y0, int w,int h, + unsigned char* src, + unsigned char *srca, int stride)) +{ + osd_draw_text_ext(global_osd, dxs, dys, left_border, top_border, + right_border, bottom_border, orig_w, orig_h, + draw_alpha_wrapper, draw_alpha); +} + +int vo_update_osd(int dxs, int dys) +{ + return osd_update(global_osd, dxs, dys); +} diff --git a/libvo/old_vo_wrapper.h b/libvo/old_vo_wrapper.h new file mode 100644 index 0000000000..250a1187fe --- /dev/null +++ b/libvo/old_vo_wrapper.h @@ -0,0 +1,29 @@ +#ifndef MPLAYER_OLD_VO_WRAPPER_H +#define MPLAYER_OLD_VO_WRAPPER_H + +#include <stdint.h> +#include "video_out.h" + +extern struct vo *global_vo; +extern struct osd_state *global_osd; + +int old_vo_preinit(struct vo *vo, const char *); +int old_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); +int old_vo_control(struct vo *vo, uint32_t request, void *data); +int old_vo_draw_frame(struct vo *vo, uint8_t *src[]); +int old_vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], + int w, int h, int x, int y); +void old_vo_draw_osd(struct vo *vo, struct osd_state *osd); +void old_vo_flip_page(struct vo *vo); +void old_vo_check_events(struct vo *vo); +void old_vo_uninit(struct vo *vo); + +void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); +void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, + int right_border, int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(int x0, int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride)); +int vo_update_osd(int dxs, int dys); + +#endif diff --git a/libvo/osd.c b/libvo/osd.c index 9f17bdb31e..a3664dadb3 100644 --- a/libvo/osd.c +++ b/libvo/osd.c @@ -391,4 +391,3 @@ void vo_draw_alpha_rgb16(int w,int h, unsigned char* src, unsigned char *srca, i } return; } - diff --git a/libvo/osx_common.c b/libvo/osx_common.c index b953860e36..e82bc7aa6e 100644 --- a/libvo/osx_common.c +++ b/libvo/osx_common.c @@ -20,6 +20,7 @@ // only to get keycode definitions from HIToolbox/Events.h #include <Carbon/Carbon.h> #include "osx_common.h" +#include "old_vo_defines.h" #include "video_out.h" #include "osdep/keycodes.h" #include "input/input.h" @@ -127,7 +128,7 @@ void change_movie_aspect(float new_aspect) new_aspect = old_movie_aspect; our_aspect_change = 1; snprintf(cmd_str, sizeof(cmd_str), "switch_ratio %f", new_aspect); - mp_input_queue_cmd(mp_input_parse_cmd(cmd_str)); + mp_input_queue_cmd(global_vo->input_ctx, mp_input_parse_cmd(cmd_str)); } /** diff --git a/libvo/spuenc.c b/libvo/spuenc.c index 670a393bc2..bc35a06d18 100644 --- a/libvo/spuenc.c +++ b/libvo/spuenc.c @@ -229,50 +229,3 @@ pixbuf_encode_rle(int x, int y, int w, int h, char *inbuf, int stride,encodedat } encode_do_control(x,y, ed, &pb); } - - -void -pixbuf_load_xpm( pixbuf* pb, char* xpm[] ) { - int colors, chrs, l, n; - char c[4], table[256]; - unsigned char *b, *i; - - sscanf( xpm[0], "%d %d %d %d", &pb->x, &pb->y, &colors, &chrs); - if( colors > 4 ) { - fprintf( stderr, "the pixmap MUST be 4 colors or less\n"); - exit (-1); - } - if( chrs != 1 ) { - fprintf( stderr, "the XPM format MUST be 1 char per pixel\n"); - exit (-1); - } - if( pb->x > 0xFFF || pb->y > 0xFFF ) { - fprintf( stderr, "the size is excesive\n"); - exit (-1); - } - - for( l=0; l<colors; l++ ) { - n= sscanf( xpm[l+1], "%c c #%x", &c[l], &pb->rgb[l]); - if( n < 2 ) { - /* this one is transparent */ - pb->rgb[l]=0xff000000; - } - table[(int)c[l]]=l; - } - - pb->pixels= malloc( pb->x * pb->y ); - b= pb->pixels; - - for( l= colors+1; l <= pb->y + colors; l++ ) { - i= xpm[l]; - while( (int)*i) { - *b++ = table[*i++]; - } - } -} - -void -pixbuf_delete( pixbuf* pb ) { - free( pb->pixels ); -} - diff --git a/libvo/spuenc.h b/libvo/spuenc.h index 5bc83b329b..7f4590b4ac 100644 --- a/libvo/spuenc.h +++ b/libvo/spuenc.h @@ -41,6 +41,5 @@ typedef struct { } encodedata; void pixbuf_encode_rle(int x, int y, int w, int h, char *inbuf, int stride, encodedata *ed); -void pixbuf_delete(pixbuf* pb); #endif /* MPLAYER_SPUENC_H */ diff --git a/libvo/sub.c b/libvo/sub.c index d0abbf30cc..3187f935ea 100644 --- a/libvo/sub.c +++ b/libvo/sub.c @@ -32,6 +32,7 @@ #include "libmpcodecs/dec_teletext.h" #include "osdep/timer.h" +#include "talloc.h" #include "mplayer.h" #include "mp_msg.h" #include "help_mp.h" @@ -64,28 +65,26 @@ struct osd_text_p { }; //^ -char * sub_osd_names[]={ - MSGTR_VO_SUB_Seekbar, - MSGTR_VO_SUB_Play, - MSGTR_VO_SUB_Pause, - MSGTR_VO_SUB_Stop, - MSGTR_VO_SUB_Rewind, - MSGTR_VO_SUB_Forward, - MSGTR_VO_SUB_Clock, - MSGTR_VO_SUB_Contrast, - MSGTR_VO_SUB_Saturation, - MSGTR_VO_SUB_Volume, - MSGTR_VO_SUB_Brightness, - MSGTR_VO_SUB_Hue, - MSGTR_VO_SUB_Balance +char * const sub_osd_names[]={ + _("Seekbar"), + _("Play"), + _("Pause"), + _("Stop"), + _("Rewind"), + _("Forward"), + _("Clock"), + _("Contrast"), + _("Saturation"), + _("Volume"), + _("Brightness"), + _("Hue"), + _("Balance") }; -char * sub_osd_names_short[] ={ "", "|>", "||", "[]", "<<" , ">>", "", "", "", "", "", "", "" }; +char * const sub_osd_names_short[] ={ "", "|>", "||", "[]", "<<" , ">>", "", "", "", "", "", "", "" }; //static int vo_font_loaded=-1; font_desc_t* vo_font=NULL; -font_desc_t* sub_font=NULL; -unsigned char* vo_osd_text=NULL; void* vo_osd_teletext_page=NULL; int vo_osd_teletext_half = 0; int vo_osd_teletext_mode=0; @@ -165,9 +164,11 @@ static void alloc_buf(mp_osd_obj_t* obj) } // renders the buffer -inline static void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ +inline static void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx) +{ if (obj->allocated > 0) { - draw_alpha(obj->bbox.x1,obj->bbox.y1, + draw_alpha(ctx, + obj->bbox.x1,obj->bbox.y1, obj->bbox.x2-obj->bbox.x1, obj->bbox.y2-obj->bbox.y1, obj->bitmap_buffer, @@ -190,8 +191,10 @@ no_utf8: return c; } -inline static void vo_update_text_osd(mp_osd_obj_t* obj,int dxs,int dys){ - const char *cp=vo_osd_text; +inline static void vo_update_text_osd(struct osd_state *osd, mp_osd_obj_t* obj, + int dxs, int dys) +{ + const char *cp = osd->osd_text; int x=20; int h=0; int font; @@ -212,7 +215,7 @@ inline static void vo_update_text_osd(mp_osd_obj_t* obj,int dxs,int dys){ alloc_buf(obj); - cp=vo_osd_text; + cp = osd->osd_text; x = obj->x; while (*cp){ uint16_t c=utf8_get_char(&cp); @@ -667,7 +670,7 @@ inline static void vo_update_text_progbar(mp_osd_obj_t* obj,int dxs,int dys){ subtitle* vo_sub=NULL; -inline static void vo_update_text_sub(mp_osd_obj_t* obj,int dxs,int dys){ +inline static void vo_update_text_sub(struct osd_state *osd, mp_osd_obj_t* obj,int dxs,int dys){ unsigned char *t; int c,i,j,l,x,y,font,prevc,counter; int k; @@ -676,10 +679,11 @@ inline static void vo_update_text_sub(mp_osd_obj_t* obj,int dxs,int dys){ int xmin=dxs,xmax=0; int h,lasth; int xtblc, utblc; + struct font_desc *sub_font = osd->sub_font; obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; - if(!vo_sub || !sub_font || !sub_visibility || (sub_font->font[40]<0)){ + if(!vo_sub || !osd->sub_font || !sub_visibility || (sub_font->font[40]<0)){ obj->flags&=~OSDFLAG_VISIBLE; return; } @@ -1050,9 +1054,9 @@ inline static void vo_update_spudec_sub(mp_osd_obj_t* obj, int dxs, int dys) obj->flags |= OSDFLAG_BBOX; } -inline static void vo_draw_spudec_sub(mp_osd_obj_t* obj, void (*draw_alpha)(int x0, int y0, int w, int h, unsigned char* src, unsigned char* srca, int stride)) +inline static void vo_draw_spudec_sub(mp_osd_obj_t* obj, void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, unsigned char* src, unsigned char* srca, int stride), void *ctx) { - spudec_draw_scaled(vo_spudec, obj->dxs, obj->dys, draw_alpha); + spudec_draw_scaled(vo_spudec, obj->dxs, obj->dys, draw_alpha, ctx); } void *vo_spudec=NULL; @@ -1076,7 +1080,8 @@ static mp_osd_obj_t* new_osd_obj(int type){ return osd; } -void free_osd_list(void){ +void osd_free(struct osd_state *osd) +{ mp_osd_obj_t* obj=vo_osd_list; while(obj){ mp_osd_obj_t* next=obj->next; @@ -1086,12 +1091,15 @@ void free_osd_list(void){ obj=next; } vo_osd_list=NULL; + talloc_free(osd); } #define FONT_LOAD_DEFER 6 -int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, - int right_border, int bottom_border, int orig_w, int orig_h){ +int osd_update_ext(struct osd_state *osd, int dxs, int dys, int left_border, + int top_border, int right_border, int bottom_border, + int orig_w, int orig_h) +{ mp_osd_obj_t* obj=vo_osd_list; int chg=0; #ifdef CONFIG_FREETYPE @@ -1121,20 +1129,20 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, force_load_font = 0; load_font_ft(dxs, dys, &vo_font, font_name, osd_font_scale_factor); if (sub_font_name) - load_font_ft(dxs, dys, &sub_font, sub_font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, sub_font_name, text_font_scale_factor); else - load_font_ft(dxs, dys, &sub_font, font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, font_name, text_font_scale_factor); prev_dxs = dxs; prev_dys = dys; defer_counter = 0; } else { if (!vo_font) load_font_ft(dxs, dys, &vo_font, font_name, osd_font_scale_factor); - if (!sub_font) { + if (!osd->sub_font) { if (sub_font_name) - load_font_ft(dxs, dys, &sub_font, sub_font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, sub_font_name, text_font_scale_factor); else - load_font_ft(dxs, dys, &sub_font, font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, font_name, text_font_scale_factor); } } #endif @@ -1150,7 +1158,7 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, break; #endif case OSDTYPE_SUBTITLE: - vo_update_text_sub(obj,dxs,dys); + vo_update_text_sub(osd, obj,dxs,dys); break; case OSDTYPE_TELETEXT: vo_update_text_teletext(obj,dxs,dys); @@ -1167,8 +1175,8 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, obj->flags&=~OSDFLAG_VISIBLE; break; case OSDTYPE_OSD: - if(vo_font && vo_osd_text && vo_osd_text[0]){ - vo_update_text_osd(obj,dxs,dys); // update bbox + if(vo_font && osd->osd_text[0]){ + vo_update_text_osd(osd, obj, dxs, dys); // update bbox obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; } else obj->flags&=~OSDFLAG_VISIBLE; @@ -1208,16 +1216,20 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, return chg; } -int vo_update_osd(int dxs, int dys) { - return vo_update_osd_ext(dxs, dys, 0, 0, 0, 0, dxs, dys); +int osd_update(struct osd_state *osd, int dxs, int dys) +{ + return osd_update_ext(osd, dxs, dys, 0, 0, 0, 0, dxs, dys); } -void vo_init_osd(void){ +struct osd_state *osd_create(void) +{ + struct osd_state *osd = talloc_zero(NULL, struct osd_state); + *osd = (struct osd_state){ + }; if(!draw_alpha_init_flag){ draw_alpha_init_flag=1; vo_draw_alpha_init(); } - if(vo_osd_list) free_osd_list(); // temp hack, should be moved to mplayer/mencoder later new_osd_obj(OSDTYPE_OSD); new_osd_obj(OSDTYPE_SUBTITLE); @@ -1230,13 +1242,16 @@ void vo_init_osd(void){ #ifdef CONFIG_FREETYPE force_load_font = 1; #endif + return osd; } int vo_osd_changed_flag=0; -void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h)){ +void osd_remove_text(struct osd_state *osd, int dxs, int dys, + void (*remove)(int x0, int y0, int w, int h)) +{ mp_osd_obj_t* obj=vo_osd_list; - vo_update_osd(dxs,dys); + osd_update(osd, dxs, dys); while(obj){ if(((obj->flags&OSDFLAG_CHANGED) || (obj->flags&OSDFLAG_VISIBLE)) && (obj->flags&OSDFLAG_OLD_BBOX)){ @@ -1252,17 +1267,24 @@ void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h)){ } } -void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, - int right_border, int bottom_border, int orig_w, int orig_h, - void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) { +void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys, + int left_border, int top_border, int right_border, + int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, + int h, unsigned char* src, + unsigned char *srca, + int stride), + void *ctx) +{ mp_osd_obj_t* obj=vo_osd_list; - vo_update_osd_ext(dxs, dys, left_border, top_border, right_border, bottom_border, orig_w, orig_h); + osd_update_ext(osd, dxs, dys, left_border, top_border, right_border, + bottom_border, orig_w, orig_h); while(obj){ if(obj->flags&OSDFLAG_VISIBLE){ vo_osd_changed_flag=obj->flags&OSDFLAG_CHANGED; // temp hack switch(obj->type){ case OSDTYPE_SPU: - vo_draw_spudec_sub(obj, draw_alpha); // FIXME + vo_draw_spudec_sub(obj, draw_alpha, ctx); // FIXME break; #ifdef CONFIG_DVDNAV case OSDTYPE_DVDNAV: @@ -1271,7 +1293,7 @@ void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, case OSDTYPE_OSD: case OSDTYPE_SUBTITLE: case OSDTYPE_PROGBAR: - vo_draw_text_from_buffer(obj,draw_alpha); + vo_draw_text_from_buffer(obj, draw_alpha, ctx); break; } obj->old_bbox=obj->bbox; @@ -1282,8 +1304,13 @@ void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, } } -void vo_draw_text(int dxs, int dys, void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) { - vo_draw_text_ext(dxs, dys, 0, 0, 0, 0, dxs, dys, draw_alpha); +void osd_draw_text(struct osd_state *osd, int dxs, int dys, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, + unsigned char* src, unsigned char *srca, + int stride), + void *ctx) +{ + osd_draw_text_ext(osd, dxs, dys, 0, 0, 0, 0, dxs, dys, draw_alpha, ctx); } static int vo_osd_changed_status = 0; diff --git a/libvo/sub.h b/libvo/sub.h index 978b4c940d..d5a30e0b86 100644 --- a/libvo/sub.h +++ b/libvo/sub.h @@ -66,14 +66,16 @@ typedef struct mp_osd_obj_s { unsigned char *bitmap_buffer; } mp_osd_obj_t; +struct osd_state { + unsigned char osd_text[128]; + struct font_desc *sub_font; +}; #include "subreader.h" extern sub_data* subdata; //currently used subtitles extern subtitle* vo_sub; -extern unsigned char* vo_osd_text; - extern void* vo_osd_teletext_page; extern int vo_osd_teletext_half; extern int vo_osd_teletext_mode; @@ -105,8 +107,8 @@ extern void* vo_vobsub; #define OSD_PB_1 0x13 /* now in textform */ -extern char * sub_osd_names[]; -extern char * sub_osd_names_short[]; +extern char * const sub_osd_names[]; +extern char * const sub_osd_names_short[]; extern int sub_unicode; extern int sub_utf8; @@ -122,17 +124,27 @@ extern int spu_alignment; extern int spu_aamode; extern float spu_gaussvar; -void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); -void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, - int right_border, int bottom_border, int orig_w, int orig_h, - void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); -void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h)); - -void vo_init_osd(void); -int vo_update_osd(int dxs,int dys); +void osd_draw_text(struct osd_state *osd, int dxs, int dys, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, + unsigned char* src, unsigned char *srca, + int stride), + void *ctx); +void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys, + int left_border, int top_border, int right_border, + int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, + int h, unsigned char* src, + unsigned char *srca, + int stride), + void *ctx); +void osd_remove_text(struct osd_state *osd, int dxs, int dys, + void (*remove)(int x0, int y0, int w, int h)); + +struct osd_state *osd_create(void); +int osd_update(struct osd_state *osd, int dxs, int dys); int vo_osd_changed(int new_value); int vo_osd_check_range_update(int,int,int,int); -void free_osd_list(void); +void osd_free(struct osd_state *osd); extern int vo_osd_changed_flag; @@ -143,4 +155,9 @@ unsigned utf8_get_char(const char **str); void osd_set_nav_box (uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey); #endif + +#ifdef IS_OLD_VO +#define vo_remove_text(...) osd_remove_text(global_osd, __VA_ARGS__) +#endif + #endif /* MPLAYER_SUB_H */ diff --git a/libvo/vdpau_template.c b/libvo/vdpau_template.c new file mode 100644 index 0000000000..3f9b26c5d8 --- /dev/null +++ b/libvo/vdpau_template.c @@ -0,0 +1,42 @@ + +/* List the VDPAU functions used by MPlayer. + * Generated by vdpau_functions.py. + * First argument on each line is the VDPAU function type name, + * second macro name needed to get function address, + * third name MPlayer uses for the function. + */ + +VDP_FUNCTION(VdpGetErrorString, VDP_FUNC_ID_GET_ERROR_STRING, get_error_string) +VDP_FUNCTION(VdpBitmapSurfaceCreate, VDP_FUNC_ID_BITMAP_SURFACE_CREATE, bitmap_surface_create) +VDP_FUNCTION(VdpBitmapSurfaceDestroy, VDP_FUNC_ID_BITMAP_SURFACE_DESTROY, bitmap_surface_destroy) +VDP_FUNCTION(VdpBitmapSurfacePutBitsNative, VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE, bitmap_surface_put_bits_native) +VDP_FUNCTION(VdpBitmapSurfaceQueryCapabilities, VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES, bitmap_surface_query_capabilities) +VDP_FUNCTION(VdpDecoderCreate, VDP_FUNC_ID_DECODER_CREATE, decoder_create) +VDP_FUNCTION(VdpDecoderDestroy, VDP_FUNC_ID_DECODER_DESTROY, decoder_destroy) +VDP_FUNCTION(VdpDecoderRender, VDP_FUNC_ID_DECODER_RENDER, decoder_render) +VDP_FUNCTION(VdpDeviceDestroy, VDP_FUNC_ID_DEVICE_DESTROY, device_destroy) +VDP_FUNCTION(VdpGenerateCSCMatrix, VDP_FUNC_ID_GENERATE_CSC_MATRIX, generate_csc_matrix) +VDP_FUNCTION(VdpOutputSurfaceCreate, VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, output_surface_create) +VDP_FUNCTION(VdpOutputSurfaceDestroy, VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, output_surface_destroy) +VDP_FUNCTION(VdpOutputSurfacePutBitsIndexed, VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED, output_surface_put_bits_indexed) +VDP_FUNCTION(VdpOutputSurfacePutBitsNative, VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE, output_surface_put_bits_native) +VDP_FUNCTION(VdpOutputSurfaceRenderBitmapSurface, VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE, output_surface_render_bitmap_surface) +VDP_FUNCTION(VdpOutputSurfaceRenderOutputSurface, VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, output_surface_render_output_surface) +VDP_FUNCTION(VdpPreemptionCallbackRegister, VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, preemption_callback_register) +VDP_FUNCTION(VdpPresentationQueueBlockUntilSurfaceIdle, VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, presentation_queue_block_until_surface_idle) +VDP_FUNCTION(VdpPresentationQueueCreate, VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE, presentation_queue_create) +VDP_FUNCTION(VdpPresentationQueueDestroy, VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY, presentation_queue_destroy) +VDP_FUNCTION(VdpPresentationQueueDisplay, VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY, presentation_queue_display) +VDP_FUNCTION(VdpPresentationQueueGetTime, VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME, presentation_queue_get_time) +VDP_FUNCTION(VdpPresentationQueueQuerySurfaceStatus, VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS, presentation_queue_query_surface_status) +VDP_FUNCTION(VdpPresentationQueueTargetCreateX11, VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, presentation_queue_target_create_x11) +VDP_FUNCTION(VdpPresentationQueueTargetDestroy, VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY, presentation_queue_target_destroy) +VDP_FUNCTION(VdpVideoMixerCreate, VDP_FUNC_ID_VIDEO_MIXER_CREATE, video_mixer_create) +VDP_FUNCTION(VdpVideoMixerDestroy, VDP_FUNC_ID_VIDEO_MIXER_DESTROY, video_mixer_destroy) +VDP_FUNCTION(VdpVideoMixerQueryFeatureSupport, VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT, video_mixer_query_feature_support) +VDP_FUNCTION(VdpVideoMixerRender, VDP_FUNC_ID_VIDEO_MIXER_RENDER, video_mixer_render) +VDP_FUNCTION(VdpVideoMixerSetAttributeValues, VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES, video_mixer_set_attribute_values) +VDP_FUNCTION(VdpVideoMixerSetFeatureEnables, VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES, video_mixer_set_feature_enables) +VDP_FUNCTION(VdpVideoSurfaceCreate, VDP_FUNC_ID_VIDEO_SURFACE_CREATE, video_surface_create) +VDP_FUNCTION(VdpVideoSurfaceDestroy, VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, video_surface_destroy) +VDP_FUNCTION(VdpVideoSurfacePutBitsYCbCr, VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, video_surface_put_bits_y_cb_cr) diff --git a/libvo/vesa_lvo.c b/libvo/vesa_lvo.c index a7b1120ceb..27ce03c63b 100644 --- a/libvo/vesa_lvo.c +++ b/libvo/vesa_lvo.c @@ -54,24 +54,24 @@ static uint8_t *lvo_mem = NULL; static uint8_t next_frame; static mga_vid_config_t mga_vid_config; static unsigned image_bpp,image_height,image_width,src_format; -uint32_t vlvo_control(uint32_t request, void *data, ...); +int vlvo_control(uint32_t request, void *data); #define PIXEL_SIZE() ((video_mode_info.BitsPerPixel+7)/8) #define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) ) #define IMAGE_LINE_SIZE(pixel_size) (image_width*(pixel_size)) -extern vo_functions_t video_out_vesa; +extern struct vo_old_functions video_out_vesa; int vlvo_preinit(const char *drvname) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_ThisBranchIsNoLongerSupported); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VESA_LVO] This branch is no longer supported.\n[VESA_LVO] Please use -vo vesa:vidix instead.\n"); return -1; if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_preinit(%s) was called\n",drvname);} lvo_handler = open(drvname,O_RDWR); if(lvo_handler == -1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CouldntOpen,drvname); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VESA_LVO] Couldn't open: '%s'\n",drvname); return -1; } /* we are able to tune up this stuff depend on fourcc format */ @@ -88,7 +88,7 @@ int vlvo_init(unsigned src_width,unsigned src_height, unsigned dst_height,unsigned format,unsigned dest_bpp) { size_t i,awidth; - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_ThisBranchIsNoLongerSupported); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VESA_LVO] This branch is no longer supported.\n[VESA_LVO] Please use -vo vesa:vidix instead.\n"); return -1; if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_init() was called\n");} @@ -127,7 +127,7 @@ int vlvo_init(unsigned src_width,unsigned src_height, mga_vid_config.frame_size = awidth*src_height*4; break; default: - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_InvalidOutputFormat,vo_format_name(format),format); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VESA_LVI] Invalid output format: %s(%0X)\n",vo_format_name(format),format); return -1; } mga_vid_config.colkey_on=0; @@ -141,7 +141,7 @@ int vlvo_init(unsigned src_width,unsigned src_height, if (ioctl(lvo_handler,MGA_VID_CONFIG,&mga_vid_config)) { perror("vesa_lvo: Error in mga_vid_config ioctl()"); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_IncompatibleDriverVersion); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VESA_LVO] Your fb_vid driver version is incompatible with this MPlayer version!\n"); return -1; } ioctl(lvo_handler,MGA_VID_ON,0); @@ -166,7 +166,7 @@ void vlvo_term( void ) if(lvo_handler != -1) close(lvo_handler); } -uint32_t vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) +int vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -206,7 +206,7 @@ uint32_t vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,i return 0; } -uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) +int vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_draw_slice() was called\n");} @@ -224,7 +224,7 @@ uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y return 0; } -uint32_t vlvo_draw_frame(uint8_t *image[]) +int vlvo_draw_frame(uint8_t *image[]) { /* Note it's very strange but sometime for YUY2 draw_frame is called */ fast_memcpy(lvo_mem,image[0],mga_vid_config.frame_size); @@ -314,7 +314,7 @@ uint32_t vlvo_query_info(uint32_t format) return VFCAP_CSP_SUPPORTED; } -uint32_t vlvo_control(uint32_t request, void *data, ...) +int vlvo_control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vesa_lvo.h b/libvo/vesa_lvo.h index 1e7887c8ae..9d77f60045 100644 --- a/libvo/vesa_lvo.h +++ b/libvo/vesa_lvo.h @@ -32,8 +32,8 @@ int vlvo_init(unsigned src_width,unsigned src_height, void vlvo_term( void ); uint32_t vlvo_query_info(uint32_t format); -uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y); -uint32_t vlvo_draw_frame(uint8_t *src[]); +int vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y); +int vlvo_draw_frame(uint8_t *src[]); void vlvo_flip_page(void); void vlvo_draw_osd(void); diff --git a/libvo/video_out.c b/libvo/video_out.c index ec4cd9c109..e2d42f4900 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,58 +78,58 @@ 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_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_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, @@ -282,79 +273,197 @@ 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) +{ + if (!vo->config_ok) + return; + 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; } /** @@ -399,8 +508,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; @@ -409,25 +520,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; @@ -519,4 +630,3 @@ out_err: /* Borrowed from vo_fbdev.c END */ #endif - diff --git a/libvo/video_out.h b/libvo/video_out.h index b143ff5554..7211d69e65 100644 --- a/libvo/video_out.h +++ b/libvo/video_out.h @@ -24,12 +24,14 @@ #define MPLAYER_VIDEO_OUT_H #include <inttypes.h> -#include <stdarg.h> +#include <stdbool.h> //#include "font_load.h" #include "libmpcodecs/img_format.h" //#include "vidix/vidix.h" +#define MP_NOPTS_VALUE (-1LL<<63) + #define VO_EVENT_EXPOSE 1 #define VO_EVENT_RESIZE 2 #define VO_EVENT_KEYPRESS 4 @@ -39,9 +41,6 @@ #define VOCTRL_QUERY_FORMAT 2 /* signal a device reset seek */ #define VOCTRL_RESET 3 -/* true if vo driver can use GUI created windows */ -#define VOCTRL_GUISUPPORT 4 -#define VOCTRL_GUI_NOWINDOW 19 /* used to switch to fullscreen */ #define VOCTRL_FULLSCREEN 5 /* signal a device pause */ @@ -60,8 +59,15 @@ #define VOCTRL_SET_PANSCAN 16 /* equalizer controls */ #define VOCTRL_SET_EQUALIZER 17 +struct voctrl_set_equalizer_args { + const char *name; + int value; +}; #define VOCTRL_GET_EQUALIZER 18 -//#define VOCTRL_GUI_NOWINDOW 19 +struct voctrl_get_equalizer_args { + const char *name; + int *valueptr; +}; /* Frame duplication */ #define VOCTRL_DUPLICATE_FRAME 20 // ... 21 @@ -82,6 +88,9 @@ typedef struct { #define VOCTRL_UPDATE_SCREENINFO 32 +#define VOCTRL_SET_YUV_COLORSPACE 33 +#define VOCTRL_GET_YUV_COLORSPACE 34 + // Vo can be used by xover #define VOCTRL_XOVERLAY_SUPPORT 22 @@ -92,6 +101,8 @@ typedef struct { } mp_colorkey_t; #define VOCTRL_XOVERLAY_SET_WIN 23 +#define VOCTRL_REDRAW_OSD 24 + typedef struct { int x,y; int w,h; @@ -111,113 +122,178 @@ typedef struct { typedef struct vo_info_s { - /* driver name ("Matrox Millennium G200/G400" */ - const char *name; - /* short name (for config strings) ("mga") */ - const char *short_name; - /* author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */ - const char *author; - /* any additional comments */ - const char *comment; + /* driver name ("Matrox Millennium G200/G400" */ + const char *name; + /* short name (for config strings) ("mga") */ + const char *short_name; + /* author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */ + const char *author; + /* any additional comments */ + const char *comment; } vo_info_t; -typedef struct vo_functions_s -{ - const 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; - -const vo_functions_t* init_best_video_out(char** vo_list); -int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height, +struct vo; +struct osd_state; +struct mp_image; + +struct vo_driver { + // Driver uses new API + bool is_new; + // Driver buffers or adds (deinterlace) frames and will keep track + // of pts values itself + bool buffer_frames; + + // This is set if the driver is not new and contains pointers to + // old-API functions to be used instead of the ones below. + struct vo_old_functions *old_functions; + + const 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)(struct vo *vo, 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)(struct vo *vo, 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)(struct vo *vo, uint32_t request, void *data); + + void (*draw_image)(struct vo *vo, struct mp_image *mpi, double pts); + + /* + * Get extra frames from the VO, such as those added by VDPAU + * deinterlace. Preparing the next such frame if any could be done + * automatically by the VO after a previous flip_page(), but having + * it as a separate step seems to allow making code more robust. + */ + void (*get_buffered_frame)(struct vo *vo, bool eof); + + /* + * 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)(struct vo *vo, uint8_t *src[], int stride[], int w, + int h, int x, int y); + + /* + * Draws OSD to the screen buffer + */ + void (*draw_osd)(struct vo *vo, struct osd_state *osd); + + /* + * Blit/Flip buffer to the screen. Must be called after each frame! + */ + void (*flip_page)(struct vo *vo); + void (*flip_page_timed)(struct vo *vo, unsigned int pts_us, int duration); + + /* + * This func is called after every frames to handle keyboard and + * other events. It's called in PAUSE mode too! + */ + void (*check_events)(struct vo *vo); + + /* + * Closes driver. Should restore the original state of the system. + */ + void (*uninit)(struct vo *vo); +}; + +struct vo_old_functions { + int (*preinit)(const char *arg); + int (*config)(uint32_t width, uint32_t height, uint32_t d_width, + uint32_t d_height, uint32_t fullscreen, char *title, + uint32_t format); + int (*control)(uint32_t request, void *data); + int (*draw_frame)(uint8_t *src[]); + int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y); + void (*draw_osd)(void); + void (*flip_page)(void); + void (*check_events)(void); + void (*uninit)(void); +}; + +struct vo { + int config_ok; // Last config call was successful? + int config_count; // Total number of successful config calls + + bool frame_loaded; // Is there a next frame the VO could flip to? + double next_pts; // pts value of the next frame if any + double next_pts2; // optional pts of frame after that + + const struct vo_driver *driver; + void *priv; + struct MPOpts *opts; + struct vo_x11_state *x11; + struct mp_fifo *key_fifo; + struct input_ctx *input_ctx; + + // requested position/resolution + int dx; + int dy; + int dwidth; + int dheight; + + int panscan_x; + int panscan_y; + float panscan_amount; + float monitor_aspect; + struct aspect_data { + int orgw; // real width + int orgh; // real height + int prew; // prescaled width + int preh; // prescaled height + int scrw; // horizontal resolution + int scrh; // vertical resolution + float asp; + } aspdat; +}; + +struct vo *init_best_video_out(struct MPOpts *opts, struct vo_x11_state *x11, + struct mp_fifo *key_fifo, + struct input_ctx *input_ctx); +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); void list_video_out(void); -// NULL terminated array of all drivers -extern const vo_functions_t* const video_out_drivers[]; +int vo_control(struct vo *vo, uint32_t request, void *data); +int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts); +int vo_get_buffered_frame(struct vo *vo, bool eof); +int vo_draw_frame(struct vo *vo, uint8_t *src[]); +int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y); +void vo_draw_osd(struct vo *vo, struct osd_state *osd); +void vo_flip_page(struct vo *vo, unsigned int pts_us, int duration); +void vo_check_events(struct vo *vo); +void vo_seek_reset(struct vo *vo); +void vo_destroy(struct vo *vo); -extern int vo_flags; -extern int vo_config_count; +// NULL terminated array of all drivers +extern const struct vo_driver *video_out_drivers[]; extern int xinerama_screen; extern int xinerama_x; extern int xinerama_y; -// correct resolution/bpp on screen: (should be autodetected by vo_init()) -extern int vo_depthonscreen; -extern int vo_screenwidth; -extern int vo_screenheight; - -// requested resolution/bpp: (-x -y -bpp options) -extern int vo_dx; -extern int vo_dy; -extern int vo_dwidth; -extern int vo_dheight; -extern int vo_dbpp; - extern int vo_grabpointer; extern int vo_doublebuffering; extern int vo_directrendering; @@ -229,18 +305,8 @@ extern int vo_adapter_num; extern int vo_refresh_rate; extern int vo_keepaspect; extern int vo_rootwin; -extern int vo_ontop; extern int vo_border; -extern int vo_gamma_gamma; -extern int vo_gamma_brightness; -extern int vo_gamma_saturation; -extern int vo_gamma_contrast; -extern int vo_gamma_hue; -extern int vo_gamma_red_intensity; -extern int vo_gamma_green_intensity; -extern int vo_gamma_blue_intensity; - extern int vo_nomouse_input; extern int vo_pts; @@ -275,7 +341,8 @@ int lookup_keymap_table(const struct keymap *map, int key); struct vo_rect { int left, right, top, bottom, width, height; }; -void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, +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 inline int aspect_scaling(void) diff --git a/libvo/video_out_internal.h b/libvo/video_out_internal.h index 36aa210fdd..8595d4ef05 100644 --- a/libvo/video_out_internal.h +++ b/libvo/video_out_internal.h @@ -27,8 +27,10 @@ #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" #include "geometry.h" +#include "old_vo_wrapper.h" +#include "old_vo_defines.h" -static int control(uint32_t request, void *data, ...); +static int control(uint32_t request, void *data); static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format); @@ -41,9 +43,19 @@ static void uninit(void); static int query_format(uint32_t format); static int preinit(const char *); -#define LIBVO_EXTERN(x) vo_functions_t video_out_##x =\ +#define LIBVO_EXTERN(x) struct vo_driver video_out_##x =\ {\ - &info,\ + .is_new = 0,\ + .info = &info,\ + .preinit = old_vo_preinit,\ + .config = old_vo_config,\ + .control = old_vo_control,\ + .draw_slice = old_vo_draw_slice,\ + .draw_osd = old_vo_draw_osd,\ + .flip_page = old_vo_flip_page,\ + .check_events = old_vo_check_events,\ + .uninit = old_vo_uninit,\ + .old_functions = &(struct vo_old_functions){\ preinit,\ config,\ control,\ @@ -52,7 +64,8 @@ static int preinit(const char *); draw_osd,\ flip_page,\ check_events,\ - uninit\ + uninit,\ + }\ }; #include "osd.h" diff --git a/libvo/vo_3dfx.c b/libvo/vo_3dfx.c index b86e593281..9295a65a67 100644 --- a/libvo/vo_3dfx.c +++ b/libvo/vo_3dfx.c @@ -169,12 +169,12 @@ create_window(Display *display, char *title) bpp = attribs.depth; if (bpp != 16) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_3DFX_Only16BppSupported); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_3DFX] Only 16bpp supported!"); exit(-1); } XMatchVisualInfo(display,screen,bpp,TrueColor,&vinfo); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_3DFX_VisualIdIs,vinfo.visualid); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_3DFX] Visual ID is %lx.\n",vinfo.visualid); theCmap = XCreateColormap(display, RootWindow(display,screen), vinfo.visual, AllocNone); @@ -335,7 +335,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin // Open driver device if ( fd == -1 ) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_3DFX_UnableToOpenDevice); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_3DFX] Unable to open /dev/3dfx.\n"); return -1; } @@ -354,7 +354,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin data.device = 0; if ((retval = ioctl(fd,_IOC(_IOC_READ,'3',3,0),&data)) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_3DFX_Error,retval); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_3DFX] Error: %d.\n",retval); return -1; } @@ -365,7 +365,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin data.device = 0; if ((retval = ioctl(fd,_IOC(_IOC_READ,'3',3,0),&data)) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_3DFX_Error,retval); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_3DFX] Error: %d.\n",retval); return -1; } @@ -374,7 +374,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin memBase1 = mmap(0,3*page_space,PROT_READ | PROT_WRITE,MAP_SHARED,fd,baseAddr1); if (memBase0 == (uint32_t *) 0xFFFFFFFF || memBase1 == (uint32_t *) 0xFFFFFFFF) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_3DFX_CouldntMapMemoryArea, + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_3DFX] Couldn't map 3dfx memory areas: %p,%p,%d.\n", memBase0,memBase1,errno); } @@ -413,7 +413,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin atexit(restore); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_3DFX_DisplayInitialized,memBase1); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_3DFX] Initialized: %p.\n",memBase1); return 0; } @@ -485,19 +485,19 @@ static int preinit(const char *arg) { if ( (fd = open("/dev/3dfx",O_RDWR) ) == -1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_3DFX_UnableToOpenDevice); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_3DFX] Unable to open /dev/3dfx.\n"); return -1; } if(arg) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_3DFX_UnknownSubdevice,arg); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_3DFX] Unknown subdevice: %s.\n",arg); return ENOSYS; } return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_aa.c b/libvo/vo_aa.c index 41d5de6294..5e9dfbae10 100644 --- a/libvo/vo_aa.c +++ b/libvo/vo_aa.c @@ -96,7 +96,9 @@ static struct SwsContext *sws=NULL; int aaopt_osdcolor = AA_SPECIAL; int aaopt_subcolor = AA_SPECIAL; -void +static unsigned char vo_osd_text[64]; + +static void resize(void){ /* * this function is called by aa lib if windows resizes @@ -190,15 +192,10 @@ osdpercent(int duration, int deko, int min, int max, int val, const char * desc, static void printosdtext(void) { - if(osd_text_length > 0 && !vo_osd_text) { - memset(c->textbuffer,' ',osd_text_length); - memset(c->attrbuffer,0,osd_text_length); - osd_text_length = 0; - } /* * places the mplayer status osd */ - if (vo_osd_text && vo_osd_text[0] != 0) { + if (vo_osd_text[0] != 0) { int len; if(vo_osd_text[0] < 32) { len = strlen(sub_osd_names_short[vo_osd_text[0]]) + strlen(vo_osd_text+1) + 2; @@ -542,18 +539,18 @@ static void clear_alpha(int x0,int y0, int w,int h) { static void draw_osd(void){ - char * vo_osd_text_save; + char vo_osd_text_save; int vo_osd_progbar_type_save; printosdprogbar(); /* let vo_draw_text only write subtitle */ - vo_osd_text_save=vo_osd_text; /* we have to save the osd_text */ - vo_osd_text=NULL; + vo_osd_text_save = global_osd->osd_text[0]; + global_osd->osd_text[0] = 0; vo_osd_progbar_type_save=vo_osd_progbar_type; vo_osd_progbar_type=-1; vo_remove_text(aa_scrwidth(c), aa_scrheight(c),clear_alpha); vo_draw_text(aa_scrwidth(c), aa_scrheight(c), draw_alpha); - vo_osd_text=vo_osd_text_save; + global_osd->osd_text[0] = vo_osd_text_save; vo_osd_progbar_type=vo_osd_progbar_type_save; } @@ -620,9 +617,16 @@ static int parse_suboptions(const char *arg) { helpmsg = strdup(aa_help); for (i=0; i<(signed)strlen(helpmsg); i++) if (helpmsg[i] == '-') helpmsg[i] = ' '; - mp_msg(MSGT_VO, MSGL_INFO, MSGTR_VO_AA_HelpHeader); + mp_tmsg(MSGT_VO, MSGL_INFO, "\n\nHere are the aalib vo_aa suboptions:\n"); mp_msg(MSGT_VO, MSGL_INFO, "%s\n\n", helpmsg); - mp_msg(MSGT_VO, MSGL_INFO, MSGTR_VO_AA_AdditionalOptions); +#define VO_AA_AdditionalOptions _("Additional options vo_aa provides:\n" \ +" help print this help message\n" \ +" osdcolor set OSD color\n subcolor set subtitle color\n" \ +" the color parameters are:\n 0 : normal\n" \ +" 1 : dim\n 2 : bold\n 3 : boldfont\n" \ +" 4 : reverse\n 5 : special\n\n\n") + + mp_tmsg(MSGT_VO, MSGL_INFO, VO_AA_AdditionalOptions); retval = -1; } if (retval == 0) { @@ -726,37 +730,26 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_SET_EQUALIZER: { - va_list ap; - int val; - - va_start(ap, data); - val = va_arg(ap, int); - va_end(ap); - - if(strcmp((char*)data,"contrast") == 0) - p->contrast = ( val + 100 ) * 64 / 100; - else if(strcmp((char*)data,"brightness") == 0) - p->bright = ( val + 100) * 128 / 100; + struct voctrl_set_equalizer_args *args = data; + if (strcmp(args->name, "contrast") == 0) + p->contrast = (args->value + 100) * 64 / 100; + else if (strcmp(args->name, "brightness") == 0) + p->bright = (args->value + 100) * 128 / 100; return VO_TRUE; } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int* val; - - va_start(ap, data); - val = va_arg(ap, int*); - va_end(ap); + struct voctrl_get_equalizer_args *args = data; - if(strcmp((char*)data,"contrast") == 0) - *val = (p->contrast - 64) * 100 / 64; - else if(strcmp((char*)data,"brightness") == 0) - *val = (p->bright - 128) * 100 / 128; + if (strcmp(args->name, "contrast") == 0) + *args->valueptr = (p->contrast - 64) * 100 / 64; + else if (strcmp(args->name, "brightness") == 0) + *args->valueptr = (p->bright - 128) * 100 / 128; return VO_TRUE; } diff --git a/libvo/vo_bl.c b/libvo/vo_bl.c index 9e98130adb..8a4c29edd7 100644 --- a/libvo/vo_bl.c +++ b/libvo/vo_bl.c @@ -470,7 +470,7 @@ static int preinit(const char *arg) { return 0; } -static int control(uint32_t request, void *data, ...) { +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); diff --git a/libvo/vo_caca.c b/libvo/vo_caca.c index 4415459080..2c36700be8 100644 --- a/libvo/vo_caca.c +++ b/libvo/vo_caca.c @@ -335,7 +335,7 @@ static int query_format(uint32_t format) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch(request) { diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m index e4b5e85545..1748e059ec 100644 --- a/libvo/vo_corevideo.m +++ b/libvo/vo_corevideo.m @@ -414,7 +414,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { @@ -956,7 +956,7 @@ static int control(uint32_t request, void *data, ...) snprintf(cmdstr, sizeof(cmdstr), "set_mouse_pos %i %i", (int)(vo_fs ? p.x : (p.x - textureFrame.origin.x)), (int)(vo_fs ? [self frame].size.height - p.y: (NSMaxY(textureFrame) - p.y))); - mp_input_queue_cmd(mp_input_parse_cmd(cmdstr)); + mp_input_queue_cmd(global_vo->input_ctx, mp_input_parse_cmd(cmdstr)); } } } diff --git a/libvo/vo_cvidix.c b/libvo/vo_cvidix.c index 70ea155535..a4a29719de 100644 --- a/libvo/vo_cvidix.c +++ b/libvo/vo_cvidix.c @@ -171,11 +171,11 @@ static int preinit(const char *arg){ mp_msg(MSGT_VO, MSGL_INFO, "vo_cvidix: No vidix driver name provided, probing available ones (-v option for details)!\n"); vidix_name = NULL; } - if(vidix_preinit(vidix_name, &video_out_cvidix))return 1; + if (vidix_preinit(vidix_name, video_out_cvidix.old_functions))return 1; return 0; } -static int control(uint32_t request, void *data, ...){ +static int control(uint32_t request, void *data){ switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); @@ -184,24 +184,6 @@ static int control(uint32_t request, void *data, ...){ else vo_fs=1; setup_vidix(); return VO_TRUE; - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - return vidix_control(request, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - va_start(ap, data); - value = va_arg(ap, int *); - va_end(ap); - return vidix_control(request, data, value); - } } return vidix_control(request, data); } diff --git a/libvo/vo_dfbmga.c b/libvo/vo_dfbmga.c index fd1a3638db..457a481c7a 100644 --- a/libvo/vo_dfbmga.c +++ b/libvo/vo_dfbmga.c @@ -1465,13 +1465,9 @@ get_equalizer( char *data, int *value ) } static int -control( uint32_t request, void *data, ... ) +control( uint32_t request, void *data) { switch (request) { - case VOCTRL_GUISUPPORT: - case VOCTRL_GUI_NOWINDOW: - return VO_TRUE; - case VOCTRL_QUERY_FORMAT: return query_format( *((uint32_t *) data) ); @@ -1483,25 +1479,13 @@ control( uint32_t request, void *data, ... ) case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start( ap, data ); - value = va_arg( ap, int ); - va_end( ap ); - - return set_equalizer( data, value ); + struct voctrl_set_equalizer_args *args = data; + return set_equalizer(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start( ap, data ); - value = va_arg( ap, int* ); - va_end( ap ); - - return get_equalizer( data, value ); + struct voctrl_get_equalizer_args *args = data; + return get_equalizer(args->name, args->valueptr); } } diff --git a/libvo/vo_dga.c b/libvo/vo_dga.c index 51527bdc6a..879831761d 100644 --- a/libvo/vo_dga.c +++ b/libvo/vo_dga.c @@ -984,7 +984,7 @@ static uint32_t get_image(mp_image_t * mpi) return VO_FALSE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c index bfeb82e562..7094af8823 100644 --- a/libvo/vo_direct3d.c +++ b/libvo/vo_direct3d.c @@ -740,7 +740,7 @@ static int preinit(const char *arg) /** @brief libvo Callback: Handle control requests. * @return VO_TRUE on success, VO_NOTIMPL when not implemented */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -763,8 +763,6 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_RESUME: priv->is_paused = 0; return VO_TRUE; - case VOCTRL_GUISUPPORT: - return VO_NOTIMPL; case VOCTRL_SET_EQUALIZER: return VO_NOTIMPL; case VOCTRL_GET_EQUALIZER: diff --git a/libvo/vo_directfb2.c b/libvo/vo_directfb2.c index d2e17593b2..a502647a6d 100644 --- a/libvo/vo_directfb2.c +++ b/libvo/vo_directfb2.c @@ -1412,7 +1412,7 @@ static uint32_t put_image(mp_image_t *mpi){ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -1423,25 +1423,13 @@ static int control(uint32_t request, void *data, ...) return put_image(data); case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return directfb_set_video_eq(data, value); + struct voctrl_set_equalizer_args *args = data; + return directfb_set_video_eq(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return directfb_get_video_eq(data, value); + struct voctrl_get_equalizer_args *args = data; + return directfb_get_video_eq(args->name, args->valueptr); } }; return VO_NOTIMPL; diff --git a/libvo/vo_directx.c b/libvo/vo_directx.c index 9aa27de2cc..a51a4314e5 100644 --- a/libvo/vo_directx.c +++ b/libvo/vo_directx.c @@ -39,10 +39,6 @@ #include "mp_fifo.h" #include "sub.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif - #ifndef WM_XBUTTONDOWN # define WM_XBUTTONDOWN 0x020B # define WM_XBUTTONUP 0x020C @@ -90,8 +86,6 @@ static float window_aspect; static BOOL (WINAPI* myGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL; static RECT last_rect = {0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE}; -extern int vidmode; - /***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during @@ -1294,11 +1288,6 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin if(format != primary_image_format)nooverlay = 0; window_aspect= (float)d_image_width / (float)d_image_height; -#ifdef CONFIG_GUI - if(use_gui){ - guiGetEvent(guiSetShVideo, 0); - } -#endif /*release all directx objects*/ if (g_cc != NULL)g_cc->lpVtbl->Release(g_cc); g_cc=NULL; @@ -1474,7 +1463,7 @@ static uint32_t color_ctrl_get(char *what, int *value) return r; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { @@ -1566,22 +1555,12 @@ static int control(uint32_t request, void *data, ...) return VO_TRUE; } case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - return color_ctrl_set(data, value); + struct voctrl_set_equalizer_args *args = data; + return color_ctrl_set(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - return color_ctrl_get(data, value); + struct voctrl_get_equalizer_args *args = data; + return color_ctrl_get(args->name, args->valueptr); } case VOCTRL_UPDATE_SCREENINFO: if (vidmode) { diff --git a/libvo/vo_dxr2.c b/libvo/vo_dxr2.c index 0e1ac2fc35..66f73f1d6d 100644 --- a/libvo/vo_dxr2.c +++ b/libvo/vo_dxr2.c @@ -42,8 +42,7 @@ #include <dxr2ioctl.h> -extern float monitor_aspect; -extern float movie_aspect; +#include "aspect.h" int dxr2_fd = -1; @@ -51,7 +50,8 @@ static int movie_w,movie_h; static int playing = 0; // vo device used to blank the screen for the overlay init -static const vo_functions_t* sub_vo = NULL; +static const struct vo_old_functions *sub_vo = NULL; +static const struct vo_info_s *sub_info; static uint8_t* sub_img = NULL; static int sub_x,sub_y,sub_w,sub_h; @@ -446,7 +446,7 @@ static int dxr2_load_vga_params(dxr2_vgaParams_t* vga,char* name) { } static int dxr2_setup_vga_params(void) { - const vo_info_t* vi = sub_vo->info; + const vo_info_t* vi = sub_info; dxr2_vgaParams_t vga; int loaded = dxr2_load_vga_params(&vga,(char*)vi->short_name); @@ -660,7 +660,7 @@ static int config(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t } // Does the sub vo support the x11 stuff // Fix me : test the other x11 vo's and enable them - if(strcmp(sub_vo->info->short_name,"x11") == 0) + if(strcmp(sub_info->short_name,"x11") == 0) sub_vo_win = 1; else sub_vo_win = 0; @@ -834,10 +834,11 @@ static int preinit(const char *arg) { const vo_info_t* vi = video_out_drivers[n]->info; if(!vi) continue; - if(strcasecmp(arg,vi->short_name) == 0) + if(!video_out_drivers[n]->is_new && strcasecmp(arg,vi->short_name) == 0) break; } - sub_vo = video_out_drivers[n]; + sub_vo = video_out_drivers[n]->old_functions; + sub_info = video_out_drivers[n]->info; } else { mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] We need a sub driver to initialize the overlay\n"); use_ol = 0; @@ -920,7 +921,7 @@ static int preinit(const char *arg) { return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_dxr3.c b/libvo/vo_dxr3.c index 05f55aa4f9..898ee96756 100644 --- a/libvo/vo_dxr3.c +++ b/libvo/vo_dxr3.c @@ -44,9 +44,6 @@ #include "aspect.h" #include "spuenc.h" #include "sub.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif #ifdef CONFIG_X11 #include "x11_common.h" #endif @@ -174,19 +171,12 @@ static overlay_t *overlay_data; /* Functions for working with the em8300's internal clock */ /* End of internal clock functions */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { - case VOCTRL_GUISUPPORT: - return VO_TRUE; - case VOCTRL_GUI_NOWINDOW: - if (dxr3_overlay) { - return VO_FALSE; - } - return VO_TRUE; case VOCTRL_SET_SPU_PALETTE: if (ioctl(fd_spu, EM8300_IOCTL_SPU_SETPALETTE, data) < 0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_UnableToLoadNewSPUPalette); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to load new SPU palette!\n"); return VO_ERROR; } return VO_TRUE; @@ -216,7 +206,7 @@ static int control(uint32_t request, void *data, ...) if (dxr3_prebuf) { ioval = EM8300_PLAYMODE_PLAY; if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetPlaymode); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set playmode!\n"); } } return VO_TRUE; @@ -224,7 +214,7 @@ static int control(uint32_t request, void *data, ...) if (dxr3_prebuf) { ioval = EM8300_PLAYMODE_PAUSED; if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetPlaymode); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set playmode!\n"); } } return VO_TRUE; @@ -252,22 +242,17 @@ static int control(uint32_t request, void *data, ...) } case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; em8300_bcs_t bcs; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); + struct voctrl_set_equalizer_args *args = data; if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0) return VO_FALSE; - if (!strcasecmp(data, "brightness")) - bcs.brightness = (value+100)*5; - else if (!strcasecmp(data, "contrast")) - bcs.contrast = (value+100)*5; - else if (!strcasecmp(data, "saturation")) - bcs.saturation = (value+100)*5; + if (!strcasecmp(args->name, "brightness")) + bcs.brightness = (args->value+100)*5; + else if (!strcasecmp(args->name, "contrast")) + bcs.contrast = (args->value+100)*5; + else if (!strcasecmp(args->name, "saturation")) + bcs.saturation = (args->value+100)*5; else return VO_FALSE; if (ioctl(fd_control, EM8300_IOCTL_SETBCS, &bcs) < 0) @@ -276,23 +261,18 @@ static int control(uint32_t request, void *data, ...) } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; em8300_bcs_t bcs; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); + struct voctrl_get_equalizer_args *args = data; if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0) return VO_FALSE; - if (!strcasecmp(data, "brightness")) - *value = (bcs.brightness/5)-100; - else if (!strcasecmp(data, "contrast")) - *value = (bcs.contrast/5)-100; - else if (!strcasecmp(data, "saturation")) - *value = (bcs.saturation/5)-100; + if (!strcasecmp(args->name, "brightness")) + *args->valueptr = (bcs.brightness/5)-100; + else if (!strcasecmp(args->name, "contrast")) + *args->valueptr = (bcs.contrast/5)-100; + else if (!strcasecmp(args->name, "saturation")) + *args->valueptr = (bcs.saturation/5)-100; else return VO_FALSE; return VO_TRUE; @@ -322,7 +302,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ { int tmp1, tmp2, size; em8300_register_t reg; - extern float monitor_aspect; /* Softzoom turned on, downscale */ /* This activates the subpicture processor, you can safely disable this and still send */ @@ -330,7 +309,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ /* up in a lockup */ ioval = EM8300_SPUMODE_ON; if (ioctl(fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetSubpictureMode); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set subpicture mode!\n"); uninit(); return -1; } @@ -338,7 +317,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ /* Set the playmode to play (just in case another app has set it to something else) */ ioval = EM8300_PLAYMODE_PLAY; if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetPlaymode); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set playmode!\n"); } /* Start em8300 prebuffering and sync engine */ @@ -370,7 +349,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ monitor_aspect = (float) width / (float) height; if (ioctl(fd_control, EM8300_IOCTL_GET_VIDEOMODE, &old_vmode) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToGetTVNorm); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to get TV norm!\n"); old_vmode = -1; } @@ -389,7 +368,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ ioval = EM8300_VIDEOMODE_PAL; } - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_AutoSelectedTVNormByFrameRate); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Auto-selected TV norm by framerate: "); ioval == EM8300_VIDEOMODE_PAL60 ? mp_msg(MSGT_VO,MSGL_INFO, "PAL-60") : mp_msg(MSGT_VO,MSGL_INFO, "PAL"); printf(".\n"); } else { @@ -399,14 +378,14 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ ioval = EM8300_VIDEOMODE_PAL; } - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_AutoSelectedTVNormByFrameRate); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Auto-selected TV norm by framerate: "); ioval == EM8300_VIDEOMODE_NTSC ? mp_msg(MSGT_VO,MSGL_INFO, "NTSC") : mp_msg(MSGT_VO,MSGL_INFO, "PAL"); printf(".\n"); } if (old_vmode != ioval) { if (ioctl(fd_control, EM8300_IOCTL_SET_VIDEOMODE, &ioval) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetTVNorm); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set TV norm!\n"); } } } @@ -417,10 +396,10 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ aspect_save_prescale(d_width, d_height); ioctl(fd_control, EM8300_IOCTL_GET_VIDEOMODE, &ioval); if (ioval == EM8300_VIDEOMODE_NTSC) { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_SettingUpForNTSC); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting up for NTSC.\n"); aspect_save_screenres(352, 240); } else { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_SettingUpForPALSECAM); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting up for PAL/SECAM.\n"); aspect_save_screenres(352, 288); } aspect(&s_width, &s_height, A_ZOOM); @@ -433,10 +412,10 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ tmp2 = abs(d_height - (int) (d_width / 2.35)); if (tmp1 < tmp2) { ioval = EM8300_ASPECTRATIO_4_3; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_SettingAspectRatioTo43); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting aspect ratio to 4:3.\n"); } else { ioval = EM8300_ASPECTRATIO_16_9; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_SettingAspectRatioTo169); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting aspect ratio to 16:9.\n"); } ioctl(fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &ioval); @@ -455,20 +434,20 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ osdpicbuf = calloc( 1,s_width * s_height); if (osdpicbuf == NULL) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_OutOfMemory); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] out of memory\n"); return -1; } spued = (encodedata *) malloc(sizeof(encodedata)); if (spued == NULL) { free( osdpicbuf ); - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_OutOfMemory); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] out of memory\n"); return -1; } spubuf = (encodedata *) malloc(sizeof(encodedata)); if (spubuf == NULL) { free( osdpicbuf ); free( spued ); - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_OutOfMemory); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] out of memory\n"); return -1; } osd_w = s_width; @@ -499,19 +478,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ vo_dy = (vo_screenheight - d_height) / 2; vo_dwidth = d_width; vo_dheight = d_height; -#ifdef CONFIG_GUI - if (use_gui) { - guiGetEvent(guiSetShVideo, 0); - XSetWindowBackground(mDisplay, vo_window, KEY_COLOR); - XClearWindow(mDisplay, vo_window); - XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &xwin_attribs); - depth = xwin_attribs.depth; - if (depth != 15 && depth != 16 && depth != 24 && depth != 32) { - depth = 24; - } - XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); - } else -#endif { XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &xwin_attribs); depth = xwin_attribs.depth; @@ -547,13 +513,13 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ ((key_color.blue >> (16 - blue_prec)) << blue_shift)); key_color.flags = DoRed | DoGreen | DoBlue; if (!XAllocColor(mDisplay, cmap, &key_color)) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_UnableToAllocateKeycolor); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to allocate keycolor!\n"); return -1; } acq_color = ((key_color.red / 256) << 16) | ((key_color.green / 256) << 8) | key_color.blue; if (key_color.pixel != KEY_COLOR) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToAllocateExactKeycolor, key_color.pixel); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to allocate exact keycolor, using closest match (0x%lx).\n", key_color.pixel); } /* Set keycolor and activate overlay */ @@ -707,25 +673,19 @@ static int draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int static void uninit(void) { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_Uninitializing); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Uninitializing.\n"); #ifdef CONFIG_X11 if (dxr3_overlay) { overlay_set_mode(overlay_data, EM8300_OVERLAY_MODE_OFF); overlay_release(overlay_data); -#ifdef CONFIG_GUI - if (!use_gui) { -#endif vo_x11_uninit(); -#ifdef CONFIG_GUI - } -#endif } #endif if (old_vmode != -1) { if (ioctl(fd_control, EM8300_IOCTL_SET_VIDEOMODE, &old_vmode) < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedRestoringTVNorm); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed restoring TV norm!\n"); } } @@ -760,24 +720,24 @@ static int preinit(const char *arg) /* Parse commandline */ while (arg) { if (!strncmp("prebuf", arg, 6) && !dxr3_prebuf) { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_EnablingPrebuffering); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Enabling prebuffering.\n"); dxr3_prebuf = 1; } else if (!strncmp("sync", arg, 4) && !dxr3_newsync) { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_UsingNewSyncEngine); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Using new sync engine.\n"); dxr3_newsync = 1; } else if (!strncmp("overlay", arg, 7) && !dxr3_overlay) { #ifdef CONFIG_X11 - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_UsingOverlay); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Using overlay.\n"); dxr3_overlay = 1; #else - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_ErrorYouNeedToCompileMplayerWithX11); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error: Overlay requires compiling with X11 libs/headers installed.\n"); #endif } else if (!strncmp("norm=", arg, 5)) { arg += 5; // dxr3_norm is 0 (-> don't change norm) by default // but maybe someone changes this in the future - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_WillSetTVNormTo); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Will set TV norm to: "); if (*arg == '5') { dxr3_norm = 5; @@ -790,16 +750,16 @@ static int preinit(const char *arg) mp_msg(MSGT_VO,MSGL_INFO, "PAL"); } else if (*arg == '2') { dxr3_norm = 2; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_AutoAdjustToMovieFrameRatePALPAL60); + mp_tmsg(MSGT_VO,MSGL_INFO, "auto-adjust to movie framerate (PAL/PAL-60)"); } else if (*arg == '1') { dxr3_norm = 1; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_AutoAdjustToMovieFrameRatePALNTSC); + mp_tmsg(MSGT_VO,MSGL_INFO, "auto-adjust to movie framerate (PAL/NTSC)"); } else if (*arg == '0') { dxr3_norm = 0; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_UseCurrentNorm); + mp_tmsg(MSGT_VO,MSGL_INFO, "Use current norm."); } else { dxr3_norm = 0; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_UseUnknownNormSuppliedCurrentNorm); + mp_tmsg(MSGT_VO,MSGL_INFO, "Unknown norm supplied. Use current norm."); } mp_msg(MSGT_VO,MSGL_INFO, ".\n"); @@ -819,15 +779,15 @@ static int preinit(const char *arg) fd_control = open(devname, fdflags); if (fd_control < 1) { /* Fall back to old naming scheme */ - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_ErrorOpeningForWritingTrying, devname); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error opening %s for writing, trying /dev/em8300 instead.\n", devname); sprintf(devname, "/dev/em8300"); fd_control = open(devname, fdflags); if (fd_control < 1) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_ErrorOpeningForWritingAsWell); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Error opening /dev/em8300 for writing as well!\nBailing out.\n"); return -1; } } else { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_Opened, devname); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Opened: %s.\n", devname); } /* Open the video interface */ @@ -835,16 +795,16 @@ static int preinit(const char *arg) fd_video = open(devname, fdflags); if (fd_video < 0) { /* Fall back to old naming scheme */ - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_ErrorOpeningForWritingTryingMV, devname); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error opening %s for writing, trying /dev/em8300_mv instead.\n", devname); sprintf(devname, "/dev/em8300_mv"); fd_video = open(devname, fdflags); if (fd_video < 0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_ErrorOpeningForWritingAsWellMV); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Error opening /dev/em8300_mv for writing as well!\nBailing out.\n"); uninit(); return -1; } } else { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_Opened, devname); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Opened: %s.\n", devname); } strcpy(fdv_name, devname); @@ -853,16 +813,16 @@ static int preinit(const char *arg) fd_spu = open(devname, fdflags); if (fd_spu < 0) { /* Fall back to old naming scheme */ - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_ErrorOpeningForWritingTryingSP, devname); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error opening %s for writing, trying /dev/em8300_sp instead.\n", devname); sprintf(devname, "/dev/em8300_sp"); fd_spu = open(devname, fdflags); if (fd_spu < 0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_ErrorOpeningForWritingAsWellSP); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Error opening /dev/em8300_sp for writing as well!\nBailing out.\n"); uninit(); return -1; } } else { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_Opened, devname); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Opened: %s.\n", devname); } strcpy(fds_name, devname); @@ -879,7 +839,7 @@ static int preinit(const char *arg) dpy = XOpenDisplay(NULL); if (!dpy) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_UnableToOpenDisplayDuringHackSetup); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to open display during overlay hack setup!\n"); return -1; } XGetWindowAttributes(dpy, RootWindow(dpy, DefaultScreen(dpy)), &attribs); @@ -895,16 +855,10 @@ static int preinit(const char *arg) /* Initialize overlay and X11 */ overlay_data = overlay_init(fd_control); -#ifdef CONFIG_GUI - if (!use_gui) { -#endif if (!vo_init()) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_UnableToInitX11); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to init X11!\n"); return -1; } -#ifdef CONFIG_GUI - } -#endif } #endif @@ -938,7 +892,7 @@ static int overlay_set_attribute(overlay_t *o, int attribute, int value) attr.value = value; if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)==-1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedSettingOverlayAttribute); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed setting overlay attribute.\n"); return -1; } @@ -1144,7 +1098,7 @@ static int overlay_set_screen(overlay_t *o, int xres, int yres, int depth) if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr)==-1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedSettingOverlayScreen); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed setting overlay screen!\nExiting.\n"); return -1; } return 0; @@ -1153,7 +1107,7 @@ static int overlay_set_screen(overlay_t *o, int xres, int yres, int depth) static int overlay_set_mode(overlay_t *o, int mode) { if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SETMODE, &mode)==-1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedEnablingOverlay); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed enabling overlay!\nExiting.\n"); return -1; } return 0; @@ -1169,7 +1123,7 @@ static int overlay_set_window(overlay_t *o, int xpos,int ypos,int width,int heig if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SETWINDOW, &win)==-1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedResizingOverlayWindow); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed resizing overlay window!\n"); return -1; } return 0; @@ -1184,7 +1138,7 @@ static int overlay_set_bcs(overlay_t *o, int brightness, int contrast, int satur if (ioctl(o->dev, EM8300_IOCTL_GETBCS, &bcs)==-1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedSettingOverlayBcs); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed setting overlay bcs!\n"); return -1; } return 0; @@ -1272,11 +1226,11 @@ static int overlay_autocalibrate(overlay_t *o, pattern_drawer_cb pd, void *arg) cal.cal_mode = EM8300_OVERLAY_CALMODE_YOFFSET; if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_CALIBRATE, &cal)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedGettingOverlayYOffsetValues); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed getting overlay Y-offset values!\nExiting.\n"); return -1; } o->yoffset = cal.result; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_YOffset,cal.result); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Yoffset: %d.\n",cal.result); /* Calibrate X-offset */ @@ -1285,11 +1239,11 @@ static int overlay_autocalibrate(overlay_t *o, pattern_drawer_cb pd, void *arg) cal.cal_mode = EM8300_OVERLAY_CALMODE_XOFFSET; if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_CALIBRATE, &cal)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedGettingOverlayXOffsetValues); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed getting overlay X-offset values!\nExiting.\n"); return -1; } o->xoffset = cal.result; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_XOffset,cal.result); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Xoffset: %d.\n",cal.result); /* Calibrate X scale correction */ @@ -1298,10 +1252,10 @@ static int overlay_autocalibrate(overlay_t *o, pattern_drawer_cb pd, void *arg) cal.cal_mode = EM8300_OVERLAY_CALMODE_XCORRECTION; if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_CALIBRATE, &cal)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedGettingOverlayXScaleCorrection); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed getting overlay X scale correction!\nExiting.\n"); return -1; } - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_XCorrection,cal.result); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Xcorrection: %d.\n",cal.result); o->xcorr = cal.result; win.xpos = 10; @@ -1309,7 +1263,7 @@ static int overlay_autocalibrate(overlay_t *o, pattern_drawer_cb pd, void *arg) win.width = o->xres-20; win.height = o->yres-20; if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SETWINDOW, &win)==-1) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_FailedResizingOverlayWindow); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Failed resizing overlay window!\n"); exit(1); } @@ -1372,7 +1326,7 @@ static int overlay_autocalibrate(overlay_t *o, pattern_drawer_cb pd, void *arg) static int overlay_signalmode(overlay_t *o, int mode) { if(ioctl(o->dev, EM8300_IOCTL_OVERLAY_SIGNALMODE, &mode) ==-1) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_FailedSetSignalMix); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed to set signal mix!\n"); return -1; } return 0; diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c index 24870a3c96..12700108aa 100644 --- a/libvo/vo_fbdev.c +++ b/libvo/vo_fbdev.c @@ -1074,7 +1074,8 @@ static int preinit(const char *vo_subdevice) if (memcmp(vo_subdevice, "vidix", 5) == 0) vidix_name = &vo_subdevice[5]; if (vidix_name) - pre_init_err = vidix_preinit(vidix_name, &video_out_fbdev); + pre_init_err = vidix_preinit(vidix_name, + video_out_fbdev.old_functions); else #endif { @@ -1106,7 +1107,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_GET_IMAGE: @@ -1119,27 +1120,8 @@ static int control(uint32_t request, void *data, ...) if (vidix_name) { switch (request) { case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, value); - } case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } + return vidix_control(request, data); } } #endif diff --git a/libvo/vo_fbdev2.c b/libvo/vo_fbdev2.c index 3483e96456..a2b51debde 100644 --- a/libvo/vo_fbdev2.c +++ b/libvo/vo_fbdev2.c @@ -413,7 +413,7 @@ static void uninit(void) fb_preinit(1); // so that later calls to preinit don't fail } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_ggi.c b/libvo/vo_ggi.c index 645bed2577..2be65696f5 100644 --- a/libvo/vo_ggi.c +++ b/libvo/vo_ggi.c @@ -83,6 +83,8 @@ static struct ggi_conf_s { } flushregion; int voflags; + + int depthonscreen; } ggi_conf; @@ -210,7 +212,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, ggiSetFlags(ggi_conf.drawvis, GGIFLAG_ASYNC); } - vo_depthonscreen = GT_DEPTH(mode.graphtype); + ggi_conf.depthonscreen = GT_DEPTH(mode.graphtype); vo_screenwidth = mode.virt.x; vo_screenheight = mode.virt.y; @@ -374,9 +376,9 @@ static int query_format(uint32_t format) | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_ACCEPT_STRIDE; - if ((!vo_depthonscreen || !vo_dbpp) && ggi_conf.vis) { + if ((!ggi_conf.depthonscreen || !vo_dbpp) && ggi_conf.vis) { if (ggiGetMode(ggi_conf.vis, &mode) == 0) { - vo_depthonscreen = GT_DEPTH(mode.graphtype); + ggi_conf.depthonscreen = GT_DEPTH(mode.graphtype); vo_dbpp = GT_SIZE(mode.graphtype); } if (GT_SCHEME(mode.graphtype) == GT_AUTO) { @@ -384,7 +386,7 @@ static int query_format(uint32_t format) } if (GT_SCHEME(mode.graphtype) != GT_TRUECOLOR) { mode.graphtype = GT_32BIT; - vo_depthonscreen = GT_DEPTH(mode.graphtype); + ggi_conf.depthonscreen = GT_DEPTH(mode.graphtype); vo_dbpp = GT_SIZE(mode.graphtype); } } @@ -468,7 +470,7 @@ static void uninit(void) ggiExit(); } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_gif89a.c b/libvo/vo_gif89a.c index eb4c178365..3a1525f244 100644 --- a/libvo/vo_gif89a.c +++ b/libvo/vo_gif89a.c @@ -335,7 +335,7 @@ static int query_format(uint32_t format) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { if (request == VOCTRL_QUERY_FORMAT) { return query_format(*((uint32_t*)data)); @@ -374,4 +374,3 @@ static void uninit(void) reduce_data = NULL; reduce_cmap = NULL; } - diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 69d9740dee..1bd908f22b 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -31,12 +31,8 @@ #include "gl_common.h" #include "aspect.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif #include "fastmemcpy.h" -#include "libass/ass.h" -#include "libass/ass_mp.h" +#include "ass_mp.h" static const vo_info_t info = { @@ -293,11 +289,11 @@ static void clearEOSD(void) { static void do_render_osd(int); -static inline int is_tinytex(ass_image_t *i, int tinytexcur) { +static inline int is_tinytex(ASS_Image *i, int tinytexcur) { return i->w < TINYTEX_SIZE && i->h < TINYTEX_SIZE && tinytexcur < TINYTEX_MAX; } -static inline int is_smalltex(ass_image_t *i, int smalltexcur) { +static inline int is_smalltex(ASS_Image *i, int smalltexcur) { return i->w < SMALLTEX_SIZE && i->h < SMALLTEX_SIZE && smalltexcur < SMALLTEX_MAX; } @@ -322,8 +318,8 @@ static void genEOSD(mp_eosd_images_t *imgs) { int smalltexcur = 0; GLuint *curtex; GLint scale_type = scaled_osd ? GL_LINEAR : GL_NEAREST; - ass_image_t *img = imgs->imgs; - ass_image_t *i; + ASS_Image *img = imgs->imgs; + ASS_Image *i; if (imgs->changed == 0) // there are elements, but they are unchanged return; @@ -538,16 +534,8 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin image_format = format; glFindFormat(format, NULL, &gl_texfmt, &gl_format, &gl_type); - int_pause = 0; vo_flipped = !!(flags & VOFLAG_FLIPPING); -#ifdef CONFIG_GUI - if (use_gui) { - // GUI creates and manages window for us - guiGetEvent(guiSetShVideo, 0); - goto glconfig; - } -#endif #ifdef GL_WIN32 if (!vo_w32_config(d_width, d_height, flags)) return -1; @@ -1126,7 +1114,7 @@ static const struct { {NULL, NULL, 0 } }; -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_PAUSE: @@ -1157,17 +1145,15 @@ static int control(uint32_t request, void *data, ...) } } return VO_TRUE; - case VOCTRL_GUISUPPORT: - return VO_TRUE; case VOCTRL_ONTOP: - vo_ontop(); + vo_gl_ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: vo_fullscreen(); resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_BORDER: - vo_border(); + vo_gl_border(); resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_GET_PANSCAN: @@ -1179,33 +1165,25 @@ static int control(uint32_t request, void *data, ...) return VO_TRUE; case VOCTRL_GET_EQUALIZER: if (image_format == IMGFMT_YV12) { + struct voctrl_get_equalizer_args *args = data; int i; - va_list va; - int *value; - va_start(va, data); - value = va_arg(va, int *); - va_end(va); for (i = 0; eq_map[i].name; i++) - if (strcmp(data, eq_map[i].name) == 0) break; + if (strcmp(args->name, eq_map[i].name) == 0) break; if (!(eq_map[i].supportmask & (1 << use_yuv))) break; - *value = *eq_map[i].value; + *args->valueptr = *eq_map[i].value; return VO_TRUE; } break; case VOCTRL_SET_EQUALIZER: if (image_format == IMGFMT_YV12) { + struct voctrl_set_equalizer_args *args = data; int i; - va_list va; - int value; - va_start(va, data); - value = va_arg(va, int); - va_end(va); for (i = 0; eq_map[i].name; i++) - if (strcmp(data, eq_map[i].name) == 0) break; + if (strcmp(args->name, eq_map[i].name) == 0) break; if (!(eq_map[i].supportmask & (1 << use_yuv))) break; - *eq_map[i].value = value; + *eq_map[i].value = args->value; update_yuvconv(); return VO_TRUE; } @@ -1213,6 +1191,14 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_UPDATE_SCREENINFO: update_xinerama_info(); return VO_TRUE; + case VOCTRL_REDRAW_OSD: + if (vo_doublebuffering) + do_render(); + draw_osd(); + if (vo_doublebuffering) + do_render_osd(2); + flip_page(); + return VO_TRUE; } return VO_NOTIMPL; } diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index 5bbd8d15a5..e72f735bcd 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -33,9 +33,6 @@ #include "gl_common.h" #include "aspect.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif #undef TEXTUREFORMAT_ALWAYS #ifdef __APPLE__ @@ -547,13 +544,6 @@ static int config_glx(uint32_t width, uint32_t height, uint32_t d_width, uint32_ } #endif -#ifdef CONFIG_GUI -static int config_glx_gui(uint32_t d_width, uint32_t d_height) { - guiGetEvent( guiSetShVideo,0 ); // the GUI will set up / resize the window - return 0; -} -#endif - static int initGl(uint32_t d_width, uint32_t d_height) { fragprog = lookupTex = 0; @@ -619,17 +609,6 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin image_width = width; image_format = format; - int_pause = 0; - -#ifdef CONFIG_GUI - if (use_gui) { - if (config_glx_gui(d_width, d_height) == -1) - return -1; - } -#ifndef GL_WIN32 - else -#endif -#endif #ifdef GL_WIN32 if (config_w32(width, height, d_width, d_height, flags, title, format) == -1) #else @@ -874,7 +853,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_PAUSE: @@ -883,10 +862,8 @@ static int control(uint32_t request, void *data, ...) return VO_TRUE; case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); - case VOCTRL_GUISUPPORT: - return VO_TRUE; case VOCTRL_ONTOP: - vo_ontop(); + vo_gl_ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: vo_fullscreen(); @@ -895,7 +872,7 @@ static int control(uint32_t request, void *data, ...) resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_BORDER: - vo_border(); + vo_gl_border(); return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; @@ -905,23 +882,13 @@ static int control(uint32_t request, void *data, ...) #ifndef GL_WIN32 case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - return vo_x11_set_equalizer(data, value); + struct voctrl_set_equalizer_args *args = data; + return vo_x11_set_equalizer(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - va_end(ap); - return vo_x11_get_equalizer(data, value); + struct voctrl_get_equalizer_args *args = data; + return vo_x11_get_equalizer(args->name, args->valueptr); } #endif case VOCTRL_UPDATE_SCREENINFO: diff --git a/libvo/vo_ivtv.c b/libvo/vo_ivtv.c index e62308722a..b80ed44dd9 100644 --- a/libvo/vo_ivtv.c +++ b/libvo/vo_ivtv.c @@ -108,7 +108,7 @@ ivtv_reset (int blank_screen) } int -ivtv_write (unsigned char *data, int len) +ivtv_write (const unsigned char *data, int len) { if (ivtv_fd < 0) return 0; @@ -285,7 +285,7 @@ query_format (uint32_t format) } static int -control (uint32_t request, void *data, ...) +control (uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_jpeg.c b/libvo/vo_jpeg.c index 72cb2a5b22..b6a5a8c352 100644 --- a/libvo/vo_jpeg.c +++ b/libvo/vo_jpeg.c @@ -44,7 +44,7 @@ #include "mp_msg.h" #include "video_out.h" #include "video_out_internal.h" -#include "mplayer.h" /* for exit_player() */ +#include "mplayer.h" /* for exit_player_bad() */ #include "help_mp.h" /* ------------------------------------------------------------------------- */ @@ -118,36 +118,36 @@ static void jpeg_mkdir(char *buf, int verbose) { case EEXIST: if ( stat(buf, &stat_p ) < 0 ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); + _("This error has occurred"), strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - MSGTR_VO_UnableToAccess,buf); - exit_player(MSGTR_Exit_error); + _("Unable to access"), buf); + exit_player_bad(_("Fatal error")); } if ( !S_ISDIR(stat_p.st_mode) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - buf, MSGTR_VO_ExistsButNoDirectory); - exit_player(MSGTR_Exit_error); + buf, _("already exists, but is not a directory.")); + exit_player_bad(_("Fatal error")); } if ( !(stat_p.st_mode & S_IWUSR) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsButNotWritable); - exit_player(MSGTR_Exit_error); + buf, _("Output directory already exists, but is not writable.")); + exit_player_bad(_("Fatal error")); } mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsAndIsWritable); + buf, _("Output directory already exists and is writable.")); break; default: mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); + _("This error has occurred"), strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_CantCreateDirectory); - exit_player(MSGTR_Exit_error); + buf, _("Unable to create output directory.")); + exit_player_bad(_("Fatal error")); } /* end switch */ } else if ( verbose ) { mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirectoryCreateSuccess); + buf, _("Output directory successfully created.")); } /* end if */ } @@ -188,11 +188,11 @@ static uint32_t jpeg_write(uint8_t * name, uint8_t * buffer) if ( !buffer ) return 1; if ( (outfile = fopen(name, "wb") ) == NULL ) { mp_msg(MSGT_VO, MSGL_ERR, "\n%s: %s\n", info.short_name, - MSGTR_VO_CantCreateFile); + _("Unable to create output file.")); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", - info.short_name, MSGTR_VO_GenericError, - strerror(errno) ); - exit_player(MSGTR_Exit_error); + info.short_name, _("This error has occurred"), + strerror(errno) ); + exit_player_bad(_("Fatal error")); } cinfo.err = jpeg_std_error(&jerr); @@ -357,7 +357,7 @@ static int preinit(const char *arg) const char *info_message = NULL; mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, - MSGTR_VO_ParsingSuboptions); + _("Parsing suboptions.")); jpeg_progressive_mode = 0; jpeg_baseline = 1; @@ -372,12 +372,12 @@ static int preinit(const char *arg) return -1; } - if (jpeg_progressive_mode) info_message = MSGTR_VO_JPEG_ProgressiveJPEG; - else info_message = MSGTR_VO_JPEG_NoProgressiveJPEG; + if (jpeg_progressive_mode) info_message = _("Progressive JPEG enabled."); + else info_message = _("Progressive JPEG disabled."); mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message); - if (jpeg_baseline) info_message = MSGTR_VO_JPEG_BaselineJPEG; - else info_message = MSGTR_VO_JPEG_NoBaselineJPEG; + if (jpeg_baseline) info_message = _("Baseline JPEG enabled."); + else info_message = _("Baseline JPEG disabled."); mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message); mp_msg(MSGT_VO, MSGL_V, "%s: optimize --> %d\n", info.short_name, @@ -398,13 +398,13 @@ static int preinit(const char *arg) } mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, - MSGTR_VO_SuboptionsParsedOK); + _("Suboptions parsed OK.")); return 0; } /* ------------------------------------------------------------------------- */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -418,4 +418,3 @@ static int control(uint32_t request, void *data, ...) #undef BUFLENGTH /* ------------------------------------------------------------------------- */ - diff --git a/libvo/vo_kva.c b/libvo/vo_kva.c index 4805d51fbd..fbd670e790 100644 --- a/libvo/vo_kva.c +++ b/libvo/vo_kva.c @@ -933,7 +933,7 @@ static int color_ctrl_get(char *what, int *value) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_GET_IMAGE: @@ -950,26 +950,14 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return color_ctrl_set(data, value); + struct voctrl_set_equalizer_args *args = data; + color_ctrl_set(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - va_end(ap); - - return color_ctrl_get(data, value); + struct voctrl_get_equalizer_args *args = data; + return color_ctrl_get(args->name, args->valueptr); } case VOCTRL_UPDATE_SCREENINFO: diff --git a/libvo/vo_md5sum.c b/libvo/vo_md5sum.c index 754630f2da..b279ea5ad6 100644 --- a/libvo/vo_md5sum.c +++ b/libvo/vo_md5sum.c @@ -40,7 +40,7 @@ #include "mp_msg.h" #include "video_out.h" #include "video_out_internal.h" -#include "mplayer.h" /* for exit_player() */ +#include "mplayer.h" /* for exit_player_bad() */ #include "help_mp.h" #include "libavutil/md5.h" @@ -85,8 +85,8 @@ int framenum = 0; */ static void md5sum_write_error(void) { - mp_msg(MSGT_VO, MSGL_ERR, MSGTR_ErrorWritingFile, info.short_name); - exit_player(MSGTR_Exit_error); + mp_tmsg(MSGT_VO, MSGL_ERR, "%s: Error writing file.\n", info.short_name); + exit_player_bad(_("Fatal error")); } /* ------------------------------------------------------------------------- */ @@ -113,7 +113,7 @@ static int preinit(const char *arg) }; mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, - MSGTR_VO_ParsingSuboptions); + _("Parsing suboptions.")); md5sum_outfile = strdup("md5sums"); if (subopt_parse(arg, subopts) != 0) { @@ -124,7 +124,7 @@ static int preinit(const char *arg) md5sum_outfile); mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, - MSGTR_VO_SuboptionsParsedOK); + _("Suboptions parsed OK.")); return 0; } @@ -149,10 +149,10 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, if ( (md5sum_fd = fopen(md5sum_outfile, "w") ) == NULL ) { mp_msg(MSGT_VO, MSGL_ERR, "\n%s: %s\n", info.short_name, - MSGTR_VO_CantCreateFile); + _("Unable to create output file.")); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", - info.short_name, MSGTR_VO_GenericError, strerror(errno) ); - exit_player(MSGTR_Exit_error); + info.short_name, _("This error has occurred"), strerror(errno) ); + exit_player_bad(_("Fatal error")); } return 0; @@ -264,7 +264,7 @@ static int query_format(uint32_t format) /* ------------------------------------------------------------------------- */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -311,4 +311,3 @@ static void flip_page (void) #undef MD5SUM_YUV_MODE /* ------------------------------------------------------------------------- */ - diff --git a/libvo/vo_mga.c b/libvo/vo_mga.c index 7a365151ac..a83b75285f 100644 --- a/libvo/vo_mga.c +++ b/libvo/vo_mga.c @@ -85,7 +85,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ aspect(&d_width,&d_height,A_NOZOOM); vo_fs = VO_FALSE; } - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_MGA_AspectResized,d_width,d_height); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_MGA] aspect(): resized to %dx%d.\n",d_width,d_height); } vo_dwidth=d_width; vo_dheight=d_height; @@ -103,7 +103,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ static void uninit(void) { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_MGA_Uninit); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO] uninit!\n"); mga_uninit(); } @@ -116,4 +116,3 @@ static void flip_page(void) static void check_events(void) { } - diff --git a/libvo/vo_mpegpes.c b/libvo/vo_mpegpes.c index 94fe08f6f2..b96b0af639 100644 --- a/libvo/vo_mpegpes.c +++ b/libvo/vo_mpegpes.c @@ -185,7 +185,7 @@ static void draw_osd(void) } -static int my_write(unsigned char* data,int len){ +static int my_write(const unsigned char* data,int len){ int orig_len = len; #ifdef CONFIG_DVB #define NFD 2 @@ -220,15 +220,10 @@ static int my_write(unsigned char* data,int len){ return orig_len; } -void send_pes_packet(unsigned char* data,int len,int id,int timestamp){ +static void send_pes_packet(unsigned char* data,int len,int id,int timestamp){ send_mpeg_pes_packet (data, len, id, timestamp, 1, my_write); } -void send_lpcm_packet(unsigned char* data,int len,int id,unsigned int timestamp,int freq_id){ - send_mpeg_lpcm_packet(data, len, id, timestamp, freq_id, my_write); -} - - static int draw_frame(uint8_t * src[]) { vo_mpegpes_t *p=(vo_mpegpes_t *)src[0]; @@ -266,7 +261,7 @@ static void check_events(void) { } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_null.c b/libvo/vo_null.c index a6b14b4edd..9bcd4a2c24 100644 --- a/libvo/vo_null.c +++ b/libvo/vo_null.c @@ -92,13 +92,13 @@ static int preinit(const char *arg) { if(arg) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_NULL_UnknownSubdevice,arg); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_NULL] Unknown subdevice: %s.\n",arg); return ENOSYS; } return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_png.c b/libvo/vo_png.c index 8110f859df..3d7d33927a 100644 --- a/libvo/vo_png.c +++ b/libvo/vo_png.c @@ -26,9 +26,6 @@ #include <stdlib.h> #include <string.h> #include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> #include <png.h> @@ -39,9 +36,6 @@ #include "video_out.h" #include "video_out_internal.h" #include "subopt-helper.h" -#include "mplayer.h" - -#define BUFLENGTH 512 static const vo_info_t info = { @@ -54,7 +48,6 @@ static const vo_info_t info = const LIBVO_EXTERN (png) static int z_compression = Z_NO_COMPRESSION; -static char *png_outdir = NULL; static int framenum = 0; static int use_alpha; @@ -65,65 +58,16 @@ struct pngdata { enum {OK,ERROR} status; }; -static void png_mkdir(char *buf, int verbose) { - struct stat stat_p; - -#ifndef __MINGW32__ - if ( mkdir(buf, 0755) < 0 ) { -#else - if ( mkdir(buf) < 0 ) { -#endif - switch (errno) { /* use switch in case other errors need to be caught - and handled in the future */ - case EEXIST: - if ( stat(buf, &stat_p ) < 0 ) { - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - MSGTR_VO_UnableToAccess,buf); - exit_player(MSGTR_Exit_error); - } - if ( !S_ISDIR(stat_p.st_mode) ) { - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - buf, MSGTR_VO_ExistsButNoDirectory); - exit_player(MSGTR_Exit_error); - } - if ( !(stat_p.st_mode & S_IWUSR) ) { - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsButNotWritable); - exit_player(MSGTR_Exit_error); - } - - mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsAndIsWritable); - break; - - default: - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_CantCreateDirectory); - exit_player(MSGTR_Exit_error); - } /* end switch */ - } else if ( verbose ) { - mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirectoryCreateSuccess); - } /* end if */ -} - static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { - char buf[BUFLENGTH]; if(z_compression == 0) { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_PNG_Warning1); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_PNG_Warning2); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_PNG_Warning3); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_PNG] Warning: compression level set to 0, compression disabled!\n"); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_PNG] Info: Use -vo png:z=<n> to set compression level from 0 to 9.\n"); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_PNG] Info: (0 = no compression, 1 = fastest, lowest - 9 best, slowest compression)\n"); } - snprintf(buf, BUFLENGTH, "%s", png_outdir); - png_mkdir(buf, 1); mp_msg(MSGT_VO,MSGL_DBG2, "PNG Compression level %i\n", z_compression); return 0; @@ -167,7 +111,7 @@ static struct pngdata create_png (char * fname, int image_width, int image_heigh png.fp = fopen (fname, "wb"); if (png.fp == NULL) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_PNG_ErrorOpeningForWriting, strerror(errno)); + mp_tmsg(MSGT_VO,MSGL_WARN, "\n[VO_PNG] Error opening '%s' for writing!\n", strerror(errno)); png.status = ERROR; return png; } @@ -220,12 +164,12 @@ static uint32_t draw_image(mp_image_t* mpi){ // if -dr or -slices then do nothing: if(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK)) return VO_TRUE; - snprintf (buf, 100, "%s/%08d.png", png_outdir, ++framenum); + snprintf (buf, 100, "%08d.png", ++framenum); png = create_png(buf, mpi->w, mpi->h, IMGFMT_IS_BGR(mpi->imgfmt)); if(png.status){ - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_PNG_ErrorInCreatePng); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_PNG] Error in create_png.\n"); return 1; } @@ -274,12 +218,7 @@ query_format(uint32_t format) return 0; } -static void uninit(void){ - if (png_outdir) { - free(png_outdir); - png_outdir = NULL; - } -} +static void uninit(void){} static void check_events(void){} @@ -293,14 +232,12 @@ static int int_zero_to_nine(int *sh) static const opt_t subopts[] = { {"alpha", OPT_ARG_BOOL, &use_alpha, NULL}, {"z", OPT_ARG_INT, &z_compression, (opt_test_f)int_zero_to_nine}, - {"outdir", OPT_ARG_MSTRZ, &png_outdir, NULL}, {NULL} }; static int preinit(const char *arg) { z_compression = 0; - png_outdir = strdup("."); use_alpha = 0; if (subopt_parse(arg, subopts) != 0) { return -1; @@ -308,7 +245,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_DRAW_IMAGE: diff --git a/libvo/vo_pnm.c b/libvo/vo_pnm.c index 90caf55e24..f8e0b2271b 100644 --- a/libvo/vo_pnm.c +++ b/libvo/vo_pnm.c @@ -39,7 +39,7 @@ #include "mp_msg.h" #include "video_out.h" #include "video_out_internal.h" -#include "mplayer.h" /* for exit_player() */ +#include "mplayer.h" /* for exit_player_bad() */ #include "help_mp.h" /* ------------------------------------------------------------------------- */ @@ -97,8 +97,8 @@ char *pnm_file_extension = NULL; */ static void pnm_write_error(void) { - mp_msg(MSGT_VO, MSGL_ERR, MSGTR_ErrorWritingFile, info.short_name); - exit_player(MSGTR_Exit_error); + mp_tmsg(MSGT_VO, MSGL_ERR, "%s: Error writing file.\n", info.short_name); + exit_player_bad(_("Fatal error")); } /* ------------------------------------------------------------------------- */ @@ -134,7 +134,7 @@ static int preinit(const char *arg) const char *info_message = NULL; mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, - MSGTR_VO_ParsingSuboptions); + _("Parsing suboptions.")); pnm_maxfiles = 1000; pnm_outdir = strdup("."); @@ -155,29 +155,29 @@ static int preinit(const char *arg) switch (pnm_mode) { case PNM_ASCII_MODE: - info_message = MSGTR_VO_PNM_ASCIIMode; + info_message = _("ASCII mode enabled."); break; case PNM_RAW_MODE: - info_message = MSGTR_VO_PNM_RawMode; + info_message = _("Raw mode enabled."); break; } mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message); switch (pnm_type) { case PNM_TYPE_PPM: - info_message = MSGTR_VO_PNM_PPMType; + info_message = _("Will write PPM files."); break; case PNM_TYPE_PGM: - info_message = MSGTR_VO_PNM_PGMType; + info_message = _("Will write PGM files."); break; case PNM_TYPE_PGMYUV: - info_message = MSGTR_VO_PNM_PGMYUVType; + info_message = _("Will write PGMYUV files."); break; } mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message); mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, - MSGTR_VO_SuboptionsParsedOK); + _("Suboptions parsed OK.")); return 0; } @@ -211,38 +211,38 @@ static void pnm_mkdir(char *buf, int verbose) { case EEXIST: if ( stat(buf, &stat_p ) < 0 ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); + _("This error has occurred"), strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - MSGTR_VO_UnableToAccess,buf); - exit_player(MSGTR_Exit_error); + _("Unable to access"), buf); + exit_player_bad(_("Fatal error")); } if ( !S_ISDIR(stat_p.st_mode) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - buf, MSGTR_VO_ExistsButNoDirectory); - exit_player(MSGTR_Exit_error); + buf, _("already exists, but is not a directory.")); + exit_player_bad(_("Fatal error")); } if ( !(stat_p.st_mode & S_IWUSR) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsButNotWritable); - exit_player(MSGTR_Exit_error); + buf, _("Output directory already exists, but is not writable.")); + exit_player_bad(_("Fatal error")); } if (strcmp(buf, ".") != 0) { mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsAndIsWritable); + buf, _("Output directory already exists and is writable.")); } break; default: mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); + _("This error has occurred"), strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_CantCreateDirectory); - exit_player(MSGTR_Exit_error); + buf, _("Unable to create output directory.")); + exit_player_bad(_("Fatal error")); } /* end switch */ } else if ( verbose ) { mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirectoryCreateSuccess); + buf, _("Output directory successfully created.")); } /* end if */ } @@ -442,7 +442,7 @@ static void pnm_write_image(mp_image_t *mpi) if (!mpi) { mp_msg(MSGT_VO, MSGL_ERR, "%s: No image data suplied to video output driver\n", info.short_name ); - exit_player(MSGTR_Exit_error); + exit_player_bad(_("Fatal error")); } /* Start writing to new subdirectory after a certain amount of frames */ @@ -470,11 +470,11 @@ static void pnm_write_image(mp_image_t *mpi) if ( (outfile = fopen(buf, "wb") ) == NULL ) { mp_msg(MSGT_VO, MSGL_ERR, "\n%s: %s\n", info.short_name, - MSGTR_VO_CantCreateFile); + "Unable to create output file."); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", - info.short_name, MSGTR_VO_GenericError, + info.short_name, "This error has occurred", strerror(errno) ); - exit_player(MSGTR_Exit_error); + exit_player_bad(_("Fatal error")); } pnm_write_pnm(outfile, mpi); @@ -542,7 +542,7 @@ static int query_format(uint32_t format) /* ------------------------------------------------------------------------- */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -595,4 +595,3 @@ static void flip_page (void) #undef PNM_TYPE_PGMYUV /* ------------------------------------------------------------------------- */ - diff --git a/libvo/vo_quartz.c b/libvo/vo_quartz.c index 46c78b0583..42c9eb4ed4 100644 --- a/libvo/vo_quartz.c +++ b/libvo/vo_quartz.c @@ -1179,7 +1179,7 @@ static uint32_t get_yuv_image(mp_image_t * mpi) return VO_FALSE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_s3fb.c b/libvo/vo_s3fb.c index c45b2c66e4..5b884b75b8 100644 --- a/libvo/vo_s3fb.c +++ b/libvo/vo_s3fb.c @@ -521,7 +521,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch(request) { case VOCTRL_GET_IMAGE: diff --git a/libvo/vo_sdl.c b/libvo/vo_sdl.c index 1b9a985d83..25e411a5ce 100644 --- a/libvo/vo_sdl.c +++ b/libvo/vo_sdl.c @@ -425,7 +425,7 @@ static int sdl_open (void *plugin, void *name) */ priv->sdlflags &= ~SDL_HWSURFACE; if ((!SDL_ListModes (vidInfo->vfmt, priv->sdlflags)) && (!priv->fullmodes)) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SDL_CouldntGetAnyAcceptableSDLModeForOutput); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SDL] Couldn't get any acceptable SDL Mode for output.\n"); return -1; } } @@ -706,7 +706,7 @@ static void set_fullmode (int mode) { setup_surfaces(); } else - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_SetVideoModeFailedFull, SDL_GetError()); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SDL] Set_fullmode: SDL_SetVideoMode failed: %s.\n", SDL_GetError()); } @@ -728,7 +728,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin switch(format){ case IMGFMT_I420: - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_MappingI420ToIYUV); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SDL] Mapping I420 to IYUV.\n"); format = SDL_IYUV_OVERLAY; case IMGFMT_YV12: case IMGFMT_IYUV: @@ -750,7 +750,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin priv->mode = RGB; break; default: - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_UnsupportedImageFormat,format); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SDL] Unsupported image format (0x%X).\n",format); return -1; } @@ -808,7 +808,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin } if(flags&VOFLAG_FULLSCREEN) { mp_msg(MSGT_VO,MSGL_V, "SDL: setting zoomed fullscreen without modeswitching\n"); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_InfoPleaseUseVmOrZoom); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SDL] Info - please use -vm or -zoom to switch to the best resolution.\n"); priv->fulltype = VOFLAG_FULLSCREEN; set_fullmode(priv->fullmode); /*if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlfullflags))) @@ -845,7 +845,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin } if(!priv->surface) { // cannot SetVideoMode - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_FailedToSetVideoMode, SDL_GetError()); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SDL] Failed to set video mode: %s.\n", SDL_GetError()); return -1; } @@ -933,7 +933,7 @@ static int setup_surfaces(void) default: /* Initialize and create the YUV Overlay used for video out */ if (!(priv->overlay = SDL_CreateYUVOverlay (surfwidth, surfheight, priv->format, priv->surface))) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_CouldntCreateAYUVOverlay, SDL_GetError()); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SDL] Couldn't create a YUV overlay: %s.\n", SDL_GetError()); return -1; } priv->framePlaneY = priv->width * priv->height; @@ -946,14 +946,14 @@ static int setup_surfaces(void) if(priv->mode != YUV) { if(!priv->rgbsurface) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_CouldntCreateARGBSurface, SDL_GetError()); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SDL] Couldn't create an RGB surface: %s.\n", SDL_GetError()); return -1; } priv->dblit = 0; if((priv->format&0xFF) != priv->bpp) - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_UsingDepthColorspaceConversion, priv->format&0xFF, priv->bpp); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SDL] Using depth/colorspace conversion, this will slow things down (%ibpp -> %ibpp).\n", priv->format&0xFF, priv->bpp); priv->framePlaneRGB = priv->width * priv->height * priv->rgbsurface->format->BytesPerPixel; priv->stridePlaneRGB = priv->width * priv->rgbsurface->format->BytesPerPixel; @@ -1081,7 +1081,7 @@ static int draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) break; default: - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_UnsupportedImageFormatInDrawslice); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SDL] Unsupported image format in draw_slice, contact MPlayer developers!\n"); } SDL_OVR_UNLOCK @@ -1443,7 +1443,7 @@ static void flip_page (void) if(!priv->dblit) { /* blit to the RGB surface */ if(SDL_BlitSurface (priv->rgbsurface, NULL, priv->surface, NULL)) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_BlitFailed, SDL_GetError()); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SDL] Blit failed: %s.\n", SDL_GetError()); } /* update screen */ @@ -1566,14 +1566,14 @@ static int preinit(const char *arg) /* initialize the SDL Video system */ if (!SDL_WasInit(SDL_INIT_VIDEO)) { if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SDL_InitializationFailed, SDL_GetError()); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SDL] SDL initialization failed: %s.\n", SDL_GetError()); return -1; } } SDL_VideoDriverName(priv->driver, 8); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_UsingDriver, priv->driver); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SDL] Using driver: %s.\n", priv->driver); priv->X = 0; #ifdef CONFIG_X11 @@ -1635,7 +1635,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_FALSE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { struct sdl_priv_s *priv = &sdl_priv; switch (request) { diff --git a/libvo/vo_svga.c b/libvo/vo_svga.c index 606d02c7d3..ed68fd79a6 100644 --- a/libvo/vo_svga.c +++ b/libvo/vo_svga.c @@ -152,7 +152,7 @@ static int preinit(const char *arg) vidix_name[i-5]=0; if(arg[i]==':')i++; arg+=i; - vidix_preinit(vidix_name, &video_out_svga); + vidix_preinit(vidix_name, video_out_svga.old_functions); } #endif if(!strncmp(arg,"sq",2)) { @@ -358,7 +358,7 @@ static int find_best_svga_mode(int req_w,int req_h, int req_bpp){ return bestmode; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -370,33 +370,8 @@ static int control(uint32_t request, void *data, ...) } #ifdef CONFIG_VIDIX - if (vidix_name[0]) { - switch (request) { - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } - } + if (vidix_name[0]) return vidix_control(request, data); - } #endif return VO_NOTIMPL; @@ -432,24 +407,24 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, }else{//force_vm vid_mode=force_vm; if(vga_hasmode(vid_mode) == 0){ - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_ForcedVidmodeNotAvailable, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SVGA] Forced vid_mode %d (%s) not available.\n", vid_mode,vga_getmodename(vid_mode)); return 1; //error; } modeinfo=vga_getmodeinfo(vid_mode); if( (modeinfo->width < req_w) || (modeinfo->height < req_h) ){ - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_ForcedVidmodeTooSmall, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SVGA] Forced vid_mode %d (%s) too small.\n", vid_mode,vga_getmodename(vid_mode)); return 1; } } mode_bpp=bpp_from_vminfo(modeinfo); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_Vidmode, + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SVGA] Vid_mode: %d, %dx%d %dbpp.\n", vid_mode,modeinfo->width,modeinfo->height,mode_bpp); if (vga_setmode(vid_mode) == -1) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_VgasetmodeFailed,vid_mode); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SVGA] Vga_setmode(%d) failed.\n",vid_mode); uninit(); return 1; // error } @@ -499,11 +474,11 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, } }//fi force native if(mode_capabilities&CAP_LINEAR){ - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_VideoModeIsLinearAndMemcpyCouldBeUsed); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SVGA] Video mode is linear and memcpy could be used for image transfer.\n"); } if(mode_capabilities&CAP_ACCEL_PUTIMAGE){ - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_VideoModeHasHardwareAcceleration); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_IfItWorksForYouIWouldLikeToKnow); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SVGA] Video mode has hardware acceleration and put_image could be used.\n"); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SVGA] If it works for you I would like to know.\n[VO_SVGA] (send log with `mplayer test.avi -v -v -v -v &> svga.log`). Thx!\n"); } //here is the place to handle strides for accel_ modes; @@ -537,7 +512,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, } } assert(max_pages>0); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_VideoModeHas,max_pages); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SVGA] Video mode has %d page(s).\n",max_pages); //15bpp if(modeinfo->bytesperpixel!=0) vga_claimvideomemory(max_pages * modeinfo->height * modeinfo->width * modeinfo->bytesperpixel); @@ -552,14 +527,14 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, x_pos = (modeinfo->width - req_w) / 2; y_pos = (modeinfo->height - req_h) / 2; x_pos &= ~(15); //align x offset position to 16 pixels - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_CenteringImageStartAt,x_pos,y_pos); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SVGA] Centering image. Starting at (%d,%d)\n",x_pos,y_pos); #ifdef CONFIG_VIDIX if(vidix_name[0]){ vidix_init(width, height, x_pos, y_pos, modeinfo->width, modeinfo->height, format, mode_bpp, modeinfo->width,modeinfo->height); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_UsingVidix,width,height, + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_SVGA] Using VIDIX. w=%i h=%i mw=%i mh=%i\n",width,height, modeinfo->width,modeinfo->height); vidix_start(); /*set colorkey*/ diff --git a/libvo/vo_tdfx_vid.c b/libvo/vo_tdfx_vid.c index fcd00969d2..b9fb75eec6 100644 --- a/libvo/vo_tdfx_vid.c +++ b/libvo/vo_tdfx_vid.c @@ -87,10 +87,10 @@ static void clear_screen(void) { mov.dst = front_buffer; mov.dst_stride = tdfx_cfg.screen_stride; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_Move, mov.width,mov.src_stride,mov.height,mov.dst_stride); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_TDXVID] Move %d(%d) x %d => %d.\n", mov.width,mov.src_stride,mov.height,mov.dst_stride); if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AGPMoveFailedToClearTheScreen); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] AGP move failed to clear the screen.\n"); } #endif @@ -176,7 +176,7 @@ flip_page(void) blit.dst_h = src_height; blit.dst_format = IMGFMT_BGR16; if(ioctl(tdfx_fd,TDFX_VID_BLIT,&blit)) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_BlitFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Blit failed.\n"); } return; } @@ -198,7 +198,7 @@ flip_page(void) blit.dst_format = dst_fmt; if(ioctl(tdfx_fd,TDFX_VID_BLIT,&blit)) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_BlitFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Blit failed.\n"); } static int @@ -266,7 +266,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin case IMGFMT_BGR24: case IMGFMT_BGR32: if(use_overlay) - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_NonNativeOverlayFormatNeedConversion); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_TDFXVID] Non-native overlay format needs conversion.\n"); case IMGFMT_BGR15: case IMGFMT_BGR16: src_bpp = ((format & 0x3F)+7)/8; @@ -282,7 +282,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin src_bpp = 2; break; default: - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_UnsupportedInputFormat,format); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Unsupported input format 0x%x.\n",format); return 1; } @@ -338,28 +338,28 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin ov.use_colorkey = 0; if(ioctl(tdfx_fd,TDFX_VID_SET_OVERLAY,&ov)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlaySetupFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Overlay setup failed.\n"); use_overlay = 0; break; } tdfx_ov = ov; if(use_overlay == 1) { if(ioctl(tdfx_fd,TDFX_VID_OVERLAY_ON)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlayOnFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Overlay on failed.\n"); use_overlay = 0; break; } use_overlay++; } - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_OverlayReady, + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_TDFXVID] Overlay ready: %d(%d) x %d @ %d => %d(%d) x %d @ %d.\n", src_width,src_stride,src_height,src_bpp, dst_width,dst_stride,dst_height,dst_bpp); break; } if(!use_overlay) - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_TextureBlitReady, + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_TDFXVID] Texture blit ready: %d(%d) x %d @ %d => %d(%d) x %d @ %d.\n", src_width,src_stride,src_height,src_bpp, dst_width,dst_stride,dst_height,dst_bpp); @@ -371,7 +371,7 @@ uninit(void) { if(use_overlay == 2) { if(ioctl(tdfx_fd,TDFX_VID_OVERLAY_OFF)) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlayOffFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Overlay off failed\n"); use_overlay--; } close(tdfx_fd); @@ -388,13 +388,13 @@ static int preinit(const char *arg) tdfx_fd = open(arg ? arg : "/dev/tdfx_vid", O_RDWR); if(tdfx_fd < 0) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_CantOpen,arg ? arg : "/dev/tdfx_vid", + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Can't open %s: %s.\n",arg ? arg : "/dev/tdfx_vid", strerror(errno)); return 1; } if(ioctl(tdfx_fd,TDFX_VID_GET_CONFIG,&tdfx_cfg)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_CantGetCurrentCfg,strerror(errno)); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Can't get current configuration: %s.\n",strerror(errno)); return 1; } @@ -413,7 +413,7 @@ static int preinit(const char *arg) tdfx_fd, 0); if(agp_mem == MAP_FAILED) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_MemmapFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Memmap failed !!!!!\n"); return 1; } @@ -465,7 +465,7 @@ static uint32_t get_image(mp_image_t *mpi) { mpi->stride[2] = mpi->chroma_width; break; default: - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_GetImageTodo); + mp_tmsg(MSGT_VO,MSGL_WARN, "Get image todo.\n"); return VO_FALSE; } mpi->flags |= MP_IMGFLAG_DIRECT; @@ -531,7 +531,7 @@ static uint32_t draw_image(mp_image_t *mpi){ mov.dst_stride = src_stride; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] AGP move failed.\n"); break; case IMGFMT_YV12: @@ -560,7 +560,7 @@ static uint32_t draw_image(mp_image_t *mpi){ yuv.base = back_buffer; yuv.stride = src_stride; if(ioctl(tdfx_fd,TDFX_VID_SET_YUV,&yuv)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_SetYuvFailed); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] Set YUV failed.\n"); break; } @@ -576,7 +576,7 @@ static uint32_t draw_image(mp_image_t *mpi){ mov.dst_stride = TDFX_VID_YUV_STRIDE; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnYPlane); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] AGP move failed on Y plane.\n"); break; } //return 0; @@ -588,7 +588,7 @@ static uint32_t draw_image(mp_image_t *mpi){ mov.src_stride = buffer_stride[p]; mov.dst += TDFX_VID_YUV_PLANE_SIZE; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnUPlane); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] AGP move failed on U plane.\n"); break; } // V @@ -597,12 +597,12 @@ static uint32_t draw_image(mp_image_t *mpi){ mov.src_stride = buffer_stride[p]; mov.dst += TDFX_VID_YUV_PLANE_SIZE; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnVPlane); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] AGP move failed on V plane.\n"); break; } break; default: - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_UnknownFormat,mpi->imgfmt); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TDFXVID] unknown format: 0x%x.\n",mpi->imgfmt); return VO_TRUE; } @@ -644,7 +644,7 @@ static uint32_t set_colorkey(mp_colorkey_t* colork) { return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -666,4 +666,3 @@ static int control(uint32_t request, void *data, ...) } return VO_NOTIMPL; } - diff --git a/libvo/vo_tdfxfb.c b/libvo/vo_tdfxfb.c index 03f0513076..343045dff3 100644 --- a/libvo/vo_tdfxfb.c +++ b/libvo/vo_tdfxfb.c @@ -111,12 +111,12 @@ static int preinit(const char *arg) name = "/dev/fb0"; if((fd = open(name, O_RDWR)) == -1) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_CantOpen, name, strerror(errno)); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] Can't open %s: %s.\n", name, strerror(errno)); return -1; } if(ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_ProblemWithFbitgetFscreenInfo, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] Problem with FBITGET_FSCREENINFO ioctl: %s.\n", strerror(errno)); close(fd); fd = -1; @@ -124,7 +124,7 @@ static int preinit(const char *arg) } if(ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_ProblemWithFbitgetVscreenInfo, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] Problem with FBITGET_VSCREENINFO ioctl: %s.\n", strerror(errno)); close(fd); fd = -1; @@ -133,7 +133,7 @@ static int preinit(const char *arg) /* BANSHEE means any of the series aparently */ if (fb_finfo.accel != FB_ACCEL_3DFX_BANSHEE) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_ThisDriverOnlySupports); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] This driver only supports the 3Dfx Banshee, Voodoo3 and Voodoo 5.\n"); close(fd); fd = -1; return -1; @@ -146,7 +146,7 @@ static int preinit(const char *arg) case 32: break; // Ok default: - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_OutputIsNotSupported, fb_vinfo.bits_per_pixel); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] %d bpp output is not supported.\n", fb_vinfo.bits_per_pixel); close(fd); fd = -1; return -1; @@ -159,7 +159,7 @@ static int preinit(const char *arg) MAP_SHARED, fd, fb_finfo.smem_len); if((long)memBase0 == -1 || (long)memBase1 == -1) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_CouldntMapMemoryAreas, strerror(errno)); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] Couldn't map memory areas: %s.\n", strerror(errno)); if((long)memBase0 != -1) munmap(memBase0, fb_finfo.smem_len); if((long)memBase1 != -1) @@ -266,7 +266,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ break; default: - mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_TDFXFB_BppOutputIsNotSupported, fb_vinfo.bits_per_pixel); + mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_TDFXFB] %d bpp output is not supported (This should never have happened).\n", fb_vinfo.bits_per_pixel); return -1; } @@ -304,7 +304,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ break; default: - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_SomethingIsWrongWithControl); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] Eik! Something's wrong with control().\n"); return -1; } @@ -321,7 +321,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ inpageoffset = hidpageoffset + screenwidth * screenheight * screendepth; if(inpageoffset + in_width * in_depth * in_height > fb_finfo.smem_len) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_NotEnoughVideoMemoryToPlay); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_TDFXFB] Not enough video memory to play this movie. Try at a lower resolution.\n"); return -1; } @@ -333,7 +333,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ memset(inpage, 0, in_width * in_height * in_depth); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXFB_ScreenIs, + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_TDFXFB] Screen is %dx%d at %d bpp, in is %dx%d at %d bpp, norm is %dx%d.\n", screenwidth, screenheight, screendepth * 8, in_width, in_height, in_depth * 8, d_width, d_height); @@ -496,7 +496,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch(request) { case VOCTRL_GET_IMAGE: diff --git a/libvo/vo_tga.c b/libvo/vo_tga.c index dad6b960a9..38299aca88 100644 --- a/libvo/vo_tga.c +++ b/libvo/vo_tga.c @@ -254,13 +254,13 @@ static void check_events(void) static int preinit(const char *arg) { if(arg) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TGA_UnknownSubdevice,arg); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TGA] Unknown subdevice: %s.\n",arg); return ENOSYS; } return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_DRAW_IMAGE: diff --git a/libvo/vo_v4l2.c b/libvo/vo_v4l2.c index 62808f8291..c0362aa83c 100644 --- a/libvo/vo_v4l2.c +++ b/libvo/vo_v4l2.c @@ -69,7 +69,7 @@ static const vo_info_t info = const LIBVO_EXTERN (v4l2) int -v4l2_write (unsigned char *data, int len) +v4l2_write (const unsigned char *data, int len) { if (v4l2_fd < 0) return 0; @@ -253,7 +253,7 @@ query_format (uint32_t format) } static int -control (uint32_t request, void *data, ...) +control (uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index 97242d9abf..484b5fc87d 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -2,6 +2,7 @@ * VDPAU video output driver * * Copyright (C) 2008 NVIDIA + * Copyright (C) 2009 Uoti Urpala * * This file is part of MPlayer. * @@ -20,623 +21,816 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/** - * \defgroup VDPAU_Presentation VDPAU Presentation - * \ingroup Decoder - * +/* * Actual decoding and presentation are implemented here. * All necessary frame information is collected through * the "vdpau_render_state" structure after parsing all headers * etc. in libavcodec for different codecs. - * - * @{ */ #include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> +#include <stdint.h> +#include <stdbool.h> +#include <limits.h> #include "config.h" #include "mp_msg.h" +#include "options.h" +#include "talloc.h" #include "video_out.h" -#include "video_out_internal.h" #include "x11_common.h" #include "aspect.h" #include "sub.h" #include "subopt-helper.h" +#include "libmpcodecs/vfcap.h" +#include "libmpcodecs/mp_image.h" +#include "osdep/timer.h" #include "libavcodec/vdpau.h" -#include "gui/interface.h" +#include "font_load.h" #include "libavutil/common.h" #include "libavutil/mathematics.h" -#include "libass/ass.h" -#include "libass/ass_mp.h" - -static vo_info_t info = { - "VDPAU with X11", - "vdpau", - "Rajib Mahapatra <rmahapatra@nvidia.com> and others", - "" -}; - -LIBVO_EXTERN(vdpau) +#include "ass_mp.h" #define CHECK_ST_ERROR(message) \ - if (vdp_st != VDP_STATUS_OK) { \ - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] %s: %s\n", \ - message, vdp_get_error_string(vdp_st)); \ - return -1; \ - } + do { \ + if (vdp_st != VDP_STATUS_OK) { \ + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] %s: %s\n", \ + message, vdp->get_error_string(vdp_st)); \ + return -1; \ + } \ + } while (0) #define CHECK_ST_WARNING(message) \ - if (vdp_st != VDP_STATUS_OK) \ - mp_msg(MSGT_VO, MSGL_WARN, "[vdpau] %s: %s\n", \ - message, vdp_get_error_string(vdp_st)); + do { \ + if (vdp_st != VDP_STATUS_OK) \ + mp_msg(MSGT_VO, MSGL_WARN, "[ vdpau] %s: %s\n", \ + message, vdp->get_error_string(vdp_st)); \ + } while (0) /* number of video and output surfaces */ -#define NUM_OUTPUT_SURFACES 2 +#define NUM_OUTPUT_SURFACES 3 #define MAX_VIDEO_SURFACES 50 +#define NUM_BUFFERED_VIDEO 4 /* number of palette entries */ #define PALETTE_SIZE 256 -/* Initial maximum number of EOSD surfaces */ -#define EOSD_SURFACES_INITIAL 512 +/* Initial size of EOSD surface in pixels (x*x) */ +#define EOSD_SURFACE_INITIAL_SIZE 256 /* * Global variable declaration - VDPAU specific */ -/* Declaration for all variables of win_x11_init_vdpau_procs() and - * win_x11_init_vdpau_flip_queue() functions - */ -static VdpDevice vdp_device; -static VdpGetProcAddress *vdp_get_proc_address; - -static VdpPresentationQueueTarget vdp_flip_target; -static VdpPresentationQueue vdp_flip_queue; - -static VdpDeviceDestroy *vdp_device_destroy; -static VdpVideoSurfaceCreate *vdp_video_surface_create; -static VdpVideoSurfaceDestroy *vdp_video_surface_destroy; - -static VdpGetErrorString *vdp_get_error_string; +struct vdp_functions { +#define VDP_FUNCTION(vdp_type, _, mp_name) vdp_type *mp_name; +#include "vdpau_template.c" +#undef VDP_FUNCTION +}; -/* May be used in software filtering/postprocessing options - * in MPlayer (./mplayer -vf ..) if we copy video_surface data to - * system memory. - */ -static VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_put_bits_y_cb_cr; -static VdpOutputSurfacePutBitsNative *vdp_output_surface_put_bits_native; - -static VdpOutputSurfaceCreate *vdp_output_surface_create; -static VdpOutputSurfaceDestroy *vdp_output_surface_destroy; - -/* VideoMixer puts video_surface data on displayable output_surface. */ -static VdpVideoMixerCreate *vdp_video_mixer_create; -static VdpVideoMixerDestroy *vdp_video_mixer_destroy; -static VdpVideoMixerRender *vdp_video_mixer_render; -static VdpVideoMixerSetFeatureEnables *vdp_video_mixer_set_feature_enables; -static VdpVideoMixerSetAttributeValues *vdp_video_mixer_set_attribute_values; - -static VdpPresentationQueueTargetDestroy *vdp_presentation_queue_target_destroy; -static VdpPresentationQueueCreate *vdp_presentation_queue_create; -static VdpPresentationQueueDestroy *vdp_presentation_queue_destroy; -static VdpPresentationQueueDisplay *vdp_presentation_queue_display; -static VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle; -static VdpPresentationQueueTargetCreateX11 *vdp_presentation_queue_target_create_x11; - -static VdpOutputSurfaceRenderOutputSurface *vdp_output_surface_render_output_surface; -static VdpOutputSurfacePutBitsIndexed *vdp_output_surface_put_bits_indexed; -static VdpOutputSurfaceRenderBitmapSurface *vdp_output_surface_render_bitmap_surface; - -static VdpBitmapSurfaceCreate *vdp_bitmap_surface_create; -static VdpBitmapSurfaceDestroy *vdp_bitmap_surface_destroy; -static VdpBitmapSurfacePutBitsNative *vdp_bitmap_surface_putbits_native; - -static VdpDecoderCreate *vdp_decoder_create; -static VdpDecoderDestroy *vdp_decoder_destroy; -static VdpDecoderRender *vdp_decoder_render; - -static VdpGenerateCSCMatrix *vdp_generate_csc_matrix; -static VdpPreemptionCallbackRegister *vdp_preemption_callback_register; - -/* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */ -#define osd_surface output_surfaces[NUM_OUTPUT_SURFACES] -static VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1]; -static VdpVideoSurface deint_surfaces[3]; -static mp_image_t *deint_mpi[2]; -static int output_surface_width, output_surface_height; - -static VdpVideoMixer video_mixer; -static int deint; -static int deint_type; -static int deint_counter; -static int deint_buffer_past_frames; -static int pullup; -static float denoise; -static float sharpen; -static int colorspace; -static int chroma_deint; -static int force_mixer; -static int top_field_first; -static int flip; -static int hqscaling; - -static VdpDecoder decoder; -static int decoder_max_refs; - -static VdpRect src_rect_vid; -static VdpRect out_rect_vid; -static int border_x, border_y; - -static struct vdpau_render_state surface_render[MAX_VIDEO_SURFACES]; -static int surface_num; -static int vid_surface_num; -static uint32_t vid_width, vid_height; -static uint32_t image_format; -static VdpChromaType vdp_chroma_type; -static VdpYCbCrFormat vdp_pixel_format; - -static volatile int is_preempted; - -/* draw_osd */ -static unsigned char *index_data; -static int index_data_size; -static uint32_t palette[PALETTE_SIZE]; - -// EOSD -// Pool of surfaces -struct { - VdpBitmapSurface surface; - int w; - int h; - char in_use; -} *eosd_surfaces; - -// List of surfaces to be rendered -struct { - VdpBitmapSurface surface; - VdpRect source; - VdpRect dest; - VdpColor color; -} *eosd_targets; - -static int eosd_render_count; -static int eosd_surface_count; - -// Video equalizer -static VdpProcamp procamp; +struct vdpctx { + struct vdp_functions *vdp; + + VdpDevice vdp_device; + bool is_preempted; + bool preemption_acked; + bool preemption_user_notified; + unsigned int last_preemption_retry_fail; + VdpDeviceCreateX11 *vdp_device_create; + VdpGetProcAddress *vdp_get_proc_address; + + VdpPresentationQueueTarget flip_target; + VdpPresentationQueue flip_queue; + uint64_t last_vdp_time; + unsigned int last_sync_update; + + void *vdpau_lib_handle; + + /* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */ +#define osd_surface vc->output_surfaces[NUM_OUTPUT_SURFACES] + VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1]; + struct buffered_video_surface { + VdpVideoSurface surface; + double pts; + mp_image_t *mpi; + } buffered_video[NUM_BUFFERED_VIDEO]; + int deint_queue_pos; + int output_surface_width, output_surface_height; + + VdpVideoMixer video_mixer; + int user_colorspace; + int colorspace; + int deint; + int deint_type; + int deint_counter; + int pullup; + float denoise; + float sharpen; + int hqscaling; + int chroma_deint; + int top_field_first; + bool flip; + + VdpDecoder decoder; + int decoder_max_refs; + + VdpRect src_rect_vid; + VdpRect out_rect_vid; + int border_x, border_y; + + struct vdpau_render_state surface_render[MAX_VIDEO_SURFACES]; + int surface_num; + VdpTime recent_vsync_time; + float user_fps; + unsigned int vsync_interval; + uint64_t last_queue_time; + uint64_t last_ideal_time; + bool dropped_frame; + uint64_t dropped_time; + uint32_t vid_width, vid_height; + uint32_t image_format; + VdpChromaType vdp_chroma_type; + VdpYCbCrFormat vdp_pixel_format; + + /* draw_osd */ + unsigned char *index_data; + int index_data_size; + uint32_t palette[PALETTE_SIZE]; + + // EOSD + // Pool of surfaces + struct eosd_bitmap_surface { + VdpBitmapSurface surface; + int w; + int h; + uint32_t max_width; + uint32_t max_height; + } eosd_surface; + + // List of surfaces to be rendered + struct eosd_target { + VdpRect source; + VdpRect dest; + VdpColor color; + } *eosd_targets; + int eosd_targets_size; + int *eosd_scratch; + + int eosd_render_count; + + // Video equalizer + VdpProcamp procamp; + + int num_shown_frames; + bool paused; + + // These tell what's been initialized and uninit() should free/uninitialize + bool mode_switched; +}; -/* - * X11 specific - */ -static int visible_buf; -static int int_pause; +static int change_vdptime_sync(struct vdpctx *vc, unsigned int *t) +{ + struct vdp_functions *vdp = vc->vdp; + VdpStatus vdp_st; + VdpTime vdp_time; + vdp_st = vdp->presentation_queue_get_time(vc->flip_queue, &vdp_time); + CHECK_ST_ERROR("Error when calling vdp_presentation_queue_get_time"); + unsigned int t1 = *t; + unsigned int t2 = GetTimer(); + uint64_t old = vc->last_vdp_time + (t1 - vc->last_sync_update) * 1000ULL; + if (vdp_time > old) + if (vdp_time > old + (t2 - t1) * 1000ULL) + vdp_time -= (t2 - t1) * 1000ULL; + else + vdp_time = old; + mp_msg(MSGT_VO, MSGL_V, "[vdpau] adjusting VdpTime offset by %f µs\n", + (int64_t)(vdp_time - old) / 1000.); + vc->last_vdp_time = vdp_time; + vc->last_sync_update = t1; + *t = t2; + return 0; +} -static void draw_eosd(void); +static uint64_t sync_vdptime(struct vo *vo) +{ + struct vdpctx *vc = vo->priv; + + unsigned int t = GetTimer(); + if (t - vc->last_sync_update > 5000000) + change_vdptime_sync(vc, &t); + uint64_t now = (t - vc->last_sync_update) * 1000ULL + vc->last_vdp_time; + // Make sure nanosecond inaccuracies don't make things inconsistent + now = FFMAX(now, vc->recent_vsync_time); + return now; +} -static void push_deint_surface(VdpVideoSurface surface) +static uint64_t convert_to_vdptime(struct vo *vo, unsigned int t) { - deint_surfaces[2] = deint_surfaces[1]; - deint_surfaces[1] = deint_surfaces[0]; - deint_surfaces[0] = surface; + struct vdpctx *vc = vo->priv; + return (int)(t - vc->last_sync_update) * 1000LL + vc->last_vdp_time; } -static void video_to_output_surface(void) +static void flip_page_timed(struct vo *vo, unsigned int pts_us, int duration); + +static int video_to_output_surface(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpTime dummy; VdpStatus vdp_st; - int i; - if (vid_surface_num < 0) - return; + if (vc->deint_queue_pos < 0) + return -1; - if (deint < 2 || deint_surfaces[0] == VDP_INVALID_HANDLE) - push_deint_surface(surface_render[vid_surface_num].surface); + struct buffered_video_surface *bv = vc->buffered_video; + int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; + unsigned int dp = vc->deint_queue_pos; + // dp==0 means last field of latest frame, 1 earlier field of latest frame, + // 2 last field of previous frame and so on + if (vc->deint) { + field = vc->top_field_first ^ (dp & 1) ? + VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD: + VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; + } + const VdpVideoSurface *past_fields = (const VdpVideoSurface []){ + bv[(dp+1)/2].surface, bv[(dp+2)/2].surface}; + const VdpVideoSurface *future_fields = (const VdpVideoSurface []){ + dp >= 1 ? bv[(dp-1)/2].surface : VDP_INVALID_HANDLE}; + VdpOutputSurface output_surface = vc->output_surfaces[vc->surface_num]; + vdp_st = vdp->presentation_queue_block_until_surface_idle(vc->flip_queue, + output_surface, + &dummy); + CHECK_ST_WARNING("Error when calling " + "vdp_presentation_queue_block_until_surface_idle"); + + vdp_st = vdp->video_mixer_render(vc->video_mixer, VDP_INVALID_HANDLE, + 0, field, 2, past_fields, + bv[dp/2].surface, 1, future_fields, + &vc->src_rect_vid, output_surface, + NULL, &vc->out_rect_vid, 0, NULL); + CHECK_ST_WARNING("Error when calling vdp_video_mixer_render"); + return 0; +} - for (i = 0; i <= !!(deint > 1); i++) { - int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; - VdpOutputSurface output_surface; - if (i) { - draw_eosd(); - draw_osd(); - flip_page(); +static void get_buffered_frame(struct vo *vo, bool eof) +{ + struct vdpctx *vc = vo->priv; + + int dqp = vc->deint_queue_pos; + if (dqp < 0) + dqp += 1000; + else + dqp = vc->deint >= 2 ? dqp - 1 : dqp - 2 | 1; + if (dqp < (eof ? 0 : 3)) + return; + + dqp = FFMIN(dqp, 4); + vc->deint_queue_pos = dqp; + vo->frame_loaded = true; + + // Set pts values + struct buffered_video_surface *bv = vc->buffered_video; + int idx = vc->deint_queue_pos >> 1; + if (idx == 0) { // no future frame/pts available + vo->next_pts = bv[0].pts; + vo->next_pts2 = MP_NOPTS_VALUE; + } else if (!(vc->deint >= 2)) { // no field-splitting deinterlace + vo->next_pts = bv[idx].pts; + vo->next_pts2 = bv[idx - 1].pts; + } else { // deinterlace with separate fields + double intermediate_pts; + double diff = bv[idx - 1].pts - bv[idx].pts; + if (diff > 0 && diff < 0.5) + intermediate_pts = (bv[idx].pts + bv[idx - 1].pts) / 2; + else + intermediate_pts = bv[idx].pts; + if (vc->deint_queue_pos & 1) { // first field + vo->next_pts = bv[idx].pts; + vo->next_pts2 = intermediate_pts; + } else { + vo->next_pts = intermediate_pts; + vo->next_pts2 = bv[idx - 1].pts; } - if (deint) - field = (top_field_first == i) ^ (deint > 1) ? - VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD: - VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; - output_surface = output_surfaces[surface_num]; - vdp_st = vdp_presentation_queue_block_until_surface_idle(vdp_flip_queue, - output_surface, - &dummy); - CHECK_ST_WARNING("Error when calling vdp_presentation_queue_block_until_surface_idle") - - vdp_st = vdp_video_mixer_render(video_mixer, VDP_INVALID_HANDLE, 0, - field, 2, deint_surfaces + 1, - deint_surfaces[0], - 1, &surface_render[vid_surface_num].surface, - &src_rect_vid, - output_surface, - NULL, &out_rect_vid, 0, NULL); - CHECK_ST_WARNING("Error when calling vdp_video_mixer_render") - push_deint_surface(surface_render[vid_surface_num].surface); + } + + video_to_output_surface(vo); +} + +static void add_new_video_surface(struct vo *vo, VdpVideoSurface surface, + struct mp_image *reserved_mpi, double pts) +{ + struct vdpctx *vc = vo->priv; + struct buffered_video_surface *bv = vc->buffered_video; + + if (reserved_mpi) + reserved_mpi->usage_count++; + if (bv[NUM_BUFFERED_VIDEO - 1].mpi) + bv[NUM_BUFFERED_VIDEO - 1].mpi->usage_count--; + + for (int i = NUM_BUFFERED_VIDEO - 1; i > 0; i--) + bv[i] = bv[i - 1]; + bv[0] = (struct buffered_video_surface){ + .mpi = reserved_mpi, + .surface = surface, + .pts = pts, + }; + + vc->deint_queue_pos += 2; + get_buffered_frame(vo, false); +} + +static void forget_frames(struct vo *vo) +{ + struct vdpctx *vc = vo->priv; + + vc->deint_queue_pos = -1001; + vc->dropped_frame = false; + for (int i = 0; i < NUM_BUFFERED_VIDEO; i++) { + struct buffered_video_surface *p = vc->buffered_video + i; + if (p->mpi) + p->mpi->usage_count--; + *p = (struct buffered_video_surface){ + .surface = VDP_INVALID_HANDLE, + }; } } -static void resize(void) +static void resize(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; int i; struct vo_rect src_rect; struct vo_rect dst_rect; struct vo_rect borders; - calc_src_dst_rects(vid_width, vid_height, &src_rect, &dst_rect, &borders, NULL); - out_rect_vid.x0 = dst_rect.left; - out_rect_vid.x1 = dst_rect.right; - out_rect_vid.y0 = dst_rect.top; - out_rect_vid.y1 = dst_rect.bottom; - src_rect_vid.x0 = src_rect.left; - src_rect_vid.x1 = src_rect.right; - src_rect_vid.y0 = flip ? src_rect.bottom : src_rect.top; - src_rect_vid.y1 = flip ? src_rect.top : src_rect.bottom; - border_x = borders.left; - border_y = borders.top; + calc_src_dst_rects(vo, vc->vid_width, vc->vid_height, &src_rect, &dst_rect, + &borders, NULL); + vc->out_rect_vid.x0 = dst_rect.left; + vc->out_rect_vid.x1 = dst_rect.right; + vc->out_rect_vid.y0 = dst_rect.top; + vc->out_rect_vid.y1 = dst_rect.bottom; + vc->src_rect_vid.x0 = src_rect.left; + vc->src_rect_vid.x1 = src_rect.right; + vc->src_rect_vid.y0 = vc->flip ? src_rect.bottom : src_rect.top; + vc->src_rect_vid.y1 = vc->flip ? src_rect.top : src_rect.bottom; + vc->border_x = borders.left; + vc->border_y = borders.top; #ifdef CONFIG_FREETYPE // adjust font size to display size force_load_font = 1; #endif vo_osd_changed(OSDTYPE_OSD); - if (output_surface_width < vo_dwidth || output_surface_height < vo_dheight) { - if (output_surface_width < vo_dwidth) { - output_surface_width += output_surface_width >> 1; - output_surface_width = FFMAX(output_surface_width, vo_dwidth); + bool had_frames = vc->num_shown_frames; + if (vc->output_surface_width < vo->dwidth + || vc->output_surface_height < vo->dheight) { + if (vc->output_surface_width < vo->dwidth) { + vc->output_surface_width += vc->output_surface_width >> 1; + vc->output_surface_width = FFMAX(vc->output_surface_width, + vo->dwidth); } - if (output_surface_height < vo_dheight) { - output_surface_height += output_surface_height >> 1; - output_surface_height = FFMAX(output_surface_height, vo_dheight); + if (vc->output_surface_height < vo->dheight) { + vc->output_surface_height += vc->output_surface_height >> 1; + vc->output_surface_height = FFMAX(vc->output_surface_height, + vo->dheight); } // Creation of output_surfaces for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) { - if (output_surfaces[i] != VDP_INVALID_HANDLE) - vdp_output_surface_destroy(output_surfaces[i]); - vdp_st = vdp_output_surface_create(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, - output_surface_width, output_surface_height, - &output_surfaces[i]); - CHECK_ST_WARNING("Error when calling vdp_output_surface_create") - mp_msg(MSGT_VO, MSGL_DBG2, "OUT CREATE: %u\n", output_surfaces[i]); + if (vc->output_surfaces[i] != VDP_INVALID_HANDLE) + vdp->output_surface_destroy(vc->output_surfaces[i]); + vdp_st = vdp->output_surface_create(vc->vdp_device, + VDP_RGBA_FORMAT_B8G8R8A8, + vc->output_surface_width, + vc->output_surface_height, + &vc->output_surfaces[i]); + CHECK_ST_WARNING("Error when calling vdp_output_surface_create"); + mp_msg(MSGT_VO, MSGL_DBG2, "OUT CREATE: %u\n", + vc->output_surfaces[i]); } + vc->num_shown_frames = 0; } - if (image_format == IMGFMT_BGRA) { - vdp_st = vdp_output_surface_render_output_surface(output_surfaces[surface_num], - NULL, VDP_INVALID_HANDLE, - NULL, NULL, NULL, - VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); - CHECK_ST_WARNING("Error when calling vdp_output_surface_render_output_surface") - vdp_st = vdp_output_surface_render_output_surface(output_surfaces[1 - surface_num], - NULL, VDP_INVALID_HANDLE, - NULL, NULL, NULL, - VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); - CHECK_ST_WARNING("Error when calling vdp_output_surface_render_output_surface") - } else - video_to_output_surface(); - if (visible_buf) - flip_page(); + if (vc->paused && had_frames) + if (video_to_output_surface(vo) >= 0) + flip_page_timed(vo, 0, -1); } static void preemption_callback(VdpDevice device, void *context) { - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Display preemption detected\n"); - is_preempted = 1; + struct vdpctx *vc = context; + vc->is_preempted = true; + vc->preemption_acked = false; } /* Initialize vdp_get_proc_address, called from preinit() */ -static int win_x11_init_vdpau_procs(void) +static int win_x11_init_vdpau_procs(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + struct vdpctx *vc = vo->priv; + talloc_free(vc->vdp); // In case this is reinitialization after preemption + struct vdp_functions *vdp = talloc_zero(vc, struct vdp_functions); + vc->vdp = vdp; VdpStatus vdp_st; struct vdp_function { const int id; - void *pointer; + int offset; }; const struct vdp_function *dsc; static const struct vdp_function vdp_func[] = { - {VDP_FUNC_ID_GET_ERROR_STRING, &vdp_get_error_string}, - {VDP_FUNC_ID_DEVICE_DESTROY, &vdp_device_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, &vdp_video_surface_create}, - {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, &vdp_video_surface_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, - &vdp_video_surface_put_bits_y_cb_cr}, - {VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE, - &vdp_output_surface_put_bits_native}, - {VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, &vdp_output_surface_create}, - {VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, &vdp_output_surface_destroy}, - {VDP_FUNC_ID_VIDEO_MIXER_CREATE, &vdp_video_mixer_create}, - {VDP_FUNC_ID_VIDEO_MIXER_DESTROY, &vdp_video_mixer_destroy}, - {VDP_FUNC_ID_VIDEO_MIXER_RENDER, &vdp_video_mixer_render}, - {VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES, - &vdp_video_mixer_set_feature_enables}, - {VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES, - &vdp_video_mixer_set_attribute_values}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY, - &vdp_presentation_queue_target_destroy}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE, &vdp_presentation_queue_create}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY, - &vdp_presentation_queue_destroy}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY, - &vdp_presentation_queue_display}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, - &vdp_presentation_queue_block_until_surface_idle}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, - &vdp_presentation_queue_target_create_x11}, - {VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, - &vdp_output_surface_render_output_surface}, - {VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED, - &vdp_output_surface_put_bits_indexed}, - {VDP_FUNC_ID_DECODER_CREATE, &vdp_decoder_create}, - {VDP_FUNC_ID_DECODER_RENDER, &vdp_decoder_render}, - {VDP_FUNC_ID_DECODER_DESTROY, &vdp_decoder_destroy}, - {VDP_FUNC_ID_BITMAP_SURFACE_CREATE, &vdp_bitmap_surface_create}, - {VDP_FUNC_ID_BITMAP_SURFACE_DESTROY, &vdp_bitmap_surface_destroy}, - {VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE, - &vdp_bitmap_surface_putbits_native}, - {VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE, - &vdp_output_surface_render_bitmap_surface}, - {VDP_FUNC_ID_GENERATE_CSC_MATRIX, &vdp_generate_csc_matrix}, - {VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, - &vdp_preemption_callback_register}, - {0, NULL} +#define VDP_FUNCTION(_, macro_name, mp_name) {macro_name, offsetof(struct vdp_functions, mp_name)}, +#include "vdpau_template.c" +#undef VDP_FUNCTION + {0, -1} }; - vdp_st = vdp_device_create_x11(mDisplay, mScreen, - &vdp_device, &vdp_get_proc_address); + vdp_st = vc->vdp_device_create(x11->display, x11->screen,&vc->vdp_device, + &vc->vdp_get_proc_address); if (vdp_st != VDP_STATUS_OK) { - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling vdp_device_create_x11: %i\n", vdp_st); + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling " + "vdp_device_create_x11: %i\n", vdp_st); return -1; } - vdp_get_error_string = NULL; - for (dsc = vdp_func; dsc->pointer; dsc++) { - vdp_st = vdp_get_proc_address(vdp_device, dsc->id, dsc->pointer); + vdp->get_error_string = NULL; + for (dsc = vdp_func; dsc->offset >= 0; dsc++) { + vdp_st = vc->vdp_get_proc_address(vc->vdp_device, dsc->id, + (void **)((char *)vdp + dsc->offset)); if (vdp_st != VDP_STATUS_OK) { - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling vdp_get_proc_address(function id %d): %s\n", - dsc->id, vdp_get_error_string ? vdp_get_error_string(vdp_st) : "?"); + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling " + "vdp_get_proc_address(function id %d): %s\n", dsc->id, + vdp->get_error_string ? vdp->get_error_string(vdp_st) : "?"); return -1; } } - vdp_st = vdp_preemption_callback_register(vdp_device, - preemption_callback, NULL); - CHECK_ST_ERROR("Error when calling vdp_preemption_callback_register") - + vdp_st = vdp->preemption_callback_register(vc->vdp_device, + preemption_callback, vc); return 0; } -/* Initialize vdpau_flip_queue, called from config() */ -static int win_x11_init_vdpau_flip_queue(void) +static int win_x11_init_vdpau_flip_queue(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + struct vo_x11_state *x11 = vo->x11; VdpStatus vdp_st; - vdp_st = vdp_presentation_queue_target_create_x11(vdp_device, vo_window, - &vdp_flip_target); - CHECK_ST_ERROR("Error when calling vdp_presentation_queue_target_create_x11") + if (vc->flip_target == VDP_INVALID_HANDLE) { + vdp_st = vdp->presentation_queue_target_create_x11(vc->vdp_device, + x11->window, + &vc->flip_target); + CHECK_ST_ERROR("Error when calling " + "vdp_presentation_queue_target_create_x11"); + } + + /* Emperically this seems to be the first call which fails when we + * try to reinit after preemption while the user is still switched + * from X to a virtual terminal (creating the vdp_device initially + * succeeds, as does creating the flip_target above). This is + * probably not guaranteed behavior, but we'll assume it as a simple + * way to reduce warnings while trying to recover from preemption. + */ + if (vc->flip_queue == VDP_INVALID_HANDLE) { + vdp_st = vdp->presentation_queue_create(vc->vdp_device, vc->flip_target, + &vc->flip_queue); + if (vc->is_preempted && vdp_st != VDP_STATUS_OK) { + mp_msg(MSGT_VO, MSGL_DBG2, "[vdpau] Failed to create flip queue " + "while preempted: %s\n", vdp->get_error_string(vdp_st)); + return -1; + } else + CHECK_ST_ERROR("Error when calling vdp_presentation_queue_create"); + } - vdp_st = vdp_presentation_queue_create(vdp_device, vdp_flip_target, - &vdp_flip_queue); - CHECK_ST_ERROR("Error when calling vdp_presentation_queue_create") + VdpTime vdp_time; + vdp_st = vdp->presentation_queue_get_time(vc->flip_queue, &vdp_time); + CHECK_ST_ERROR("Error when calling vdp_presentation_queue_get_time"); + vc->last_vdp_time = vdp_time; + vc->last_sync_update = GetTimer(); + + vc->vsync_interval = 1; + if (vc->user_fps > 0) { + vc->vsync_interval = 1e9 / vc->user_fps; + mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Assuming user-specified display " + "refresh rate of %.3f Hz.\n", vc->user_fps); + } else if (vc->user_fps == 0) { +#ifdef CONFIG_XF86VM + double fps = vo_vm_get_fps(vo); + if (!fps) + mp_msg(MSGT_VO, MSGL_WARN, "[vdpau] Failed to get display FPS\n"); + else { + vc->vsync_interval = 1e9 / fps; + // This is verbose, but I'm not yet sure how common wrong values are + mp_msg(MSGT_VO, MSGL_INFO, + "[vdpau] Got display refresh rate %.3f Hz.\n" + "[vdpau] If that value looks wrong give the " + "-vo vdpau:fps=X suboption manually.\n", fps); + } +#else + mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] This binary has been compiled " + "without XF86VidMode support.\n"); + mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Can't use vsync-aware timing " + "without manually provided -vo vdpau:fps=X suboption.\n"); +#endif + } else + mp_msg(MSGT_VO, MSGL_V, "[vdpau] framedrop/timing logic disabled by " + "user.\n"); return 0; } -static int update_csc_matrix(void) +static void update_csc_matrix(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; - VdpCSCMatrix matrix; - static const VdpVideoMixerAttribute attributes[] = {VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX}; - const void *attribute_values[] = {&matrix}; - static const VdpColorStandard vdp_colors[] = {0, VDP_COLOR_STANDARD_ITUR_BT_601, VDP_COLOR_STANDARD_ITUR_BT_709, VDP_COLOR_STANDARD_SMPTE_240M}; - static const char * const vdp_names[] = {NULL, "BT.601", "BT.709", "SMPTE-240M"}; - int csp = colorspace; - - if (!csp) - csp = vid_width >= 1280 || vid_height > 576 ? 2 : 1; + const VdpColorStandard vdp_colors[] = {VDP_COLOR_STANDARD_ITUR_BT_601, + VDP_COLOR_STANDARD_ITUR_BT_709, + VDP_COLOR_STANDARD_SMPTE_240M}; + char * const vdp_names[] = {"BT.601", "BT.709", "SMPTE-240M"}; + int csp = vc->colorspace; mp_msg(MSGT_VO, MSGL_V, "[vdpau] Updating CSC matrix for %s\n", vdp_names[csp]); - vdp_st = vdp_generate_csc_matrix(&procamp, vdp_colors[csp], &matrix); - CHECK_ST_WARNING("Error when generating CSC matrix") + VdpCSCMatrix matrix; + vdp_st = vdp->generate_csc_matrix(&vc->procamp, vdp_colors[csp], &matrix); + CHECK_ST_WARNING("Error when generating CSC matrix"); - vdp_st = vdp_video_mixer_set_attribute_values(video_mixer, 1, attributes, - attribute_values); - CHECK_ST_WARNING("Error when setting CSC matrix") - return VO_TRUE; + const VdpVideoMixerAttribute attributes[] = + {VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX}; + const void *attribute_values[] = {&matrix}; + vdp_st = vdp->video_mixer_set_attribute_values(vc->video_mixer, 1, + attributes, + attribute_values); + CHECK_ST_WARNING("Error when setting CSC matrix"); } -static int create_vdp_mixer(VdpChromaType vdp_chroma_type) +static int create_vdp_mixer(struct vo *vo, VdpChromaType vdp_chroma_type) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; #define VDP_NUM_MIXER_PARAMETER 3 #define MAX_NUM_FEATURES 6 int i; VdpStatus vdp_st; + + if (vc->video_mixer != VDP_INVALID_HANDLE) + return 0; + int feature_count = 0; VdpVideoMixerFeature features[MAX_NUM_FEATURES]; VdpBool feature_enables[MAX_NUM_FEATURES]; - static const VdpVideoMixerAttribute denoise_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL}; - const void * const denoise_value[] = {&denoise}; - static const VdpVideoMixerAttribute sharpen_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL}; - const void * const sharpen_value[] = {&sharpen}; - static const VdpVideoMixerAttribute skip_chroma_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE}; + static const VdpVideoMixerAttribute denoise_attrib[] = + {VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL}; + const void * const denoise_value[] = {&vc->denoise}; + static const VdpVideoMixerAttribute sharpen_attrib[] = + {VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL}; + const void * const sharpen_value[] = {&vc->sharpen}; + static const VdpVideoMixerAttribute skip_chroma_attrib[] = + {VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE}; const uint8_t skip_chroma_value = 1; const void * const skip_chroma_value_ptr[] = {&skip_chroma_value}; static const VdpVideoMixerParameter parameters[VDP_NUM_MIXER_PARAMETER] = { VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT, - VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE + VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE, }; const void *const parameter_values[VDP_NUM_MIXER_PARAMETER] = { - &vid_width, - &vid_height, - &vdp_chroma_type + &vc->vid_width, + &vc->vid_height, + &vdp_chroma_type, }; features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL; - if (deint == 4) - features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL; - if (pullup) + if (vc->deint == 4) + features[feature_count++] = + VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL; + if (vc->pullup) features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE; - if (denoise) + if (vc->denoise) features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION; - if (sharpen) + if (vc->sharpen) features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_SHARPNESS; - if (hqscaling) - features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 + (hqscaling - 1); + if (vc->hqscaling) { +#ifndef VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] MPlayer was compiled with (old?)" + "libvdpau headers with no support for requested hqscaling.\n"); +#else + VdpVideoMixerFeature hqscaling_feature = + VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 + vc->hqscaling-1; + VdpBool hqscaling_available; + vdp_st = vdp->video_mixer_query_feature_support(vc->vdp_device, + hqscaling_feature, + &hqscaling_available); + CHECK_ST_ERROR("Error when calling video_mixer_query_feature_support"); + if (hqscaling_available) + features[feature_count++] = hqscaling_feature; + else + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Your hardware or VDPAU " + "library does not support requested hqscaling.\n"); + } +#endif - vdp_st = vdp_video_mixer_create(vdp_device, feature_count, features, - VDP_NUM_MIXER_PARAMETER, - parameters, parameter_values, - &video_mixer); - CHECK_ST_ERROR("Error when calling vdp_video_mixer_create") + vdp_st = vdp->video_mixer_create(vc->vdp_device, feature_count, features, + VDP_NUM_MIXER_PARAMETER, + parameters, parameter_values, + &vc->video_mixer); + CHECK_ST_ERROR("Error when calling vdp_video_mixer_create"); for (i = 0; i < feature_count; i++) feature_enables[i] = VDP_TRUE; - if (deint < 3) + if (vc->deint < 3) feature_enables[0] = VDP_FALSE; if (feature_count) - vdp_video_mixer_set_feature_enables(video_mixer, feature_count, features, feature_enables); - if (denoise) - vdp_video_mixer_set_attribute_values(video_mixer, 1, denoise_attrib, denoise_value); - if (sharpen) - vdp_video_mixer_set_attribute_values(video_mixer, 1, sharpen_attrib, sharpen_value); - if (!chroma_deint) - vdp_video_mixer_set_attribute_values(video_mixer, 1, skip_chroma_attrib, skip_chroma_value_ptr); - - update_csc_matrix(); + vdp->video_mixer_set_feature_enables(vc->video_mixer, feature_count, + features, feature_enables); + if (vc->denoise) + vdp->video_mixer_set_attribute_values(vc->video_mixer, 1, + denoise_attrib, denoise_value); + if (vc->sharpen) + vdp->video_mixer_set_attribute_values(vc->video_mixer, 1, + sharpen_attrib, sharpen_value); + if (!vc->chroma_deint) + vdp->video_mixer_set_attribute_values(vc->video_mixer, 1, + skip_chroma_attrib, + skip_chroma_value_ptr); + + update_csc_matrix(vo); return 0; } // Free everything specific to a certain video file -static void free_video_specific(void) +static void free_video_specific(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; int i; VdpStatus vdp_st; - if (decoder != VDP_INVALID_HANDLE) - vdp_decoder_destroy(decoder); - decoder = VDP_INVALID_HANDLE; - decoder_max_refs = -1; + if (vc->decoder != VDP_INVALID_HANDLE) + vdp->decoder_destroy(vc->decoder); + vc->decoder = VDP_INVALID_HANDLE; + vc->decoder_max_refs = -1; - for (i = 0; i < 3; i++) - deint_surfaces[i] = VDP_INVALID_HANDLE; - - for (i = 0; i < 2; i++) - if (deint_mpi[i]) { - deint_mpi[i]->usage_count--; - deint_mpi[i] = NULL; - } + forget_frames(vo); for (i = 0; i < MAX_VIDEO_SURFACES; i++) { - if (surface_render[i].surface != VDP_INVALID_HANDLE) { - vdp_st = vdp_video_surface_destroy(surface_render[i].surface); - CHECK_ST_WARNING("Error when calling vdp_video_surface_destroy") + if (vc->surface_render[i].surface != VDP_INVALID_HANDLE) { + vdp_st = vdp->video_surface_destroy(vc->surface_render[i].surface); + CHECK_ST_WARNING("Error when calling vdp_video_surface_destroy"); } - surface_render[i].surface = VDP_INVALID_HANDLE; + vc->surface_render[i].surface = VDP_INVALID_HANDLE; } - if (video_mixer != VDP_INVALID_HANDLE) { - vdp_st = vdp_video_mixer_destroy(video_mixer); - CHECK_ST_WARNING("Error when calling vdp_video_mixer_destroy") + if (vc->video_mixer != VDP_INVALID_HANDLE) { + vdp_st = vdp->video_mixer_destroy(vc->video_mixer); + CHECK_ST_WARNING("Error when calling vdp_video_mixer_destroy"); } - video_mixer = VDP_INVALID_HANDLE; + vc->video_mixer = VDP_INVALID_HANDLE; } -static int create_vdp_decoder(uint32_t format, uint32_t width, uint32_t height, - int max_refs) +static int create_vdp_decoder(struct vo *vo, int max_refs) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; VdpDecoderProfile vdp_decoder_profile; - if (decoder != VDP_INVALID_HANDLE) - vdp_decoder_destroy(decoder); - switch (format) { - case IMGFMT_VDPAU_MPEG1: - vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG1; - break; - case IMGFMT_VDPAU_MPEG2: - vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG2_MAIN; - break; - case IMGFMT_VDPAU_H264: - vdp_decoder_profile = VDP_DECODER_PROFILE_H264_HIGH; - mp_msg(MSGT_VO, MSGL_V, "[vdpau] Creating H264 hardware decoder for %d reference frames.\n", max_refs); - break; - case IMGFMT_VDPAU_WMV3: - vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_MAIN; - break; - case IMGFMT_VDPAU_VC1: - vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; - break; - case IMGFMT_VDPAU_MPEG4: - vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; - break; - default: - goto err_out; + if (vc->decoder != VDP_INVALID_HANDLE) + vdp->decoder_destroy(vc->decoder); + switch (vc->image_format) { + case IMGFMT_VDPAU_MPEG1: + vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG1; + break; + case IMGFMT_VDPAU_MPEG2: + vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG2_MAIN; + break; + case IMGFMT_VDPAU_H264: + vdp_decoder_profile = VDP_DECODER_PROFILE_H264_HIGH; + mp_msg(MSGT_VO, MSGL_V, "[vdpau] Creating H264 hardware decoder " + "for %d reference frames.\n", max_refs); + break; + case IMGFMT_VDPAU_WMV3: + vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_MAIN; + break; + case IMGFMT_VDPAU_VC1: + vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; + break; +#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP + case IMGFMT_VDPAU_MPEG4: + vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; + break; +#endif } - vdp_st = vdp_decoder_create(vdp_device, vdp_decoder_profile, - width, height, max_refs, &decoder); + vdp_st = vdp->decoder_create(vc->vdp_device, vdp_decoder_profile, + vc->vid_width, vc->vid_height, max_refs, + &vc->decoder); CHECK_ST_WARNING("Failed creating VDPAU decoder"); if (vdp_st != VDP_STATUS_OK) { -err_out: - decoder = VDP_INVALID_HANDLE; - decoder_max_refs = 0; + vc->decoder = VDP_INVALID_HANDLE; + vc->decoder_max_refs = 0; return 0; } - decoder_max_refs = max_refs; + vc->decoder_max_refs = max_refs; return 1; } -static void mark_vdpau_objects_uninitialized(void) +static int initialize_vdpau_objects(struct vo *vo) { - int i; + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + VdpStatus vdp_st; - decoder = VDP_INVALID_HANDLE; - for (i = 0; i < MAX_VIDEO_SURFACES; i++) - surface_render[i].surface = VDP_INVALID_HANDLE; - for (i = 0; i < 3; i++) { - deint_surfaces[i] = VDP_INVALID_HANDLE; - if (i < 2 && deint_mpi[i]) - deint_mpi[i]->usage_count--; - deint_mpi[i] = NULL; + vc->vdp_chroma_type = VDP_CHROMA_TYPE_420; + switch (vc->image_format) { + case IMGFMT_YV12: + case IMGFMT_I420: + case IMGFMT_IYUV: + vc->vdp_pixel_format = VDP_YCBCR_FORMAT_YV12; + break; + case IMGFMT_NV12: + vc->vdp_pixel_format = VDP_YCBCR_FORMAT_NV12; + break; + case IMGFMT_YUY2: + vc->vdp_pixel_format = VDP_YCBCR_FORMAT_YUYV; + vc->vdp_chroma_type = VDP_CHROMA_TYPE_422; + break; + case IMGFMT_UYVY: + vc->vdp_pixel_format = VDP_YCBCR_FORMAT_UYVY; + vc->vdp_chroma_type = VDP_CHROMA_TYPE_422; } - video_mixer = VDP_INVALID_HANDLE; - vdp_flip_queue = VDP_INVALID_HANDLE; - vdp_flip_target = VDP_INVALID_HANDLE; - for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) - output_surfaces[i] = VDP_INVALID_HANDLE; - vdp_device = VDP_INVALID_HANDLE; - for (i = 0; i < eosd_surface_count; i++) - eosd_surfaces[i].surface = VDP_INVALID_HANDLE; - output_surface_width = output_surface_height = -1; - eosd_render_count = 0; - visible_buf = 0; + if (win_x11_init_vdpau_flip_queue(vo) < 0) + return -1; + + if (create_vdp_mixer(vo, vc->vdp_chroma_type) < 0) + return -1; + + vdp_st = vdp-> + bitmap_surface_query_capabilities(vc->vdp_device, + VDP_RGBA_FORMAT_A8, + &(VdpBool){0}, + &vc->eosd_surface.max_width, + &vc->eosd_surface.max_height); + CHECK_ST_WARNING("Query to get max EOSD surface size failed"); + forget_frames(vo); + resize(vo); + return 0; } -static int handle_preemption(void) +static void mark_vdpau_objects_uninitialized(struct vo *vo) { - if (!is_preempted) + struct vdpctx *vc = vo->priv; + + vc->decoder = VDP_INVALID_HANDLE; + for (int i = 0; i < MAX_VIDEO_SURFACES; i++) + vc->surface_render[i].surface = VDP_INVALID_HANDLE; + forget_frames(vo); + vc->video_mixer = VDP_INVALID_HANDLE; + vc->flip_queue = VDP_INVALID_HANDLE; + vc->flip_target = VDP_INVALID_HANDLE; + for (int i = 0; i <= NUM_OUTPUT_SURFACES; i++) + vc->output_surfaces[i] = VDP_INVALID_HANDLE; + vc->vdp_device = VDP_INVALID_HANDLE; + vc->eosd_surface = (struct eosd_bitmap_surface){ + .surface = VDP_INVALID_HANDLE, + }; + vc->output_surface_width = vc->output_surface_height = -1; + vc->eosd_render_count = 0; + vc->num_shown_frames = 0; +} + +static int handle_preemption(struct vo *vo) +{ + struct vdpctx *vc = vo->priv; + + if (!vc->is_preempted) return 0; - is_preempted = 0; - mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Attempting to recover from preemption.\n"); - mark_vdpau_objects_uninitialized(); - if (win_x11_init_vdpau_procs() < 0 || - win_x11_init_vdpau_flip_queue() < 0 || - create_vdp_mixer(vdp_chroma_type) < 0) { - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Recovering from preemption failed\n"); - is_preempted = 1; + if (!vc->preemption_acked) + mark_vdpau_objects_uninitialized(vo); + vc->preemption_acked = true; + if (!vc->preemption_user_notified) { + mp_tmsg(MSGT_VO, MSGL_ERR, "[vdpau] Got display preemption notice! " + "Will attempt to recover.\n"); + vc->preemption_user_notified = true; + } + /* Trying to initialize seems to be quite slow, so only try once a + * second to avoid using 100% CPU. */ + if (vc->last_preemption_retry_fail + && GetTimerMS() - vc->last_preemption_retry_fail < 1000) + return -1; + if (win_x11_init_vdpau_procs(vo) < 0 || initialize_vdpau_objects(vo) < 0) { + vc->last_preemption_retry_fail = GetTimerMS() | 1; return -1; } - resize(); - mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Recovered from display preemption.\n"); + vc->last_preemption_retry_fail = 0; + vc->is_preempted = false; + vc->preemption_user_notified = false; + mp_tmsg(MSGT_VO, MSGL_INFO, "[vdpau] Recovered from display preemption.\n"); return 1; } @@ -644,10 +838,12 @@ static int handle_preemption(void) * connect to X server, create and map window, initialize all * VDPAU objects, create different surfaces etc. */ -static int config(uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t flags, char *title, - uint32_t format) +static int 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) { + struct vdpctx *vc = vo->priv; + struct vo_x11_state *x11 = vo->x11; XVisualInfo vinfo; XSetWindowAttributes xswa; XWindowAttributes attribs; @@ -657,142 +853,121 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; #endif - flip = flags & VOFLAG_FLIPPING; - - image_format = format; - vid_width = width; - vid_height = height; - free_video_specific(); - if (IMGFMT_IS_VDPAU(image_format) - && !create_vdp_decoder(image_format, vid_width, vid_height, 2)) - return -1; - int_pause = 0; - visible_buf = 0; + if (handle_preemption(vo) < 0) + return -1; -#ifdef CONFIG_GUI - if (use_gui) - guiGetEvent(guiSetShVideo, 0); // the GUI will set up / resize our window + vc->flip = flags & VOFLAG_FLIPPING; + vc->image_format = format; + vc->vid_width = width; + vc->vid_height = height; + if (vc->user_colorspace == 0) + vc->colorspace = width >= 1280 || height > 576 ? 1 : 0; else -#endif - { + vc->colorspace = vc->user_colorspace - 1; + free_video_specific(vo); + if (IMGFMT_IS_VDPAU(vc->image_format) && !create_vdp_decoder(vo, 2)) + return -1; + #ifdef CONFIG_XF86VM - if (vm) - vo_vm_switch(); - else + if (vm) { + vo_vm_switch(vo); + vc->mode_switched = true; + } #endif - XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &attribs); - depth = attribs.depth; - if (depth != 15 && depth != 16 && depth != 24 && depth != 32) - depth = 24; - XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); - - xswa.background_pixel = 0; - xswa.border_pixel = 0; - /* Do not use CWBackPixel: It leads to VDPAU errors after - aspect ratio changes. */ - xswamask = CWBorderPixel; - - vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, d_width, d_height, - flags, CopyFromParent, "vdpau", title); - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); + XGetWindowAttributes(x11->display, DefaultRootWindow(x11->display), + &attribs); + depth = attribs.depth; + if (depth != 15 && depth != 16 && depth != 24 && depth != 32) + depth = 24; + XMatchVisualInfo(x11->display, x11->screen, depth, TrueColor, &vinfo); + + xswa.background_pixel = 0; + xswa.border_pixel = 0; + /* Do not use CWBackPixel: It leads to VDPAU errors after + * aspect ratio changes. */ + xswamask = CWBorderPixel; + + vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, d_width, d_height, + flags, CopyFromParent, "vdpau", title); + XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa); #ifdef CONFIG_XF86VM - if (vm) { - /* Grab the mouse pointer in our window */ - if (vo_grabpointer) - XGrabPointer(mDisplay, vo_window, True, 0, - GrabModeAsync, GrabModeAsync, - vo_window, None, CurrentTime); - XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); - } -#endif + if (vm) { + /* Grab the mouse pointer in our window */ + if (vo_grabpointer) + XGrabPointer(x11->display, x11->window, True, 0, + GrabModeAsync, GrabModeAsync, + x11->window, None, CurrentTime); + XSetInputFocus(x11->display, x11->window, RevertToNone, CurrentTime); } +#endif if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1; - /* -----VDPAU related code here -------- */ - if (vdp_flip_queue == VDP_INVALID_HANDLE && win_x11_init_vdpau_flip_queue()) + if (initialize_vdpau_objects(vo) < 0) return -1; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - switch (image_format) { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - vdp_pixel_format = VDP_YCBCR_FORMAT_YV12; - break; - case IMGFMT_NV12: - vdp_pixel_format = VDP_YCBCR_FORMAT_NV12; - break; - case IMGFMT_YUY2: - vdp_pixel_format = VDP_YCBCR_FORMAT_YUYV; - vdp_chroma_type = VDP_CHROMA_TYPE_422; - break; - case IMGFMT_UYVY: - vdp_pixel_format = VDP_YCBCR_FORMAT_UYVY; - vdp_chroma_type = VDP_CHROMA_TYPE_422; - } - if (create_vdp_mixer(vdp_chroma_type)) - return -1; - - surface_num = 0; - vid_surface_num = -1; - resize(); - return 0; } -static void check_events(void) +static void check_events(struct vo *vo) { - int e = vo_x11_check_events(mDisplay); + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; - if (handle_preemption() < 0) + if (handle_preemption(vo) < 0) return; - if (e & VO_EVENT_RESIZE) - resize(); + int e = vo_x11_check_events(vo); - if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause) { + if (e & VO_EVENT_RESIZE) + resize(vo); + else if (e & VO_EVENT_EXPOSE && vc->paused) { /* did we already draw a buffer */ - if (visible_buf) { + if (vc->num_shown_frames) { /* redraw the last visible buffer */ VdpStatus vdp_st; - vdp_st = vdp_presentation_queue_display(vdp_flip_queue, - output_surfaces[surface_num], - vo_dwidth, vo_dheight, - 0); - CHECK_ST_WARNING("Error when calling vdp_presentation_queue_display") + int last_surface = (vc->surface_num + NUM_OUTPUT_SURFACES - 1) + % NUM_OUTPUT_SURFACES; + vdp_st = vdp->presentation_queue_display(vc->flip_queue, + vc->output_surfaces[last_surface], + vo->dwidth, vo->dheight, 0); + CHECK_ST_WARNING("Error when calling " + "vdp_presentation_queue_display"); } } } -static void draw_osd_I8A8(int x0,int y0, int w,int h, unsigned char *src, - unsigned char *srca, int stride) +static void draw_osd_I8A8(void *ctx, int x0, int y0, int w, int h, + unsigned char *src, unsigned char *srca, int stride) { - VdpOutputSurface output_surface = output_surfaces[surface_num]; + struct vo *vo = ctx; + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + VdpOutputSurface output_surface = vc->output_surfaces[vc->surface_num]; VdpStatus vdp_st; - int i, j; + int i; int pitch; int index_data_size_required; VdpRect output_indexed_rect_vid; - VdpOutputSurfaceRenderBlendState blend_state; if (!w || !h) return; index_data_size_required = 2*w*h; - if (index_data_size < index_data_size_required) { - index_data = realloc(index_data, index_data_size_required); - index_data_size = index_data_size_required; + if (vc->index_data_size < index_data_size_required) { + vc->index_data = talloc_realloc_size(vc, vc->index_data, + index_data_size_required); + vc->index_data_size = index_data_size_required; } // index_data creation, component order - I, A, I, A, ..... for (i = 0; i < h; i++) - for (j = 0; j < w; j++) { - index_data[i*2*w + j*2] = src [i*stride + j]; - index_data[i*2*w + j*2 + 1] = -srca[i*stride + j]; + for (int j = 0; j < w; j++) { + vc->index_data[i*2*w + j*2] = src [i*stride+j]; + vc->index_data[i*2*w + j*2 + 1] = -srca[i*stride+j]; } output_indexed_rect_vid.x0 = x0; @@ -803,283 +978,510 @@ static void draw_osd_I8A8(int x0,int y0, int w,int h, unsigned char *src, pitch = w*2; // write source_data to osd_surface. - vdp_st = vdp_output_surface_put_bits_indexed(osd_surface, - VDP_INDEXED_FORMAT_I8A8, - (const void *const*)&index_data, - &pitch, - &output_indexed_rect_vid, - VDP_COLOR_TABLE_FORMAT_B8G8R8X8, - (void *)palette); - CHECK_ST_WARNING("Error when calling vdp_output_surface_put_bits_indexed") - - blend_state.struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION; - blend_state.blend_factor_source_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE; - blend_state.blend_factor_source_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE; - blend_state.blend_factor_destination_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - blend_state.blend_factor_destination_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - blend_state.blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD; - blend_state.blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD; - - vdp_st = vdp_output_surface_render_output_surface(output_surface, - &output_indexed_rect_vid, - osd_surface, - &output_indexed_rect_vid, - NULL, - &blend_state, - VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); - CHECK_ST_WARNING("Error when calling vdp_output_surface_render_output_surface") + vdp_st = vdp-> + output_surface_put_bits_indexed(osd_surface, VDP_INDEXED_FORMAT_I8A8, + (const void *const*)&vc->index_data, + &pitch, &output_indexed_rect_vid, + VDP_COLOR_TABLE_FORMAT_B8G8R8X8, + (void *)vc->palette); + CHECK_ST_WARNING("Error when calling vdp_output_surface_put_bits_indexed"); + + VdpOutputSurfaceRenderBlendState blend_state = { + .struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION, + .blend_factor_source_color = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, + .blend_factor_source_alpha = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, + .blend_factor_destination_color = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .blend_factor_destination_alpha = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, + .blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, + }; + + vdp_st = vdp-> + output_surface_render_output_surface(output_surface, + &output_indexed_rect_vid, + osd_surface, + &output_indexed_rect_vid, + NULL, &blend_state, + VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); + CHECK_ST_WARNING("Error when calling " + "vdp_output_surface_render_output_surface"); } -static void draw_eosd(void) +static void draw_eosd(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; - VdpOutputSurface output_surface = output_surfaces[surface_num]; - VdpOutputSurfaceRenderBlendState blend_state; + VdpOutputSurface output_surface = vc->output_surfaces[vc->surface_num]; int i; - blend_state.struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION; - blend_state.blend_factor_source_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA; - blend_state.blend_factor_source_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE; - blend_state.blend_factor_destination_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - blend_state.blend_factor_destination_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA; - blend_state.blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD; - blend_state.blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD; - - for (i = 0; i < eosd_render_count; i++) { - vdp_st = vdp_output_surface_render_bitmap_surface( - output_surface, &eosd_targets[i].dest, - eosd_targets[i].surface, &eosd_targets[i].source, - &eosd_targets[i].color, &blend_state, - VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); - CHECK_ST_WARNING("EOSD: Error when rendering") + if (handle_preemption(vo) < 0) + return; + + VdpOutputSurfaceRenderBlendState blend_state = { + .struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION, + .blend_factor_source_color = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA, + .blend_factor_source_alpha = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, + .blend_factor_destination_color = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .blend_factor_destination_alpha = + VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA, + .blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, + .blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, + }; + + for (i = 0; i < vc->eosd_render_count; i++) { + vdp_st = vdp-> + output_surface_render_bitmap_surface(output_surface, + &vc->eosd_targets[i].dest, + vc->eosd_surface.surface, + &vc->eosd_targets[i].source, + &vc->eosd_targets[i].color, + &blend_state, + VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); + CHECK_ST_WARNING("EOSD: Error when rendering"); + } +} + +#define HEIGHT_SORT_BITS 4 +static int size_index(struct eosd_target *r) +{ + unsigned int h = r->source.y1; + int n = av_log2_16bit(h); + return (n << HEIGHT_SORT_BITS) + + (- 1 - (h << HEIGHT_SORT_BITS >> n) & (1 << HEIGHT_SORT_BITS) - 1); +} + +/* Pack the given rectangles into an area of size w * h. + * The size of each rectangle is read from .source.x1/.source.y1. + * The height of each rectangle must be at least 1 and less than 65536. + * The .source rectangle is then set corresponding to the packed position. + * 'scratch' must point to work memory for num_rects+16 ints. + * Return 0 on success, -1 if the rectangles did not fit in w*h. + * + * The rectangles are placed in rows in order approximately sorted by + * height (the approximate sorting is simpler than a full one would be, + * and allows the algorithm to work in linear time). Additionally, to + * reduce wasted space when there are a few tall rectangles, empty + * lower-right parts of rows are filled recursively when the size of + * rectangles in the row drops past a power-of-two threshold. So if a + * row starts with rectangles of size 3x50, 10x40 and 5x20 then the + * free rectangle with corners (13, 20)-(w, 50) is filled recursively. + */ +static int pack_rectangles(struct eosd_target *rects, int num_rects, + int w, int h, int *scratch) +{ + int bins[16 << HEIGHT_SORT_BITS]; + int sizes[16 << HEIGHT_SORT_BITS] = {}; + for (int i = 0; i < num_rects; i++) + sizes[size_index(rects + i)]++; + int idx = 0; + for (int i = 0; i < 16 << HEIGHT_SORT_BITS; i += 1 << HEIGHT_SORT_BITS) { + for (int j = 0; j < 1 << HEIGHT_SORT_BITS; j++) { + bins[i + j] = idx; + idx += sizes[i + j]; + } + scratch[idx++] = -1; } + for (int i = 0; i < num_rects; i++) + scratch[bins[size_index(rects + i)]++] = i; + for (int i = 0; i < 16; i++) + bins[i] = bins[i << HEIGHT_SORT_BITS] - sizes[i << HEIGHT_SORT_BITS]; + struct { + int size, x, bottom; + } stack[16] = {{15, 0, h}}, s = {}; + int stackpos = 1; + int y; + while (stackpos) { + y = s.bottom; + s = stack[--stackpos]; + s.size++; + while (s.size--) { + int maxy = -1; + int obj; + while ((obj = scratch[bins[s.size]]) >= 0) { + int bottom = y + rects[obj].source.y1; + if (bottom > s.bottom) + break; + int right = s.x + rects[obj].source.x1; + if (right > w) + break; + bins[s.size]++; + rects[obj].source.x0 = s.x; + rects[obj].source.x1 += s.x; + rects[obj].source.y0 = y; + rects[obj].source.y1 += y; + num_rects--; + if (maxy <= 0) + stack[stackpos++] = s; + s.x = right; + maxy = FFMAX(maxy, bottom); + } + if (maxy > 0) + s.bottom = maxy; + } + } + return num_rects ? -1 : 0; } -static void generate_eosd(mp_eosd_images_t *imgs) +static void generate_eosd(struct vo *vo, mp_eosd_images_t *imgs) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; - VdpRect destRect; - int j, found; - ass_image_t *img = imgs->imgs; - ass_image_t *i; + int i; + ASS_Image *img = imgs->imgs; + ASS_Image *p; + struct eosd_bitmap_surface *sfc = &vc->eosd_surface; + bool need_upload = false; - // Nothing changed, no need to redraw if (imgs->changed == 0) - return; - eosd_render_count = 0; - // There's nothing to render! + return; // Nothing changed, no need to redraw + + vc->eosd_render_count = 0; + if (!img) - return; + return; // There's nothing to render! if (imgs->changed == 1) goto eosd_skip_upload; - for (j = 0; j < eosd_surface_count; j++) - eosd_surfaces[j].in_use = 0; - - for (i = img; i; i = i->next) { - // Try to reuse a suitable surface - found = -1; - for (j = 0; j < eosd_surface_count; j++) { - if (eosd_surfaces[j].surface != VDP_INVALID_HANDLE && !eosd_surfaces[j].in_use && - eosd_surfaces[j].w >= i->w && eosd_surfaces[j].h >= i->h) { - found = j; - break; - } - } - // None found, allocate a new surface - if (found < 0) { - for (j = 0; j < eosd_surface_count; j++) { - if (!eosd_surfaces[j].in_use) { - if (eosd_surfaces[j].surface != VDP_INVALID_HANDLE) - vdp_bitmap_surface_destroy(eosd_surfaces[j].surface); - found = j; - break; - } - } + need_upload = true; + bool reallocate = false; + while (1) { + for (p = img, i = 0; p; p = p->next) { + if (p->w <= 0 || p->h <= 0) + continue; // Allocate new space for surface/target arrays - if (found < 0) { - j = found = eosd_surface_count; - eosd_surface_count = eosd_surface_count ? eosd_surface_count*2 : EOSD_SURFACES_INITIAL; - eosd_surfaces = realloc(eosd_surfaces, eosd_surface_count * sizeof(*eosd_surfaces)); - eosd_targets = realloc(eosd_targets, eosd_surface_count * sizeof(*eosd_targets)); - for (j = found; j < eosd_surface_count; j++) { - eosd_surfaces[j].surface = VDP_INVALID_HANDLE; - eosd_surfaces[j].in_use = 0; - } + if (i >= vc->eosd_targets_size) { + vc->eosd_targets_size = FFMAX(vc->eosd_targets_size * 2, 512); + vc->eosd_targets = + talloc_realloc_size(vc, vc->eosd_targets, + vc->eosd_targets_size + * sizeof(*vc->eosd_targets)); + vc->eosd_scratch = + talloc_realloc_size(vc, vc->eosd_scratch, + (vc->eosd_targets_size + 16) + * sizeof(*vc->eosd_scratch)); } - vdp_st = vdp_bitmap_surface_create(vdp_device, VDP_RGBA_FORMAT_A8, - i->w, i->h, VDP_TRUE, &eosd_surfaces[found].surface); - CHECK_ST_WARNING("EOSD: error when creating surface") - eosd_surfaces[found].w = i->w; - eosd_surfaces[found].h = i->h; + vc->eosd_targets[i].source.x1 = p->w; + vc->eosd_targets[i].source.y1 = p->h; + i++; } - eosd_surfaces[found].in_use = 1; - eosd_targets[eosd_render_count].surface = eosd_surfaces[found].surface; - destRect.x0 = 0; - destRect.y0 = 0; - destRect.x1 = i->w; - destRect.y1 = i->h; - vdp_st = vdp_bitmap_surface_putbits_native(eosd_targets[eosd_render_count].surface, - (const void *) &i->bitmap, &i->stride, &destRect); - CHECK_ST_WARNING("EOSD: putbits failed") - eosd_render_count++; + if (pack_rectangles(vc->eosd_targets, i, sfc->w, sfc->h, + vc->eosd_scratch) >= 0) + break; + int w = FFMIN(FFMAX(sfc->w * 2, EOSD_SURFACE_INITIAL_SIZE), + sfc->max_width); + int h = FFMIN(FFMAX(sfc->h * 2, EOSD_SURFACE_INITIAL_SIZE), + sfc->max_height); + if (w == sfc->w && h == sfc->h) { + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] EOSD bitmaps do not fit on " + "a surface with the maximum supported size\n"); + return; + } else { + sfc->w = w; + sfc->h = h; + } + reallocate = true; + } + if (reallocate) { + if (sfc->surface != VDP_INVALID_HANDLE) + vdp->bitmap_surface_destroy(sfc->surface); + mp_msg(MSGT_VO, MSGL_V, "[vdpau] Allocating a %dx%d surface for " + "EOSD bitmaps.\n", sfc->w, sfc->h); + vdp_st = vdp->bitmap_surface_create(vc->vdp_device, VDP_RGBA_FORMAT_A8, + sfc->w, sfc->h, true, + &sfc->surface); + if (vdp_st != VDP_STATUS_OK) + sfc->surface = VDP_INVALID_HANDLE; + CHECK_ST_WARNING("EOSD: error when creating surface"); } eosd_skip_upload: - eosd_render_count = 0; - for (i = img; i; i = i->next) { + if (sfc->surface == VDP_INVALID_HANDLE) + return; + for (p = img; p; p = p->next) { + if (p->w <= 0 || p->h <= 0) + continue; + struct eosd_target *target = &vc->eosd_targets[vc->eosd_render_count]; + if (need_upload) { + vdp_st = vdp-> + bitmap_surface_put_bits_native(sfc->surface, + (const void *) &p->bitmap, + &p->stride, &target->source); + CHECK_ST_WARNING("EOSD: putbits failed"); + } // Render dest, color, etc. - eosd_targets[eosd_render_count].color.alpha = 1.0 - ((i->color >> 0) & 0xff) / 255.0; - eosd_targets[eosd_render_count].color.blue = ((i->color >> 8) & 0xff) / 255.0; - eosd_targets[eosd_render_count].color.green = ((i->color >> 16) & 0xff) / 255.0; - eosd_targets[eosd_render_count].color.red = ((i->color >> 24) & 0xff) / 255.0; - eosd_targets[eosd_render_count].dest.x0 = i->dst_x; - eosd_targets[eosd_render_count].dest.y0 = i->dst_y; - eosd_targets[eosd_render_count].dest.x1 = i->w + i->dst_x; - eosd_targets[eosd_render_count].dest.y1 = i->h + i->dst_y; - eosd_targets[eosd_render_count].source.x0 = 0; - eosd_targets[eosd_render_count].source.y0 = 0; - eosd_targets[eosd_render_count].source.x1 = i->w; - eosd_targets[eosd_render_count].source.y1 = i->h; - eosd_render_count++; + target->color.alpha = 1.0 - ((p->color >> 0) & 0xff) / 255.0; + target->color.blue = ((p->color >> 8) & 0xff) / 255.0; + target->color.green = ((p->color >> 16) & 0xff) / 255.0; + target->color.red = ((p->color >> 24) & 0xff) / 255.0; + target->dest.x0 = p->dst_x; + target->dest.y0 = p->dst_y; + target->dest.x1 = p->w + p->dst_x; + target->dest.y1 = p->h + p->dst_y; + vc->eosd_render_count++; } } -static void draw_osd(void) +static void draw_osd(struct vo *vo, struct osd_state *osd) { + struct vdpctx *vc = vo->priv; mp_msg(MSGT_VO, MSGL_DBG2, "DRAW_OSD\n"); - if (handle_preemption() < 0) + if (handle_preemption(vo) < 0) return; - vo_draw_text_ext(vo_dwidth, vo_dheight, border_x, border_y, border_x, border_y, - vid_width, vid_height, draw_osd_I8A8); + osd_draw_text_ext(osd, vo->dwidth, vo->dheight, vc->border_x, vc->border_y, + vc->border_x, vc->border_y, vc->vid_width, + vc->vid_height, draw_osd_I8A8, vo); } -static void flip_page(void) +static void wait_for_previous_frame(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; - mp_msg(MSGT_VO, MSGL_DBG2, "\nFLIP_PAGE VID:%u -> OUT:%u\n", - surface_render[vid_surface_num].surface, output_surfaces[surface_num]); - if (handle_preemption() < 0) + if (vc->num_shown_frames < 2) return; - vdp_st = vdp_presentation_queue_display(vdp_flip_queue, output_surfaces[surface_num], - vo_dwidth, vo_dheight, - 0); - CHECK_ST_WARNING("Error when calling vdp_presentation_queue_display") + VdpTime vtime; + VdpOutputSurface visible_s, prev_s; + int base = vc->surface_num + NUM_OUTPUT_SURFACES; + visible_s = vc->output_surfaces[(base - 1) % NUM_OUTPUT_SURFACES]; + prev_s = vc->output_surfaces[(base - 2) % NUM_OUTPUT_SURFACES]; + vdp_st = vdp->presentation_queue_block_until_surface_idle(vc->flip_queue, + prev_s, &vtime); + CHECK_ST_WARNING("Error calling " + "presentation_queue_block_until_surface_idle"); + VdpPresentationQueueStatus status; + vdp_st = vdp->presentation_queue_query_surface_status(vc->flip_queue, + visible_s, + &status, &vtime); + CHECK_ST_WARNING("Error calling presentation_queue_query_surface_status"); + vc->recent_vsync_time = vtime; +} - surface_num = (surface_num + 1) % NUM_OUTPUT_SURFACES; - visible_buf = 1; +static inline uint64_t prev_vs2(struct vdpctx *vc, uint64_t ts, int shift) +{ + uint64_t offset = ts - vc->recent_vsync_time; + // Fix negative values for 1<<shift vsyncs before vc->recent_vsync_time + offset += (uint64_t)vc->vsync_interval << shift; + offset %= vc->vsync_interval; + return ts - offset; } -static int draw_slice(uint8_t *image[], int stride[], int w, int h, - int x, int y) +static void flip_page_timed(struct vo *vo, unsigned int pts_us, int duration) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; - struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0]; - int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2; + uint32_t vsync_interval = vc->vsync_interval; - if (handle_preemption() < 0) + if (handle_preemption(vo) < 0) + return; + + if (duration > INT_MAX / 1000) + duration = -1; + else + duration *= 1000; + + if (vc->user_fps < 0) + duration = -1; // Make sure drop logic is disabled + + uint64_t now = sync_vdptime(vo); + uint64_t pts = pts_us ? convert_to_vdptime(vo, pts_us) : now; + uint64_t ideal_pts = pts; + uint64_t npts = duration >= 0 ? pts + duration : UINT64_MAX; + +#define PREV_VS2(ts, shift) prev_vs2(vc, ts, shift) + // Only gives accurate results for ts >= vc->recent_vsync_time +#define PREV_VSYNC(ts) PREV_VS2(ts, 0) + + /* We hope to be here at least one vsync before the frame should be shown. + * If we are running late then don't drop the frame unless there is + * already one queued for the next vsync; even if we _hope_ to show the + * next frame soon enough to mean this one should be dropped we might + * not make the target time in reality. Without this check we could drop + * every frame, freezing the display completely if video lags behind. + */ + if (now > PREV_VSYNC(FFMAX(pts, + vc->last_queue_time + vsync_interval))) + npts = UINT64_MAX; + + /* Allow flipping a frame at a vsync if its presentation time is a + * bit after that vsync and the change makes the flip time delta + * from previous frame better match the target timestamp delta. + * This avoids instability with frame timestamps falling near vsyncs. + * For example if the frame timestamps were (with vsyncs at + * integer values) 0.01, 1.99, 4.01, 5.99, 8.01, ... then + * straightforward timing at next vsync would flip the frames at + * 1, 2, 5, 6, 9; this changes it to 1, 2, 4, 6, 8 and so on with + * regular 2-vsync intervals. + * + * Also allow moving the frame forward if it looks like we dropped + * the previous frame incorrectly (now that we know better after + * having final exact timestamp information for this frame) and + * there would unnecessarily be a vsync without a frame change. + */ + uint64_t vsync = PREV_VSYNC(pts); + if (pts < vsync + vsync_interval / 4 + && (vsync - PREV_VS2(vc->last_queue_time, 16) + > pts - vc->last_ideal_time + vsync_interval / 2 + || vc->dropped_frame && vsync > vc->dropped_time)) + pts -= vsync_interval / 2; + + vc->dropped_frame = true; // changed at end if false + vc->dropped_time = ideal_pts; + + pts = FFMAX(pts, vc->last_queue_time + vsync_interval); + pts = FFMAX(pts, now); + if (npts < PREV_VSYNC(pts) + vsync_interval) + return; + + /* At least on my NVIDIA 9500GT with driver versions 185.18.36 and 190.42 + * trying to queue two unshown frames simultaneously caused bad behavior + * (high CPU use in _other_ VDPAU functions called later). Avoiding + * longer queues also makes things simpler. So currently we always + * try to keep exactly one frame queued for the future, queuing the + * current frame immediately after the previous one is shown. + */ + wait_for_previous_frame(vo); + + now = sync_vdptime(vo); + pts = FFMAX(pts, now); + vsync = PREV_VSYNC(pts); + if (npts < vsync + vsync_interval) + return; + pts = vsync + (vsync_interval >> 2); + vdp_st = + vdp->presentation_queue_display(vc->flip_queue, + vc->output_surfaces[vc->surface_num], + vo->dwidth, vo->dheight, pts); + CHECK_ST_WARNING("Error when calling vdp_presentation_queue_display"); + + vc->last_queue_time = pts; + vc->last_ideal_time = ideal_pts; + vc->dropped_frame = false; + vc->surface_num = (vc->surface_num + 1) % NUM_OUTPUT_SURFACES; + vc->num_shown_frames = FFMIN(vc->num_shown_frames + 1, 1000); +} + +static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w, + int h, int x, int y) +{ + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + VdpStatus vdp_st; + + if (handle_preemption(vo) < 0) return VO_TRUE; - if (!IMGFMT_IS_VDPAU(image_format)) + struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0]; + int max_refs = vc->image_format == IMGFMT_VDPAU_H264 ? + rndr->info.h264.num_ref_frames : 2; + if (!IMGFMT_IS_VDPAU(vc->image_format)) return VO_FALSE; - if ((decoder == VDP_INVALID_HANDLE || decoder_max_refs < max_refs) - && !create_vdp_decoder(image_format, vid_width, vid_height, max_refs)) + if ((vc->decoder == VDP_INVALID_HANDLE || vc->decoder_max_refs < max_refs) + && !create_vdp_decoder(vo, max_refs)) return VO_FALSE; - vdp_st = vdp_decoder_render(decoder, rndr->surface, (void *)&rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers); + vdp_st = vdp->decoder_render(vc->decoder, rndr->surface, + (void *)&rndr->info, + rndr->bitstream_buffers_used, + rndr->bitstream_buffers); CHECK_ST_WARNING("Failed VDPAU decoder rendering"); return VO_TRUE; } -static int draw_frame(uint8_t *src[]) +static struct vdpau_render_state *get_surface(struct vo *vo, int number) { - return VO_ERROR; -} + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; -static struct vdpau_render_state *get_surface(int number) -{ if (number > MAX_VIDEO_SURFACES) return NULL; - if (surface_render[number].surface == VDP_INVALID_HANDLE) { + if (vc->surface_render[number].surface == VDP_INVALID_HANDLE + && !vc->is_preempted) { VdpStatus vdp_st; - vdp_st = vdp_video_surface_create(vdp_device, vdp_chroma_type, - vid_width, vid_height, - &surface_render[number].surface); - CHECK_ST_WARNING("Error when calling vdp_video_surface_create") - if (vdp_st != VDP_STATUS_OK) - return NULL; + vdp_st = vdp->video_surface_create(vc->vdp_device, vc->vdp_chroma_type, + vc->vid_width, vc->vid_height, + &vc->surface_render[number].surface); + CHECK_ST_WARNING("Error when calling vdp_video_surface_create"); } - mp_msg(MSGT_VO, MSGL_DBG2, "VID CREATE: %u\n", surface_render[number].surface); - return &surface_render[number]; + mp_msg(MSGT_VO, MSGL_DBG2, "VID CREATE: %u\n", + vc->surface_render[number].surface); + return &vc->surface_render[number]; } -static uint32_t draw_image(mp_image_t *mpi) +static void draw_image(struct vo *vo, mp_image_t *mpi, double pts) { - if (IMGFMT_IS_VDPAU(image_format)) { - struct vdpau_render_state *rndr = mpi->priv; - vid_surface_num = rndr - surface_render; - if (deint_buffer_past_frames) { - mpi->usage_count++; - if (deint_mpi[1]) - deint_mpi[1]->usage_count--; - deint_mpi[1] = deint_mpi[0]; - deint_mpi[0] = mpi; - } - } else if (image_format == IMGFMT_BGRA) { - VdpStatus vdp_st; - VdpRect r = {0, 0, vid_width, vid_height}; - vdp_st = vdp_output_surface_put_bits_native(output_surfaces[2], - (void const*const*)mpi->planes, - mpi->stride, &r); - CHECK_ST_ERROR("Error when calling vdp_output_surface_put_bits_native") - vdp_st = vdp_output_surface_render_output_surface(output_surfaces[surface_num], - &out_rect_vid, - output_surfaces[2], - &src_rect_vid, NULL, NULL, - VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); - CHECK_ST_ERROR("Error when calling vdp_output_surface_render_output_surface") + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + struct mp_image *reserved_mpi = NULL; + struct vdpau_render_state *rndr; + + if (vc->is_preempted) { + vo->frame_loaded = true; + return; + } + + if (IMGFMT_IS_VDPAU(vc->image_format)) { + rndr = mpi->priv; + reserved_mpi = mpi; } else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) { VdpStatus vdp_st; void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]}; - struct vdpau_render_state *rndr = get_surface(deint_counter); - deint_counter = (deint_counter + 1) % 3; - vid_surface_num = rndr - surface_render; - if (image_format == IMGFMT_NV12) + rndr = get_surface(vo, vc->deint_counter); + vc->deint_counter = (vc->deint_counter + 1) % NUM_BUFFERED_VIDEO; + if (vc->image_format == IMGFMT_NV12) destdata[1] = destdata[2]; - vdp_st = vdp_video_surface_put_bits_y_cb_cr(rndr->surface, - vdp_pixel_format, - (const void *const*)destdata, - mpi->stride); // pitch - CHECK_ST_ERROR("Error when calling vdp_video_surface_put_bits_y_cb_cr") - } + vdp_st = + vdp->video_surface_put_bits_y_cb_cr(rndr->surface, + vc->vdp_pixel_format, + (const void *const*)destdata, + mpi->stride); // pitch + CHECK_ST_WARNING("Error when calling " + "vdp_video_surface_put_bits_y_cb_cr"); + } else + // We don't support slice callbacks so this shouldn't occur - + // I think the flags test above in pointless, but I'm adding + // this instead of removing it just in case. + abort(); if (mpi->fields & MP_IMGFIELD_ORDERED) - top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST); + vc->top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST); else - top_field_first = 1; + vc->top_field_first = 1; - video_to_output_surface(); - return VO_TRUE; + add_new_video_surface(vo, rndr->surface, mpi, pts); + + return; } -static uint32_t get_image(mp_image_t *mpi) +static uint32_t get_image(struct vo *vo, mp_image_t *mpi) { + struct vdpctx *vc = vo->priv; struct vdpau_render_state *rndr; // no dr for non-decoding for now - if (!IMGFMT_IS_VDPAU(image_format)) + if (!IMGFMT_IS_VDPAU(vc->image_format)) return VO_FALSE; if (mpi->type != MP_IMGTYPE_NUMBERED) return VO_FALSE; - rndr = get_surface(mpi->number); + rndr = get_surface(vo, mpi->number); if (!rndr) { - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] no surfaces available in get_image\n"); + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] no surfaces available in " + "get_image\n"); // TODO: this probably breaks things forever, provide a dummy buffer? return VO_FALSE; } @@ -1095,332 +1497,326 @@ static uint32_t get_image(mp_image_t *mpi) static int query_format(uint32_t format) { - int default_flags = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_EOSD | VFCAP_EOSD_UNSCALED | VFCAP_FLIP; + int default_flags = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW + | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_EOSD + | VFCAP_EOSD_UNSCALED | VFCAP_FLIP; switch (format) { - case IMGFMT_BGRA: - if (force_mixer) - return 0; - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_NV12: - case IMGFMT_YUY2: - case IMGFMT_UYVY: - return default_flags | VOCAP_NOSLICES; - case IMGFMT_VDPAU_MPEG1: - case IMGFMT_VDPAU_MPEG2: - case IMGFMT_VDPAU_H264: - case IMGFMT_VDPAU_WMV3: - case IMGFMT_VDPAU_VC1: - case IMGFMT_VDPAU_MPEG4: - if (create_vdp_decoder(format, 48, 48, 2)) + case IMGFMT_YV12: + case IMGFMT_I420: + case IMGFMT_IYUV: + case IMGFMT_NV12: + case IMGFMT_YUY2: + case IMGFMT_UYVY: + return default_flags | VOCAP_NOSLICES; + case IMGFMT_VDPAU_MPEG1: + case IMGFMT_VDPAU_MPEG2: + case IMGFMT_VDPAU_H264: + case IMGFMT_VDPAU_WMV3: + case IMGFMT_VDPAU_VC1: + case IMGFMT_VDPAU_MPEG4: return default_flags; } return 0; } -static void DestroyVdpauObjects(void) +static void destroy_vdpau_objects(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + int i; VdpStatus vdp_st; - free_video_specific(); + free_video_specific(vo); - vdp_st = vdp_presentation_queue_destroy(vdp_flip_queue); - CHECK_ST_WARNING("Error when calling vdp_presentation_queue_destroy") + if (vc->flip_queue != VDP_INVALID_HANDLE) { + vdp_st = vdp->presentation_queue_destroy(vc->flip_queue); + CHECK_ST_WARNING("Error when calling vdp_presentation_queue_destroy"); + } - vdp_st = vdp_presentation_queue_target_destroy(vdp_flip_target); - CHECK_ST_WARNING("Error when calling vdp_presentation_queue_target_destroy") + if (vc->flip_target != VDP_INVALID_HANDLE) { + vdp_st = vdp->presentation_queue_target_destroy(vc->flip_target); + CHECK_ST_WARNING("Error when calling " + "vdp_presentation_queue_target_destroy"); + } for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) { - vdp_st = vdp_output_surface_destroy(output_surfaces[i]); - output_surfaces[i] = VDP_INVALID_HANDLE; - CHECK_ST_WARNING("Error when calling vdp_output_surface_destroy") + if (vc->output_surfaces[i] == VDP_INVALID_HANDLE) + continue; + vdp_st = vdp->output_surface_destroy(vc->output_surfaces[i]); + CHECK_ST_WARNING("Error when calling vdp_output_surface_destroy"); } - for (i = 0; i<eosd_surface_count; i++) { - if (eosd_surfaces[i].surface != VDP_INVALID_HANDLE) { - vdp_st = vdp_bitmap_surface_destroy(eosd_surfaces[i].surface); - CHECK_ST_WARNING("Error when calling vdp_bitmap_surface_destroy") - } - eosd_surfaces[i].surface = VDP_INVALID_HANDLE; + if (vc->eosd_surface.surface != VDP_INVALID_HANDLE) { + vdp_st = vdp->bitmap_surface_destroy(vc->eosd_surface.surface); + CHECK_ST_WARNING("Error when calling vdp_bitmap_surface_destroy"); } - vdp_st = vdp_device_destroy(vdp_device); - CHECK_ST_WARNING("Error when calling vdp_device_destroy") + vdp_st = vdp->device_destroy(vc->vdp_device); + CHECK_ST_WARNING("Error when calling vdp_device_destroy"); } -static void uninit(void) +static void uninit(struct vo *vo) { - int i; - - if (!vo_config_count) - return; - visible_buf = 0; - - for (i = 0; i < MAX_VIDEO_SURFACES; i++) { - // Allocated in ff_vdpau_add_data_chunk() - av_freep(&surface_render[i].bitstream_buffers); - surface_render[i].bitstream_buffers_allocated = 0; - } + struct vdpctx *vc = vo->priv; /* Destroy all vdpau objects */ - DestroyVdpauObjects(); - - free(index_data); - index_data = NULL; - - free(eosd_surfaces); - eosd_surfaces = NULL; - free(eosd_targets); - eosd_targets = NULL; + destroy_vdpau_objects(vo); #ifdef CONFIG_XF86VM - vo_vm_close(); + if (vc->mode_switched) + vo_vm_close(vo); #endif - vo_x11_uninit(); -} + vo_x11_uninit(vo); -static const opt_t subopts[] = { - {"deint", OPT_ARG_INT, &deint, (opt_test_f)int_non_neg}, - {"chroma-deint", OPT_ARG_BOOL, &chroma_deint, NULL}, - {"pullup", OPT_ARG_BOOL, &pullup, NULL}, - {"denoise", OPT_ARG_FLOAT, &denoise, NULL}, - {"sharpen", OPT_ARG_FLOAT, &sharpen, NULL}, - {"colorspace", OPT_ARG_INT, &colorspace, NULL}, - {"force-mixer", OPT_ARG_BOOL, &force_mixer, NULL}, - {"hqscaling", OPT_ARG_INT, &hqscaling, (opt_test_f)int_non_neg}, - {NULL} -}; + // Free bitstream buffers allocated by FFmpeg + for (int i = 0; i < MAX_VIDEO_SURFACES; i++) + av_freep(&vc->surface_render[i].bitstream_buffers); + + dlclose(vc->vdpau_lib_handle); +} -static const char help_msg[] = - "\n-vo vdpau command line help:\n" - "Example: mplayer -vo vdpau:deint=2\n" - "\nOptions:\n" - " deint (all modes > 0 respect -field-dominance)\n" - " 0: no deinterlacing\n" - " 1: only show first field\n" - " 2: bob deinterlacing\n" - " 3: temporal deinterlacing (resource-hungry)\n" - " 4: temporal-spatial deinterlacing (very resource-hungry)\n" - " chroma-deint\n" - " Operate on luma and chroma when using temporal deinterlacing (default)\n" - " Use nochroma-deint to speed up temporal deinterlacing\n" - " pullup\n" - " Try to apply inverse-telecine (needs temporal deinterlacing)\n" - " denoise\n" - " Apply denoising, argument is strength from 0.0 to 1.0\n" - " sharpen\n" - " Apply sharpening or softening, argument is strength from -1.0 to 1.0\n" - " colorspace\n" - " 0: guess based on video resolution\n" - " 1: ITU-R BT.601 (default)\n" - " 2: ITU-R BT.709\n" - " 3: SMPTE-240M\n" - " hqscaling\n" - " 0: default VDPAU scaler\n" - " 1-9: high quality VDPAU scaler (needs capable hardware)\n" - " force-mixer\n" - " Use the VDPAU mixer (default)\n" - " Use noforce-mixer to allow BGRA output (disables all above options)\n" - ; - -static int preinit(const char *arg) +static int preinit(struct vo *vo, const char *arg) { int i; - deint = 0; - deint_type = 3; - deint_counter = 0; - deint_buffer_past_frames = 0; - deint_mpi[0] = deint_mpi[1] = NULL; - chroma_deint = 1; - pullup = 0; - denoise = 0; - sharpen = 0; - colorspace = 1; - force_mixer = 1; - hqscaling = 0; + struct vdpctx *vc = talloc_zero(vo, struct vdpctx); + vo->priv = vc; + + // Mark everything as invalid first so uninit() can tell what has been + // allocated + mark_vdpau_objects_uninitialized(vo); + + vc->deint_type = 3; + vc->chroma_deint = 1; + vc->user_colorspace = 1; + const opt_t subopts[] = { + {"deint", OPT_ARG_INT, &vc->deint, (opt_test_f)int_non_neg}, + {"chroma-deint", OPT_ARG_BOOL, &vc->chroma_deint, NULL}, + {"pullup", OPT_ARG_BOOL, &vc->pullup, NULL}, + {"denoise", OPT_ARG_FLOAT, &vc->denoise, NULL}, + {"sharpen", OPT_ARG_FLOAT, &vc->sharpen, NULL}, + {"colorspace", OPT_ARG_INT, &vc->user_colorspace, NULL}, + {"hqscaling", OPT_ARG_INT, &vc->hqscaling, NULL}, + {"fps", OPT_ARG_FLOAT, &vc->user_fps, NULL}, + {NULL} + }; if (subopt_parse(arg, subopts) != 0) { - mp_msg(MSGT_VO, MSGL_FATAL, help_msg); + mp_msg(MSGT_VO, MSGL_FATAL, "[vdpau] Could not parse suboptions.\n"); return -1; } - if (deint) - deint_type = deint; - if (deint > 1) - deint_buffer_past_frames = 1; - if (colorspace < 0 || colorspace > 3) { - mp_msg(MSGT_VO, MSGL_WARN, "[vdpau] Invalid color space specified, " - "using BT.601\n"); - colorspace = 1; + if (vc->hqscaling < 0 || vc->hqscaling > 9) { + mp_msg(MSGT_VO, MSGL_FATAL, "[vdpau] Invalid value for suboption " + "hqscaling\n"); + return -1; } - - if (!vo_init() || win_x11_init_vdpau_procs()) + if (vc->deint) + vc->deint_type = vc->deint; + + char *vdpaulibrary = "libvdpau.so.1"; + char *vdpau_device_create = "vdp_device_create_x11"; + vc->vdpau_lib_handle = dlopen(vdpaulibrary, RTLD_LAZY); + if (!vc->vdpau_lib_handle) { + mp_msg(MSGT_VO, MSGL_ERR, + "[vdpau] Could not open dynamic library %s\n", vdpaulibrary); return -1; + } + vc->vdp_device_create = dlsym(vc->vdpau_lib_handle, vdpau_device_create); + if (!vc->vdp_device_create) { + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Could not find function %s in %s\n", + vdpau_device_create, vdpaulibrary); + dlclose(vc->vdpau_lib_handle); + return -1; + } + if (!vo_init(vo)) { + dlclose(vc->vdpau_lib_handle); + return -1; + } - decoder = VDP_INVALID_HANDLE; - for (i = 0; i < MAX_VIDEO_SURFACES; i++) - surface_render[i].surface = VDP_INVALID_HANDLE; - video_mixer = VDP_INVALID_HANDLE; - for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) - output_surfaces[i] = VDP_INVALID_HANDLE; - vdp_flip_queue = VDP_INVALID_HANDLE; - output_surface_width = output_surface_height = -1; + // After this calling uninit() should work to free resources + + if (win_x11_init_vdpau_procs(vo) < 0) { + if (vc->vdp->device_destroy) + vc->vdp->device_destroy(vc->vdp_device); + vo_x11_uninit(vo); + dlclose(vc->vdpau_lib_handle); + return -1; + } // full grayscale palette. for (i = 0; i < PALETTE_SIZE; ++i) - palette[i] = (i << 16) | (i << 8) | i; - index_data = NULL; - index_data_size = 0; - - eosd_surface_count = eosd_render_count = 0; - eosd_surfaces = NULL; - eosd_targets = NULL; + vc->palette[i] = (i << 16) | (i << 8) | i; - procamp.struct_version = VDP_PROCAMP_VERSION; - procamp.brightness = 0.0; - procamp.contrast = 1.0; - procamp.saturation = 1.0; - procamp.hue = 0.0; + vc->procamp.struct_version = VDP_PROCAMP_VERSION; + vc->procamp.brightness = 0.0; + vc->procamp.contrast = 1.0; + vc->procamp.saturation = 1.0; + vc->procamp.hue = 0.0; return 0; } -static int get_equalizer(char *name, int *value) +static int get_equalizer(struct vo *vo, const char *name, int *value) { + struct vdpctx *vc = vo->priv; + if (!strcasecmp(name, "brightness")) - *value = procamp.brightness * 100; + *value = vc->procamp.brightness * 100; else if (!strcasecmp(name, "contrast")) - *value = (procamp.contrast-1.0) * 100; + *value = (vc->procamp.contrast - 1.0) * 100; else if (!strcasecmp(name, "saturation")) - *value = (procamp.saturation-1.0) * 100; + *value = (vc->procamp.saturation - 1.0) * 100; else if (!strcasecmp(name, "hue")) - *value = procamp.hue * 100 / M_PI; + *value = vc->procamp.hue * 100 / M_PI; else return VO_NOTIMPL; return VO_TRUE; } -static int set_equalizer(char *name, int value) +static int set_equalizer(struct vo *vo, const char *name, int value) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + if (!strcasecmp(name, "brightness")) - procamp.brightness = value / 100.0; + vc->procamp.brightness = value / 100.0; else if (!strcasecmp(name, "contrast")) - procamp.contrast = value / 100.0 + 1.0; + vc->procamp.contrast = value / 100.0 + 1.0; else if (!strcasecmp(name, "saturation")) - procamp.saturation = value / 100.0 + 1.0; + vc->procamp.saturation = value / 100.0 + 1.0; else if (!strcasecmp(name, "hue")) - procamp.hue = value / 100.0 * M_PI; + vc->procamp.hue = value / 100.0 * M_PI; else return VO_NOTIMPL; - return update_csc_matrix(); + update_csc_matrix(vo); + return true; } -static int control(uint32_t request, void *data, ...) +static int control(struct vo *vo, uint32_t request, void *data) { - if (handle_preemption() < 0) - return VO_FALSE; + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + + handle_preemption(vo); switch (request) { case VOCTRL_GET_DEINTERLACE: - *(int*)data = deint; + *(int*)data = vc->deint; return VO_TRUE; case VOCTRL_SET_DEINTERLACE: - if (image_format == IMGFMT_BGRA) - return VO_NOTIMPL; - deint = *(int*)data; - if (deint) - deint = deint_type; - if (deint_type > 2) { + vc->deint = *(int*)data; + if (vc->deint) + vc->deint = vc->deint_type; + if (vc->deint_type > 2) { VdpStatus vdp_st; VdpVideoMixerFeature features[1] = - {deint_type == 3 ? + {vc->deint_type == 3 ? VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL : VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL}; - VdpBool feature_enables[1] = {deint ? VDP_TRUE : VDP_FALSE}; - vdp_st = vdp_video_mixer_set_feature_enables(video_mixer, 1, - features, - feature_enables); - CHECK_ST_WARNING("Error changing deinterlacing settings") - deint_buffer_past_frames = 1; + VdpBool feature_enables[1] = {vc->deint ? VDP_TRUE : VDP_FALSE}; + vdp_st = vdp->video_mixer_set_feature_enables(vc->video_mixer, + 1, features, + feature_enables); + CHECK_ST_WARNING("Error changing deinterlacing settings"); } return VO_TRUE; case VOCTRL_PAUSE: - return int_pause = 1; + if (vc->dropped_frame) + flip_page_timed(vo, 0, -1); + return (vc->paused = true); case VOCTRL_RESUME: - return int_pause = 0; + return (vc->paused = false); case VOCTRL_QUERY_FORMAT: return query_format(*(uint32_t *)data); case VOCTRL_GET_IMAGE: - return get_image(data); + return get_image(vo, data); case VOCTRL_DRAW_IMAGE: - return draw_image(data); - case VOCTRL_GUISUPPORT: - return VO_TRUE; + abort(); // draw_image() should get called directly case VOCTRL_BORDER: - vo_x11_border(); - resize(); + vo_x11_border(vo); + resize(vo); return VO_TRUE; case VOCTRL_FULLSCREEN: - vo_x11_fullscreen(); - resize(); + vo_x11_fullscreen(vo); + resize(vo); return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: - resize(); + resize(vo); return VO_TRUE; case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - if (image_format == IMGFMT_BGRA) - return VO_NOTIMPL; - - va_start(ap, data); - value = va_arg(ap, int); - - va_end(ap); - return set_equalizer(data, value); + struct voctrl_set_equalizer_args *args = data; + return set_equalizer(vo, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - - va_end(ap); - return get_equalizer(data, value); + struct voctrl_get_equalizer_args *args = data; + return get_equalizer(vo, args->name, args->valueptr); } + case VOCTRL_SET_YUV_COLORSPACE: + vc->colorspace = *(int *)data % 3; + update_csc_matrix(vo); + return true; + case VOCTRL_GET_YUV_COLORSPACE: + *(int *)data = vc->colorspace; + return true; case VOCTRL_ONTOP: - vo_x11_ontop(); + vo_x11_ontop(vo); return VO_TRUE; case VOCTRL_UPDATE_SCREENINFO: - update_xinerama_info(); + update_xinerama_info(vo); return VO_TRUE; case VOCTRL_DRAW_EOSD: if (!data) return VO_FALSE; - generate_eosd(data); - draw_eosd(); + generate_eosd(vo, data); + draw_eosd(vo); return VO_TRUE; case VOCTRL_GET_EOSD_RES: { mp_eosd_res_t *r = data; r->mt = r->mb = r->ml = r->mr = 0; if (vo_fs) { - r->w = vo_screenwidth; - r->h = vo_screenheight; - r->ml = r->mr = border_x; - r->mt = r->mb = border_y; + r->w = vo->opts->vo_screenwidth; + r->h = vo->opts->vo_screenheight; + r->ml = r->mr = vc->border_x; + r->mt = r->mb = vc->border_y; } else { - r->w = vo_dwidth; - r->h = vo_dheight; + r->w = vo->dwidth; + r->h = vo->dheight; } return VO_TRUE; } + case VOCTRL_REDRAW_OSD: + video_to_output_surface(vo); + draw_eosd(vo); + draw_osd(vo, data); + flip_page_timed(vo, 0, -1); + return true; + case VOCTRL_RESET: + forget_frames(vo); + return true; } return VO_NOTIMPL; } -/* @} */ +const struct vo_driver video_out_vdpau = { + .is_new = true, + .buffer_frames = true, + .info = &(const struct vo_info_s){ + "VDPAU with X11", + "vdpau", + "Rajib Mahapatra <rmahapatra@nvidia.com> and others", + "" + }, + .preinit = preinit, + .config = config, + .control = control, + .draw_image = draw_image, + .get_buffered_frame = get_buffered_frame, + .draw_slice = draw_slice, + .draw_osd = draw_osd, + .flip_page_timed = flip_page_timed, + .check_events = check_events, + .uninit = uninit, +}; diff --git a/libvo/vo_vesa.c b/libvo/vo_vesa.c index 5f58f5ddeb..1ab3cdd184 100644 --- a/libvo/vo_vesa.c +++ b/libvo/vo_vesa.c @@ -194,7 +194,7 @@ static inline void vbeSwitchBank(unsigned long offset) show_err: vesa_term(); PRINT_VBE_ERR("vbeSetWindow",err); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_FatalErrorOccurred); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] Fatal error occurred! Can't continue.\n"); abort(); } win.low = new_offset * gran; @@ -396,7 +396,7 @@ static void flip_page(void) { vesa_term(); PRINT_VBE_ERR("vbeSetDisplayStart",err); - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_FatalErrorOccurred); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] Fatal error occurred! Can't continue.\n"); abort(); } multi_idx = multi_idx ? 0 : 1; @@ -462,7 +462,7 @@ static uint32_t parseSubDevice(const char *sd) else if(memcmp(sd,"vidix",5) == 0) vidix_name = &sd[5]; /* vidix_name will be valid within init() */ #endif - else { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_UnknownSubdevice, sd); return 0xFFFFFFFFUL; } + else { mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] unknown subdevice: '%s'.\n", sd); return 0xFFFFFFFFUL; } return flags; } @@ -550,7 +550,7 @@ unsigned fillMultiBuffer( unsigned long vsize, unsigned nbuffs ) total = min(total,nbuffs); while(i < total) { multi_buff[i++] = offset; offset += screen_size; } if(!i) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_YouHaveTooLittleVideoMemory, screen_size, vsize); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] You have too little video memory for this mode:\n[VO_VESA] Required: %08lX present: %08lX.\n", screen_size, vsize); return i; } @@ -569,7 +569,7 @@ static int set_refresh(unsigned x, unsigned y, unsigned mode,struct VesaCRTCInfo monitor_dotclock = str2range(monitor_dotclock_str); if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_YouHaveToSpecifyTheCapabilitiesOfTheMonitor); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] You have to specify the capabilities of the monitor. Not changing refresh rate.\n"); return 0; } @@ -606,7 +606,7 @@ static int set_refresh(unsigned x, unsigned y, unsigned mode,struct VesaCRTCInfo if (!in_range(monitor_vfreq,crtc_pass->RefreshRate/100)|| !in_range(monitor_hfreq,H_freq*1000)) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_UnableToFitTheMode); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] The mode does not fit the monitor limits. Not changing refresh rate.\n"); return 0; } @@ -637,13 +637,13 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin fs_mode = 0; if(subdev_flags == 0xFFFFFFFEUL) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_DetectedInternalFatalError); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Detected internal fatal error: init is called before preinit.\n"); return -1; } if(subdev_flags == 0xFFFFFFFFUL) return -1; if(flags & VOFLAG_FLIPPING) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_SwitchFlipIsNotSupported); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] The -flip option is not supported.\n"); } if(flags & VOFLAG_SWSCALE) use_scaler = 1; if(flags & VOFLAG_FULLSCREEN) @@ -656,30 +656,32 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin if(!vib_set && (err=vbeGetControllerInfo(&vib)) != VBE_OK) { PRINT_VBE_ERR("vbeGetControllerInfo",err); - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_PossibleReasonNoVbe2BiosFound); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Possible reason: No VBE2 BIOS found.\n"); return -1; } vib_set = 1; /* Print general info here */ - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_FoundVesaVbeBiosVersion, + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Found VESA VBE BIOS Version %x.%x Revision: %x.\n", (int)(vib.VESAVersion >> 8) & 0xff, (int)(vib.VESAVersion & 0xff), (int)(vib.OemSoftwareRev & 0xffff)); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_VideoMemory,vib.TotalMemory*64); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_Capabilites + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Video memory: %u Kb.\n",vib.TotalMemory*64); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] VESA Capabilities: %s %s %s %s %s.\n" ,vib.Capabilities & VBE_DAC_8BIT ? "8-bit DAC," : "6-bit DAC," ,vib.Capabilities & VBE_NONVGA_CRTC ? "non-VGA CRTC,":"VGA CRTC," ,vib.Capabilities & VBE_SNOWED_RAMDAC ? "snowed RAMDAC,":"normal RAMDAC," ,vib.Capabilities & VBE_STEREOSCOPIC ? "stereoscopic,":"no stereoscopic," ,vib.Capabilities & VBE_STEREO_EVC ? "Stereo EVC":"no stereo"); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_BelowWillBePrintedOemInfo); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_YouShouldSee5OemRelatedLines); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_OemInfo,vib.OemStringPtr); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_OemRevision,vib.OemSoftwareRev); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_OemVendor,vib.OemVendorNamePtr); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_OemProductName,vib.OemProductNamePtr); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_OemProductRev,vib.OemProductRevPtr); - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_Hint); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] !!! OEM info will be printed below !!!\n"); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] You should see 5 OEM related lines below; If not, you've broken vm86.\n"); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] OEM info: %s.\n",vib.OemStringPtr); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] OEM Revision: %x.\n",vib.OemSoftwareRev); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] OEM vendor: %s.\n",vib.OemVendorNamePtr); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] OEM Product Name: %s.\n",vib.OemProductNamePtr); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] OEM Product Rev: %s.\n",vib.OemProductRevPtr); + mp_tmsg(MSGT_VO,MSGL_INFO, + "[VO_VESA] Hint: For working TV-Out you should have plugged in the TV connector\n"\ + "[VO_VESA] before booting since VESA BIOS initializes itself only during POST.\n"); /* Find best mode here */ num_modes = 0; mode_ptr = vib.VideoModePtr; @@ -795,7 +797,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin return -1; } dstBpp = video_mode_info.BitsPerPixel; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingVesaMode + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Using VESA mode (%u) = %x [%ux%u@%u]\n" ,best_mode_idx,video_mode,video_mode_info.XResolution ,video_mode_info.YResolution,dstBpp); if(subdev_flags & SUBDEV_NODGA) video_mode_info.PhysBasePtr = 0; @@ -830,7 +832,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin sws = sws_getContextFromCmdLine(srcW,srcH,srcFourcc,dstW,dstH,dstFourcc); if(!sws) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CantInitializeSwscaler); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] Can't initialize software scaler.\n"); return -1; } else if( mp_msg_test(MSGT_VO,MSGL_V) ) { @@ -850,7 +852,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin vsize = vib.TotalMemory*64*1024; lfb = vbeMapVideoBuffer(video_mode_info.PhysBasePtr,vsize); if(lfb == NULL) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CantUseDga); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] Can't use DGA. Force bank switching mode. :(\n"); else { video_base = win.ptr = lfb; @@ -858,7 +860,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin win.high = vsize; win.idx = -1; /* HAS_DGA() is on */ video_mode |= VESA_MODE_USE_LINEAR; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingDga + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Using DGA (physical resources: %08lXh, %08lXh)" ,video_mode_info.PhysBasePtr ,vsize); if( mp_msg_test(MSGT_VO,MSGL_V) ) { @@ -866,30 +868,30 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin printf("\n"); if(!(multi_size = fillMultiBuffer(vsize,2))) return -1; if(vo_doublebuffering && multi_size < 2) - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CantUseDoubleBuffering); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] Can't use double buffering: not enough video memory.\n"); } } if(win.idx == -2) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantFindNeitherDga); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Can find neither DGA nor relocatable window frame.\n"); return -1; } if(!HAS_DGA()) { if(subdev_flags & SUBDEV_FORCEDGA) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_YouveForcedDga); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] You've forced DGA. Exiting\n"); return -1; } if(!(win_seg = win.idx == 0 ? video_mode_info.WinASegment:video_mode_info.WinBSegment)) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantFindValidWindowAddress); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Can't find valid window address.\n"); return -1; } win.ptr = PhysToVirtSO(win_seg,0); win.low = 0L; win.high= video_mode_info.WinSize*1024; - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingBankSwitchingMode + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Using bank switching mode (physical resources: %08lXh, %08lXh).\n" ,(unsigned long)win.ptr,(unsigned long)win.high); } if(video_mode_info.XResolution > dstW) @@ -919,7 +921,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin { if(!(dga_buffer = memalign(64,video_mode_info.XResolution*video_mode_info.YResolution*dstBpp))) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantAllocateTemporaryBuffer); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Can't allocate temporary buffer.\n"); return -1; } if( mp_msg_test(MSGT_VO,MSGL_V) ) { @@ -955,10 +957,10 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin if (neomagic_tvout) { err = vbeSetTV(video_mode,neomagic_tvnorm); if (err!=0x4f) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_SorryUnsupportedMode); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_VESA] Sorry, unsupported mode -- try -x 640 -zoom.\n"); } else { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_OhYouReallyHavePictureOnTv); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Oh you really have a picture on the TV!\n"); } } /* Now we are in video mode!!!*/ @@ -972,11 +974,11 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin { if(vlvo_init(width,height,x_offset,y_offset,dstW,dstH,format,dstBpp) != 0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantInitialozeLinuxVideoOverlay); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Can't initialize Linux Video Overlay.\n"); vesa_term(); return -1; } - else mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingVideoOverlay,lvo_name); + else mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Using video overlay: %s.\n",lvo_name); lvo_opened = 1; } #ifdef CONFIG_VIDIX @@ -987,11 +989,11 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin dstH,format,dstBpp, video_mode_info.XResolution,video_mode_info.YResolution) != 0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantInitializeVidixDriver); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Can't initialize VIDIX driver.\n"); vesa_term(); return -1; } - else mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingVidix); + else mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] Using VIDIX.\n"); vidix_start(); /* set colorkey */ @@ -1017,12 +1019,12 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin } else { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantFindModeFor,width,height,bpp); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_VESA] Can't find mode for: %ux%u@%u.\n",width,height,bpp); return -1; } if( mp_msg_test(MSGT_VO,MSGL_V) ) { - mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_InitializationComplete); + mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_VESA] VESA initialization complete.\n"); fflush(stdout); } if(HAS_DGA() && vo_doublebuffering) @@ -1087,7 +1089,8 @@ static int preinit(const char *arg) if(arg) subdev_flags = parseSubDevice(arg); if(lvo_name) pre_init_err = vlvo_preinit(lvo_name); #ifdef CONFIG_VIDIX - else if(vidix_name) pre_init_err = vidix_preinit(vidix_name,&video_out_vesa); + else if(vidix_name) pre_init_err = vidix_preinit(vidix_name, + video_out_vesa.old_functions); #endif // check if we can open /dev/mem (it will be opened later in config(), but if we // detect now that we can't we can exit cleanly) @@ -1101,7 +1104,7 @@ static int preinit(const char *arg) return pre_init_err; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -1109,33 +1112,8 @@ static int control(uint32_t request, void *data, ...) } #ifdef CONFIG_VIDIX - if (vidix_name) { - switch (request) { - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, (int *)value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } - } + if (vidix_name) return vidix_control(request, data); - } #endif return VO_NOTIMPL; diff --git a/libvo/vo_wii.c b/libvo/vo_wii.c index 030b19dd05..8999852d80 100644 --- a/libvo/vo_wii.c +++ b/libvo/vo_wii.c @@ -351,7 +351,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { if (request == VOCTRL_GET_IMAGE) return get_image(data); diff --git a/libvo/vo_winvidix.c b/libvo/vo_winvidix.c index ad4c5e2dd8..3c3f0419d8 100644 --- a/libvo/vo_winvidix.c +++ b/libvo/vo_winvidix.c @@ -57,6 +57,7 @@ LIBVO_EXTERN(winvidix) /* VIDIX related */ static char *vidix_name; +static int depthonscreen; /* Image parameters */ static uint32_t image_width; static uint32_t image_height; @@ -129,7 +130,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l /*update vidix*/ /* FIXME: implement runtime resize/move if possible, this way is very ugly! */ vidix_stop(); - if(vidix_init(image_width, image_height, vo_dx, vo_dy, vo_dwidth, vo_dheight, image_format, vo_depthonscreen, vo_screenwidth, vo_screenheight) != 0) + if(vidix_init(image_width, image_height, vo_dx, vo_dy, vo_dwidth, vo_dheight, image_format, depthonscreen, vo_screenwidth, vo_screenheight) != 0) mp_msg(MSGT_VO, MSGL_FATAL, "Can't initialize VIDIX driver: %s\n", strerror(errno)); /*set colorkey*/ vidix_start(); @@ -203,7 +204,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,uint32_t d_h image_format = format; vo_screenwidth = GetSystemMetrics(SM_CXSCREEN); vo_screenheight = GetSystemMetrics(SM_CYSCREEN); - vo_depthonscreen = GetDeviceCaps(GetDC(GetDesktopWindow()),BITSPIXEL); + depthonscreen = GetDeviceCaps(GetDC(GetDesktopWindow()),BITSPIXEL); aspect_save_orig(width, height); @@ -336,13 +337,13 @@ static int preinit(const char *arg){ vidix_name = NULL; } - if (vidix_preinit(vidix_name, &video_out_winvidix) != 0) + if (vidix_preinit(vidix_name, video_out_winvidix.old_functions) != 0) return 1; return 0; } -static int control(uint32_t request, void *data, ...){ +static int control(uint32_t request, void *data){ switch (request) { case VOCTRL_FULLSCREEN: if(!vo_fs){vo_fs=1;ShowWindow(hWndFS,SW_SHOW);SetForegroundWindow(hWndFS);} @@ -350,28 +351,6 @@ static int control(uint32_t request, void *data, ...){ break; case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, (int *)value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } } return vidix_control(request, data); // return VO_NOTIMPL; diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c index 05762e5bbe..938640a809 100644 --- a/libvo/vo_x11.c +++ b/libvo/vo_x11.c @@ -56,11 +56,6 @@ static int CompletionType = -1; #include "mp_msg.h" #include "help_mp.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#include "mplayer.h" -#endif - static const vo_info_t info = { "X11 ( XImage/Shm )", "x11", @@ -330,7 +325,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, old_vo_dwidth = -1; old_vo_dheight = -1; - int_pause = 0; if (!title) title = "MPlayer X11 (XImage/Shm) render"; @@ -358,11 +352,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, image_width = (width + 7) & (~7); image_height = height; -#ifdef CONFIG_GUI - if (use_gui) - guiGetEvent(guiSetShVideo, 0); // the GUI will set up / resize the window - else -#endif { #ifdef CONFIG_XF86VM if (vm) @@ -665,7 +654,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { @@ -677,33 +666,19 @@ static int control(uint32_t request, void *data, ...) return query_format(*((uint32_t *) data)); case VOCTRL_GET_IMAGE: return get_image(data); - case VOCTRL_GUISUPPORT: - return VO_TRUE; case VOCTRL_FULLSCREEN: vo_x11_fullscreen(); vo_x11_clearwindow(mDisplay, vo_window); return VO_TRUE; case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - - va_end(ap); - return vo_x11_set_equalizer(data, value); + struct voctrl_set_equalizer_args *args = data; + return vo_x11_set_equalizer(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - - va_end(ap); - return vo_x11_get_equalizer(data, value); + struct voctrl_get_equalizer_args *args = data; + return vo_x11_get_equalizer(args->name, args->valueptr); } case VOCTRL_ONTOP: vo_x11_ontop(); diff --git a/libvo/vo_xmga.c b/libvo/vo_xmga.c index b0d44440bb..817ce2d2e8 100644 --- a/libvo/vo_xmga.c +++ b/libvo/vo_xmga.c @@ -55,10 +55,6 @@ static unsigned int timer = 0; static unsigned int timerd = 0; #endif -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif - static const vo_info_t info = { "Matrox G200/G4x0/G550 overlay in X11 window (using /dev/mga_vid)", "xmga", @@ -181,11 +177,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, initialized = 1; -#ifdef CONFIG_GUI - if (use_gui) - guiGetEvent(guiSetShVideo, 0); // the GUI will set up / resize the window - else -#endif { if (flags & VOFLAG_FULLSCREEN) aspect(&dwidth, &dheight, A_ZOOM); @@ -205,7 +196,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, flags, xWAttribs.colormap, "xmga", title); XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xWAttribs); - } // !GUI + } if ((flags & VOFLAG_FULLSCREEN) && (!WinID)) { diff --git a/libvo/vo_xover.c b/libvo/vo_xover.c index 06815f15cd..dd7bceadb1 100644 --- a/libvo/vo_xover.c +++ b/libvo/vo_xover.c @@ -48,10 +48,6 @@ #include "aspect.h" #include "mp_msg.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif - static const vo_info_t info = { @@ -82,8 +78,8 @@ static uint32_t window_width, window_height; static uint32_t drwX, drwY, drwWidth, drwHeight, drwBorderWidth, drwDepth, drwcX, drwcY, dwidth, dheight; -static const vo_functions_t* sub_vo = NULL; - +static const struct vo_old_functions *sub_vo = NULL; +static const struct vo_info_s *sub_info; static void set_window(int force_update) { @@ -224,7 +220,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, mp_colorkey_t colork; char _title[255]; - sprintf(_title,"MPlayer %s X11 Overlay",sub_vo->info->name); + sprintf(_title,"MPlayer %s X11 Overlay", sub_info->name); title = _title; panscan_init(); @@ -270,12 +266,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, vo_dy += xinerama_y; vo_dwidth=d_width; vo_dheight=d_height; -#ifdef CONFIG_GUI - if(use_gui) guiGetEvent( guiSetShVideo,0 ); // the GUI will set up / resize the window - else - { -#endif - #ifdef X11_FULLSCREEN if ( ( flags&VOFLAG_FULLSCREEN )||(flags & VOFLAG_SWSCALE) ) aspect(&d_width, &d_height, A_ZOOM); #endif @@ -302,10 +292,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, xswa.colormap, "xvidix", title); XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); -#ifdef CONFIG_GUI - } -#endif - if ( ( !WinID )&&( flags&VOFLAG_FULLSCREEN ) ) { vo_dx=0; vo_dy=0; vo_dwidth=vo_screenwidth; vo_dheight=vo_screenheight; vo_fs=1; } if(sub_vo->config(image_width,image_height,vo_dwidth,vo_dheight, @@ -378,10 +364,10 @@ static void uninit(void) sub_vo = NULL; vo_x11_uninit(); // Restore our callbacks - video_out_xover.draw_frame = draw_frame; - video_out_xover.draw_slice = draw_slice; - video_out_xover.flip_page = flip_page; - video_out_xover.draw_osd = draw_osd; + video_out_xover.old_functions->draw_frame = draw_frame; + video_out_xover.old_functions->draw_slice = draw_slice; + video_out_xover.old_functions->flip_page = flip_page; + video_out_xover.old_functions->draw_osd = draw_osd; } static int preinit(const char *arg) @@ -393,40 +379,41 @@ static int preinit(const char *arg) return 1; } - for(i = 0 ; video_out_drivers[i] != NULL ; i++) { - if(!strcmp(video_out_drivers[i]->info->short_name,arg) && - strcmp(video_out_drivers[i]->info->short_name,"xover")) + const struct vo_driver *candidate; + for(i = 0; (candidate = video_out_drivers[i]) != NULL; i++) + if (!candidate->is_new && !strcmp(candidate->info->short_name,arg) && + strcmp(candidate->info->short_name,"xover")) break; - } - if(!video_out_drivers[i]) { + if (!candidate) { mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: Subdriver %s not found\n", arg); return 1; } - if(video_out_drivers[i]->control(VOCTRL_XOVERLAY_SUPPORT,NULL) != VO_TRUE) { + + const struct vo_old_functions *functions = candidate->old_functions; + if (functions->control(VOCTRL_XOVERLAY_SUPPORT,NULL) != VO_TRUE) { mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: %s doesn't support XOverlay\n", arg); return 1; } // X11 init if (!vo_init()) return VO_FALSE; - if(video_out_drivers[i]->preinit(NULL)) { + if(functions->preinit(NULL)) { mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: Subvo init failed\n"); return 1; } - sub_vo = video_out_drivers[i]; + sub_vo = functions; + sub_info = candidate->info; // Setup the sub vo callbacks - video_out_xover.draw_frame = sub_vo->draw_frame; - video_out_xover.draw_slice = sub_vo->draw_slice; - video_out_xover.flip_page = sub_vo->flip_page; - video_out_xover.draw_osd = sub_vo->draw_osd; + video_out_xover.old_functions->draw_frame = sub_vo->draw_frame; + video_out_xover.old_functions->draw_slice = sub_vo->draw_slice; + video_out_xover.old_functions->flip_page = sub_vo->flip_page; + video_out_xover.old_functions->draw_osd = sub_vo->draw_osd; return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { if(!sub_vo) return VO_ERROR; switch (request) { - case VOCTRL_GUISUPPORT: - return VO_TRUE; case VOCTRL_GET_PANSCAN: if ( !vo_config_count || !vo_fs ) return VO_FALSE; return VO_TRUE; @@ -443,7 +430,6 @@ static int control(uint32_t request, void *data, ...) } return VO_TRUE; default: - // Safe atm bcs nothing use more than 1 arg return sub_vo->control(request,data); } return VO_NOTIMPL; diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index 451d575884..9a030ac71c 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -37,13 +37,18 @@ Buffer allocation: #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdint.h> +#include <stdbool.h> #include "config.h" +#include "options.h" +#include "talloc.h" #include "mp_msg.h" #include "help_mp.h" #include "video_out.h" -#include "video_out_internal.h" - +#include "libmpcodecs/vfcap.h" +#include "libmpcodecs/mp_image.h" +#include "osd.h" #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -58,10 +63,7 @@ Buffer allocation: #include "subopt-helper.h" #include "input/input.h" - -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif +#include "mp_fifo.h" #include "libavutil/common.h" @@ -72,719 +74,779 @@ static const vo_info_t info = { "" }; -const LIBVO_EXTERN(xv) #ifdef HAVE_SHM #include <sys/ipc.h> #include <sys/shm.h> #include <X11/extensions/XShm.h> - -static XShmSegmentInfo Shminfo[NUM_BUFFERS]; -static int Shmem_Flag; #endif // Note: depends on the inclusion of X11/extensions/XShm.h #include <X11/extensions/Xv.h> #include <X11/extensions/Xvlib.h> -// FIXME: dynamically allocate this stuff -static void allocate_xvimage(int); -static unsigned int ver, rel, req, ev, err; -static unsigned int formats, adaptors, xv_format; -static XvAdaptorInfo *ai = NULL; -static XvImageFormatValues *fo=NULL; - -static int current_buf = 0; -static int current_ip_buf = 0; -static int num_buffers = 1; // default -static int visible_buf = -1; // -1 means: no buffer was drawn yet -static XvImage *xvimage[NUM_BUFFERS]; - - -static uint32_t image_width; -static uint32_t image_height; -static uint32_t image_format; - -static int int_pause; +struct xvctx { + XvAdaptorInfo *ai; + XvImageFormatValues *fo; + unsigned int formats, adaptors, xv_format; + int current_buf; + int current_ip_buf; + int num_buffers; + int total_buffers; + int have_visible_image_copy; + int have_next_image_copy; + int unchanged_visible_image; + int unchanged_next_image; + int visible_buf; + XvImage *xvimage[NUM_BUFFERS + 1]; + uint32_t image_width; + uint32_t image_height; + uint32_t image_format; + int is_paused; + struct vo_rect src_rect; + struct vo_rect dst_rect; + uint32_t max_width, max_height; // zero means: not set + int event_fd_registered; // for uninit called from preinit + int mode_switched; + int osd_objects_drawn; + void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h, + unsigned char *src, unsigned char *srca, + int stride); +#ifdef HAVE_SHM + XShmSegmentInfo Shminfo[NUM_BUFFERS + 1]; + int Shmem_Flag; +#endif +}; -static struct vo_rect src_rect; -static struct vo_rect dst_rect; -static uint32_t max_width = 0, max_height = 0; // zero means: not set +static void allocate_xvimage(struct vo *, int); -static void (*draw_alpha_fnc) (int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, - int stride); -static void draw_alpha_yv12(int x0, int y0, int w, int h, +static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yv12(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + x0, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + x0, + ctx->xvimage[ctx->current_buf]->pitches[0]); + ctx->osd_objects_drawn++; } -static void draw_alpha_yuy2(int x0, int y0, int w, int h, +static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yuy2(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + 2 * x0, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0, + ctx->xvimage[ctx->current_buf]->pitches[0]); + ctx->osd_objects_drawn++; } -static void draw_alpha_uyvy(int x0, int y0, int w, int h, +static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yuy2(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + 2 * x0 + 1, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0 + 1, + ctx->xvimage[ctx->current_buf]->pitches[0]); + ctx->osd_objects_drawn++; } -static void draw_alpha_null(int x0, int y0, int w, int h, +static void draw_alpha_null(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { } -static void deallocate_xvimage(int foo); +static void deallocate_xvimage(struct vo *vo, int foo); -static void resize(void) +static void resize(struct vo *vo) { - calc_src_dst_rects(image_width, image_height, &src_rect, &dst_rect, NULL, NULL); - vo_x11_clearwindow_part(mDisplay, vo_window, dst_rect.width, dst_rect.height, 1); - vo_xv_draw_colorkey(dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height); + struct xvctx *ctx = vo->priv; + + calc_src_dst_rects(vo, ctx->image_width, ctx->image_height, &ctx->src_rect, + &ctx->dst_rect, NULL, NULL); + struct vo_rect *dst = &ctx->dst_rect; + vo_x11_clearwindow_part(vo, vo->x11->window, dst->width, dst->height, 1); + vo_xv_draw_colorkey(vo, dst->left, dst->top, dst->width, dst->height); } /* * connect to server, create and map window, * allocate colors and (shared) memory */ -static int config(uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t flags, char *title, - uint32_t format) +static int 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) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; XVisualInfo vinfo; XSetWindowAttributes xswa; XWindowAttributes attribs; unsigned long xswamask; int depth; + struct xvctx *ctx = vo->priv; + int i; -#ifdef CONFIG_XF86VM - int vm = flags & VOFLAG_MODESWITCHING; -#endif - - image_height = height; - image_width = width; - image_format = format; + ctx->image_height = height; + ctx->image_width = width; + ctx->image_format = format; - if ((max_width != 0 && max_height != 0) && - (image_width > max_width || image_height > max_height)) - { - mp_msg( MSGT_VO, MSGL_ERR, MSGTR_VO_XV_ImagedimTooHigh, - image_width, image_height, max_width, max_height); + if ((ctx->max_width != 0 && ctx->max_height != 0) + && (ctx->image_width > ctx->max_width + || ctx->image_height > ctx->max_height)) { + mp_tmsg(MSGT_VO, MSGL_ERR, "Source image dimensions are too high: %ux%u (maximum is %ux%u)\n", + ctx->image_width, ctx->image_height, ctx->max_width, + ctx->max_height); return -1; } - int_pause = 0; - visible_buf = -1; - - num_buffers = - vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1; + ctx->visible_buf = -1; + ctx->have_visible_image_copy = false; + ctx->have_next_image_copy = false; /* check image formats */ - { - unsigned int i; - - xv_format = 0; - for (i = 0; i < formats; i++) - { - mp_msg(MSGT_VO, MSGL_V, - "Xvideo image format: 0x%x (%4.4s) %s\n", fo[i].id, - (char *) &fo[i].id, - (fo[i].format == XvPacked) ? "packed" : "planar"); - if (fo[i].id == format) - xv_format = fo[i].id; - } - if (!xv_format) - return -1; + ctx->xv_format = 0; + for (i = 0; i < ctx->formats; i++) { + mp_msg(MSGT_VO, MSGL_V, "Xvideo image format: 0x%x (%4.4s) %s\n", + ctx->fo[i].id, (char *) &ctx->fo[i].id, + (ctx->fo[i].format == XvPacked) ? "packed" : "planar"); + if (ctx->fo[i].id == format) + ctx->xv_format = ctx->fo[i].id; } + if (!ctx->xv_format) + return -1; -#ifdef CONFIG_GUI - if (use_gui) - guiGetEvent(guiSetShVideo, 0); // the GUI will set up / resize the window - else -#endif { #ifdef CONFIG_XF86VM - if (vm) - { - vo_vm_switch(); + int vm = flags & VOFLAG_MODESWITCHING; + if (vm) { + vo_vm_switch(vo); + ctx->mode_switched = 1; } #endif - XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), + XGetWindowAttributes(x11->display, DefaultRootWindow(x11->display), &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24; - XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); + XMatchVisualInfo(x11->display, x11->screen, depth, TrueColor, &vinfo); xswa.background_pixel = 0; - if (xv_ck_info.method == CK_METHOD_BACKGROUND) - { - xswa.background_pixel = xv_colorkey; - } + if (x11->xv_ck_info.method == CK_METHOD_BACKGROUND) + xswa.background_pixel = x11->xv_colorkey; xswa.border_pixel = 0; xswamask = CWBackPixel | CWBorderPixel; - vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, vo_dwidth, vo_dheight, - flags, CopyFromParent, "xv", title); - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); + vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, vo->dwidth, + vo->dheight, flags, CopyFromParent, "xv", + title); + XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa); #ifdef CONFIG_XF86VM - if (vm) - { + if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) - XGrabPointer(mDisplay, vo_window, True, 0, - GrabModeAsync, GrabModeAsync, - vo_window, None, CurrentTime); - XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); + XGrabPointer(x11->display, x11->window, True, 0, GrabModeAsync, + GrabModeAsync, x11->window, None, CurrentTime); + XSetInputFocus(x11->display, x11->window, RevertToNone, + CurrentTime); } #endif } mp_msg(MSGT_VO, MSGL_V, "using Xvideo port %d for hw scaling\n", - xv_port); - - switch (xv_format) - { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - draw_alpha_fnc = draw_alpha_yv12; - break; - case IMGFMT_YUY2: - case IMGFMT_YVYU: - draw_alpha_fnc = draw_alpha_yuy2; - break; - case IMGFMT_UYVY: - draw_alpha_fnc = draw_alpha_uyvy; - break; - default: - draw_alpha_fnc = draw_alpha_null; + x11->xv_port); + + switch (ctx->xv_format) { + case IMGFMT_YV12: + case IMGFMT_I420: + case IMGFMT_IYUV: + ctx->draw_alpha_fnc = draw_alpha_yv12; + break; + case IMGFMT_YUY2: + case IMGFMT_YVYU: + ctx->draw_alpha_fnc = draw_alpha_yuy2; + break; + case IMGFMT_UYVY: + ctx->draw_alpha_fnc = draw_alpha_uyvy; + break; + default: + ctx->draw_alpha_fnc = draw_alpha_null; } - if (vo_config_count) - for (current_buf = 0; current_buf < num_buffers; ++current_buf) - deallocate_xvimage(current_buf); + // In case config has been called before + for (i = 0; i < ctx->total_buffers; i++) + deallocate_xvimage(vo, i); + + ctx->num_buffers = + vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1; + ctx->total_buffers = ctx->num_buffers + 1; + + for (i = 0; i < ctx->total_buffers; i++) + allocate_xvimage(vo, i); - for (current_buf = 0; current_buf < num_buffers; ++current_buf) - allocate_xvimage(current_buf); + ctx->current_buf = 0; + ctx->current_ip_buf = 0; - current_buf = 0; - current_ip_buf = 0; - resize(); + resize(vo); return 0; } -static void allocate_xvimage(int foo) +static void allocate_xvimage(struct vo *vo, int foo) { + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; /* * allocate XvImages. FIXME: no error checking, without * mit-shm this will bomb... trzing to fix ::atmos */ #ifdef HAVE_SHM - if (mLocalDisplay && XShmQueryExtension(mDisplay)) - Shmem_Flag = 1; - else - { - Shmem_Flag = 0; - mp_msg(MSGT_VO, MSGL_INFO, - MSGTR_LIBVO_XV_SharedMemoryNotSupported); + if (x11->display_is_local && XShmQueryExtension(x11->display)) + ctx->Shmem_Flag = 1; + else { + ctx->Shmem_Flag = 0; + mp_tmsg(MSGT_VO, MSGL_INFO, "[VO_XV] Shared memory not supported\nReverting to normal Xv.\n"); } - if (Shmem_Flag) - { - xvimage[foo] = - (XvImage *) XvShmCreateImage(mDisplay, xv_port, xv_format, - NULL, image_width, image_height, - &Shminfo[foo]); - - Shminfo[foo].shmid = - shmget(IPC_PRIVATE, xvimage[foo]->data_size, IPC_CREAT | 0777); - Shminfo[foo].shmaddr = (char *) shmat(Shminfo[foo].shmid, 0, 0); - Shminfo[foo].readOnly = False; - - xvimage[foo]->data = Shminfo[foo].shmaddr; - XShmAttach(mDisplay, &Shminfo[foo]); - XSync(mDisplay, False); - shmctl(Shminfo[foo].shmid, IPC_RMID, 0); + if (ctx->Shmem_Flag) { + ctx->xvimage[foo] = + (XvImage *) XvShmCreateImage(x11->display, x11->xv_port, + ctx->xv_format, NULL, + ctx->image_width, ctx->image_height, + &ctx->Shminfo[foo]); + + ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE, + ctx->xvimage[foo]->data_size, + IPC_CREAT | 0777); + ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, + 0); + ctx->Shminfo[foo].readOnly = False; + + ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr; + XShmAttach(x11->display, &ctx->Shminfo[foo]); + XSync(x11->display, False); + shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0); } else #endif { - xvimage[foo] = - (XvImage *) XvCreateImage(mDisplay, xv_port, xv_format, NULL, - image_width, image_height); - xvimage[foo]->data = malloc(xvimage[foo]->data_size); - XSync(mDisplay, False); + ctx->xvimage[foo] = + (XvImage *) XvCreateImage(x11->display, x11->xv_port, + ctx->xv_format, NULL, ctx->image_width, + ctx->image_height); + ctx->xvimage[foo]->data = malloc(ctx->xvimage[foo]->data_size); + XSync(x11->display, False); } - memset(xvimage[foo]->data, 128, xvimage[foo]->data_size); + memset(ctx->xvimage[foo]->data, 128, ctx->xvimage[foo]->data_size); return; } -static void deallocate_xvimage(int foo) +static void deallocate_xvimage(struct vo *vo, int foo) { + struct xvctx *ctx = vo->priv; #ifdef HAVE_SHM - if (Shmem_Flag) - { - XShmDetach(mDisplay, &Shminfo[foo]); - shmdt(Shminfo[foo].shmaddr); + if (ctx->Shmem_Flag) { + XShmDetach(vo->x11->display, &ctx->Shminfo[foo]); + shmdt(ctx->Shminfo[foo].shmaddr); } else #endif { - free(xvimage[foo]->data); + free(ctx->xvimage[foo]->data); } - XFree(xvimage[foo]); + XFree(ctx->xvimage[foo]); - XSync(mDisplay, False); + XSync(vo->x11->display, False); return; } -static inline void put_xvimage( XvImage * xvi ) +static inline void put_xvimage(struct vo *vo, XvImage *xvi) { + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; + struct vo_rect *src = &ctx->src_rect; + struct vo_rect *dst = &ctx->dst_rect; #ifdef HAVE_SHM - if (Shmem_Flag) - { - XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvi, - src_rect.left, src_rect.top, src_rect.width, src_rect.height, - dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height, + if (ctx->Shmem_Flag) { + XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi, + src->left, src->top, src->width, src->height, + dst->left, dst->top, dst->width, dst->height, False); } else #endif { - XvPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvi, - src_rect.left, src_rect.top, src_rect.width, src_rect.height, - dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height); + XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi, + src->left, src->top, src->width, src->height, + dst->left, dst->top, dst->width, dst->height); } } -static void check_events(void) +// Only copies luma for planar formats as draw_alpha doesn't change others */ +static void copy_backup_image(struct vo *vo, int dest, int src) { - int e = vo_x11_check_events(mDisplay); + struct xvctx *ctx = vo->priv; + + XvImage *vb = ctx->xvimage[dest]; + XvImage *cp = ctx->xvimage[src]; + memcpy_pic(vb->data + vb->offsets[0], cp->data + cp->offsets[0], + vb->width, vb->height, + vb->pitches[0], cp->pitches[0]); +} + +static void check_events(struct vo *vo) +{ + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; + int e = vo_x11_check_events(vo); if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) - { - resize(); - } + resize(vo); - if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause) - { + if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && ctx->is_paused) { /* did we already draw a buffer */ - if ( visible_buf != -1 ) - { - /* redraw the last visible buffer */ - put_xvimage( xvimage[visible_buf] ); + if (ctx->visible_buf != -1) { + /* redraw the last visible buffer */ + put_xvimage(vo, ctx->xvimage[ctx->visible_buf]); } } } -static void draw_osd(void) +static void draw_osd(struct vo *vo, struct osd_state *osd) { - vo_draw_text(image_width - - image_width * vo_panscan_x / (vo_dwidth + vo_panscan_x), - image_height, draw_alpha_fnc); + struct xvctx *ctx = vo->priv; + + ctx->osd_objects_drawn = 0; + osd_draw_text(osd, + ctx->image_width - + ctx->image_width * vo->panscan_x / (vo->dwidth + + vo->panscan_x), + ctx->image_height, ctx->draw_alpha_fnc, vo); + if (ctx->osd_objects_drawn) + ctx->unchanged_next_image = false; } -static void flip_page(void) +static int redraw_osd(struct vo *vo, struct osd_state *osd) { - put_xvimage( xvimage[current_buf] ); + struct xvctx *ctx = vo->priv; + + if (ctx->have_visible_image_copy) + copy_backup_image(vo, ctx->visible_buf, ctx->num_buffers); + else if (ctx->unchanged_visible_image) { + copy_backup_image(vo, ctx->num_buffers, ctx->visible_buf); + ctx->have_visible_image_copy = true; + } + else + return false; + int temp = ctx->current_buf; + ctx->current_buf = ctx->visible_buf; + draw_osd(vo, osd); + ctx->current_buf = temp; + put_xvimage(vo, ctx->xvimage[ctx->visible_buf]); + return true; +} + +static void flip_page(struct vo *vo) +{ + struct xvctx *ctx = vo->priv; + put_xvimage(vo, ctx->xvimage[ctx->current_buf]); /* remember the currently visible buffer */ - visible_buf = current_buf; + ctx->visible_buf = ctx->current_buf; - if (num_buffers > 1) - { - current_buf = - vo_directrendering ? 0 : ((current_buf + 1) % num_buffers); - XFlush(mDisplay); + ctx->have_visible_image_copy = ctx->have_next_image_copy; + ctx->have_next_image_copy = false; + ctx->unchanged_visible_image = ctx->unchanged_next_image; + ctx->unchanged_next_image = false; + + if (ctx->num_buffers > 1) { + ctx->current_buf = vo_directrendering ? 0 : ((ctx->current_buf + 1) % + ctx->num_buffers); + XFlush(vo->x11->display); } else - XSync(mDisplay, False); + XSync(vo->x11->display, False); return; } -static int draw_slice(uint8_t * image[], int stride[], int w, int h, - int x, int y) +static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w, + int h, int x, int y) { + struct xvctx *ctx = vo->priv; uint8_t *dst; + XvImage *current_image = ctx->xvimage[ctx->current_buf]; - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y + x; - memcpy_pic(dst, image[0], w, h, xvimage[current_buf]->pitches[0], - stride[0]); + dst = current_image->data + current_image->offsets[0] + + current_image->pitches[0] * y + x; + memcpy_pic(dst, image[0], w, h, current_image->pitches[0], stride[0]); x /= 2; y /= 2; w /= 2; h /= 2; - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[1] + - xvimage[current_buf]->pitches[1] * y + x; - if (image_format != IMGFMT_YV12) - memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1], - stride[1]); + dst = current_image->data + current_image->offsets[1] + + current_image->pitches[1] * y + x; + if (ctx->image_format != IMGFMT_YV12) + memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]); else - memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1], - stride[2]); - - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[2] + - xvimage[current_buf]->pitches[2] * y + x; - if (image_format == IMGFMT_YV12) - memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1], - stride[1]); + memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]); + + dst = current_image->data + current_image->offsets[2] + + current_image->pitches[2] * y + x; + if (ctx->image_format == IMGFMT_YV12) + memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]); else - memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1], - stride[2]); + memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]); return 0; } -static int draw_frame(uint8_t * src[]) +static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) { - return VO_ERROR; -} + struct xvctx *ctx = vo->priv; + + ctx->have_next_image_copy = false; -static uint32_t draw_image(mp_image_t * mpi) -{ if (mpi->flags & MP_IMGFLAG_DIRECT) - { // direct rendering: - current_buf = (int) (mpi->priv); // hack! - return VO_TRUE; - } - if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) - return VO_TRUE; // done - if (mpi->flags & MP_IMGFLAG_PLANAR) - { - draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0); - return VO_TRUE; - } - if (mpi->flags & MP_IMGFLAG_YUV) - { + ctx->current_buf = (int) (mpi->priv); // hack! + else if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) + ; // done + else if (mpi->flags & MP_IMGFLAG_PLANAR) + draw_slice(vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0); + else if (mpi->flags & MP_IMGFLAG_YUV) // packed YUV: - memcpy_pic(xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0], mpi->planes[0], + memcpy_pic(ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0], mpi->planes[0], mpi->w * (mpi->bpp / 8), mpi->h, - xvimage[current_buf]->pitches[0], mpi->stride[0]); - return VO_TRUE; + ctx->xvimage[ctx->current_buf]->pitches[0], mpi->stride[0]); + else + return false; + + if (ctx->is_paused) { + copy_backup_image(vo, ctx->num_buffers, ctx->current_buf); + ctx->have_next_image_copy = true; } - return VO_FALSE; // not (yet) supported + ctx->unchanged_next_image = true; + return true; } -static uint32_t get_image(mp_image_t * mpi) +static uint32_t get_image(struct xvctx *ctx, mp_image_t *mpi) { - int buf = current_buf; // we shouldn't change current_buf unless we do DR! + // we shouldn't change current_buf unless we do DR! + int buf = ctx->current_buf; - if (mpi->type == MP_IMGTYPE_STATIC && num_buffers > 1) + if (mpi->type == MP_IMGTYPE_STATIC && ctx->num_buffers > 1) return VO_FALSE; // it is not static - if (mpi->imgfmt != image_format) + if (mpi->imgfmt != ctx->image_format) return VO_FALSE; // needs conversion :( -// if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // slow video ram - if (mpi->flags & MP_IMGFLAG_READABLE && - (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) - { + if (mpi->flags & MP_IMGFLAG_READABLE + && (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) { // reference (I/P) frame of IP or IPB: - if (num_buffers < 2) + if (ctx->num_buffers < 2) return VO_FALSE; // not enough - current_ip_buf ^= 1; + ctx->current_ip_buf ^= 1; // for IPB with 2 buffers we can DR only one of the 2 P frames: - if (mpi->type == MP_IMGTYPE_IPB && num_buffers < 3 - && current_ip_buf) + if (mpi->type == MP_IMGTYPE_IPB && ctx->num_buffers < 3 + && ctx->current_ip_buf) return VO_FALSE; - buf = current_ip_buf; + buf = ctx->current_ip_buf; if (mpi->type == MP_IMGTYPE_IPB) ++buf; // preserve space for B } - if (mpi->height > xvimage[buf]->height) + if (mpi->height > ctx->xvimage[buf]->height) return VO_FALSE; //buffer to small - if (mpi->width * (mpi->bpp / 8) > xvimage[buf]->pitches[0]) + if (mpi->width * (mpi->bpp / 8) > ctx->xvimage[buf]->pitches[0]) return VO_FALSE; //buffer to small if ((mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH)) - || (mpi->width * (mpi->bpp / 8) == xvimage[buf]->pitches[0])) - { - current_buf = buf; - mpi->planes[0] = - xvimage[current_buf]->data + xvimage[current_buf]->offsets[0]; - mpi->stride[0] = xvimage[current_buf]->pitches[0]; + || (mpi->width * (mpi->bpp / 8) == ctx->xvimage[buf]->pitches[0])) { + ctx->current_buf = buf; + XvImage *current_image = ctx->xvimage[ctx->current_buf]; + mpi->planes[0] = current_image->data + current_image->offsets[0]; + mpi->stride[0] = current_image->pitches[0]; mpi->width = mpi->stride[0] / (mpi->bpp / 8); - if (mpi->flags & MP_IMGFLAG_PLANAR) - { - if (mpi->flags & MP_IMGFLAG_SWAPPED) - { + if (mpi->flags & MP_IMGFLAG_PLANAR) { + if (mpi->flags & MP_IMGFLAG_SWAPPED) { // I420 - mpi->planes[1] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[1]; - mpi->planes[2] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[2]; - mpi->stride[1] = xvimage[current_buf]->pitches[1]; - mpi->stride[2] = xvimage[current_buf]->pitches[2]; - } else - { + mpi->planes[1] = current_image->data + + current_image->offsets[1]; + mpi->planes[2] = current_image->data + + current_image->offsets[2]; + mpi->stride[1] = current_image->pitches[1]; + mpi->stride[2] = current_image->pitches[2]; + } else { // YV12 - mpi->planes[1] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[2]; - mpi->planes[2] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[1]; - mpi->stride[1] = xvimage[current_buf]->pitches[2]; - mpi->stride[2] = xvimage[current_buf]->pitches[1]; + mpi->planes[1] = current_image->data + + current_image->offsets[2]; + mpi->planes[2] = current_image->data + + current_image->offsets[1]; + mpi->stride[1] = current_image->pitches[2]; + mpi->stride[2] = current_image->pitches[1]; } } mpi->flags |= MP_IMGFLAG_DIRECT; - mpi->priv = (void *) current_buf; -// printf("mga: get_image() SUCCESS -> Direct Rendering ENABLED\n"); + mpi->priv = (void *) ctx->current_buf; return VO_TRUE; } return VO_FALSE; } -static int query_format(uint32_t format) +static int query_format(struct xvctx *ctx, uint32_t format) { uint32_t i; int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_ACCEPT_STRIDE; // FIXME! check for DOWN /* check image formats */ - for (i = 0; i < formats; i++) - { - if (fo[i].id == format) + for (i = 0; i < ctx->formats; i++) { + if (ctx->fo[i].id == format) return flag; //xv_format = fo[i].id; } return 0; } -static void uninit(void) +static void uninit(struct vo *vo) { + struct xvctx *ctx = vo->priv; int i; - if (!vo_config_count) - return; - visible_buf = -1; - XvFreeAdaptorInfo(ai); - ai = NULL; - if(fo){ - XFree(fo); - fo=NULL; + ctx->visible_buf = -1; + if (ctx->ai) + XvFreeAdaptorInfo(ctx->ai); + ctx->ai = NULL; + if (ctx->fo) { + XFree(ctx->fo); + ctx->fo = NULL; } - for (i = 0; i < num_buffers; i++) - deallocate_xvimage(i); + for (i = 0; i < ctx->total_buffers; i++) + deallocate_xvimage(vo, i); #ifdef CONFIG_XF86VM - vo_vm_close(); + if (ctx->mode_switched) + vo_vm_close(vo); #endif - mp_input_rm_event_fd(ConnectionNumber(mDisplay)); - vo_x11_uninit(); + if (ctx->event_fd_registered) + mp_input_rm_key_fd(vo->input_ctx, ConnectionNumber(vo->x11->display)); + // uninit() shouldn't get called unless initialization went past vo_init() + vo_x11_uninit(vo); +} + +static int x11_fd_callback(void *ctx, int fd) +{ + struct vo *vo = ctx; + check_events(vo); + return mplayer_get_key(vo->key_fifo, 0); } -static int preinit(const char *arg) +static int preinit(struct vo *vo, const char *arg) { XvPortID xv_p; int busy_ports = 0; unsigned int i; strarg_t ck_src_arg = { 0, NULL }; strarg_t ck_method_arg = { 0, NULL }; + struct xvctx *ctx = talloc_zero(vo, struct xvctx); + vo->priv = ctx; + struct vo_x11_state *x11 = vo->x11; int xv_adaptor = -1; - const opt_t subopts[] = - { - /* name arg type arg var test */ - { "port", OPT_ARG_INT, &xv_port, (opt_test_f)int_pos }, - { "adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f)int_non_neg }, - { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck }, - { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm }, - { NULL } + const opt_t subopts[] = { + /* name arg type arg var test */ + {"port", OPT_ARG_INT, &x11->xv_port, (opt_test_f) int_pos}, + {"adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f) int_non_neg}, + {"ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck}, + {"ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm}, + {NULL} }; - xv_port = 0; + x11->xv_port = 0; /* parse suboptions */ - if ( subopt_parse( arg, subopts ) != 0 ) - { - return -1; + if (subopt_parse(arg, subopts) != 0) { + return -1; } /* modify colorkey settings according to the given options */ - xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); + xv_setup_colorkeyhandling(vo, ck_method_arg.str, ck_src_arg.str); - if (!vo_init()) + if (!vo_init(vo)) return -1; /* check for Xvideo extension */ - if (Success != XvQueryExtension(mDisplay, &ver, &rel, &req, &ev, &err)) - { - mp_msg(MSGT_VO, MSGL_ERR, - MSGTR_LIBVO_XV_XvNotSupportedByX11); - return -1; + unsigned int ver, rel, req, ev, err; + if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) { + mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_XV] Sorry, Xv not supported by this X11 version/driver\n[VO_XV] ******** Try with -vo x11 or -vo sdl *********\n"); + goto error; } /* check for Xvideo support */ if (Success != - XvQueryAdaptors(mDisplay, DefaultRootWindow(mDisplay), &adaptors, - &ai)) - { - mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvQueryAdaptorsFailed); - return -1; + XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display), + &ctx->adaptors, &ctx->ai)) { + mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_XV] XvQueryAdaptors failed.\n"); + goto error; } /* check adaptors */ - if (xv_port) - { + if (x11->xv_port) { int port_found; - for (port_found = 0, i = 0; !port_found && i < adaptors; i++) - { - if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask)) - { - for (xv_p = ai[i].base_id; - xv_p < ai[i].base_id + ai[i].num_ports; ++xv_p) - { - if (xv_p == xv_port) - { + for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) { + if ((ctx->ai[i].type & XvInputMask) + && (ctx->ai[i].type & XvImageMask)) { + for (xv_p = ctx->ai[i].base_id; + xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; + ++xv_p) { + if (xv_p == x11->xv_port) { port_found = 1; break; } } } } - if (port_found) - { - if (XvGrabPort(mDisplay, xv_port, CurrentTime)) - xv_port = 0; - } else - { - mp_msg(MSGT_VO, MSGL_WARN, - MSGTR_LIBVO_XV_InvalidPortParameter); - xv_port = 0; + if (port_found) { + if (XvGrabPort(x11->display, x11->xv_port, CurrentTime)) + x11->xv_port = 0; + } else { + mp_tmsg(MSGT_VO, MSGL_WARN, "[VO_XV] Invalid port parameter, overriding with port 0.\n"); + x11->xv_port = 0; } } - for (i = 0; i < adaptors && xv_port == 0; i++) - { + for (i = 0; i < ctx->adaptors && x11->xv_port == 0; i++) { /* check if adaptor number has been specified */ if (xv_adaptor != -1 && xv_adaptor != i) - continue; + continue; - if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask)) - { - for (xv_p = ai[i].base_id; - xv_p < ai[i].base_id + ai[i].num_ports; ++xv_p) - if (!XvGrabPort(mDisplay, xv_p, CurrentTime)) - { - xv_port = xv_p; + if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) { + for (xv_p = ctx->ai[i].base_id; + xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) + if (!XvGrabPort(x11->display, xv_p, CurrentTime)) { + x11->xv_port = xv_p; mp_msg(MSGT_VO, MSGL_V, "[VO_XV] Using Xv Adapter #%d (%s)\n", - i, ai[i].name); + i, ctx->ai[i].name); break; - } else - { - mp_msg(MSGT_VO, MSGL_WARN, - MSGTR_LIBVO_XV_CouldNotGrabPort, (int) xv_p); + } else { + mp_tmsg(MSGT_VO, MSGL_WARN, "[VO_XV] Could not grab port %i.\n", + (int) xv_p); ++busy_ports; } } } - if (!xv_port) - { + if (!x11->xv_port) { if (busy_ports) - mp_msg(MSGT_VO, MSGL_ERR, - MSGTR_LIBVO_XV_CouldNotFindFreePort); + mp_tmsg(MSGT_VO, MSGL_ERR, + "[VO_XV] Could not find free Xvideo port - maybe another process is already\n"\ + "[VO_XV] using it. Close all video applications, and try again. If that does\n"\ + "[VO_XV] not help, see 'mplayer -vo help' for other (non-xv) video out drivers.\n"); else - mp_msg(MSGT_VO, MSGL_ERR, - MSGTR_LIBVO_XV_NoXvideoSupport); - return -1; + mp_tmsg(MSGT_VO, MSGL_ERR, + "[VO_XV] It seems there is no Xvideo support for your video card available.\n"\ + "[VO_XV] Run 'xvinfo' to verify its Xv support and read\n"\ + "[VO_XV] DOCS/HTML/en/video.html#xv!\n"\ + "[VO_XV] See 'mplayer -vo help' for other (non-xv) video out drivers.\n"\ + "[VO_XV] Try -vo x11.\n"); + goto error; } - if ( !vo_xv_init_colorkey() ) - { - return -1; // bail out, colorkey setup failed + if (!vo_xv_init_colorkey(vo)) { + goto error; // bail out, colorkey setup failed } - vo_xv_enable_vsync(); - vo_xv_get_max_img_dim( &max_width, &max_height ); + vo_xv_enable_vsync(vo); + vo_xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height); - fo = XvListImageFormats(mDisplay, xv_port, (int *) &formats); + ctx->fo = XvListImageFormats(x11->display, x11->xv_port, + (int *) &ctx->formats); - mp_input_add_event_fd(ConnectionNumber(mDisplay), check_events); + mp_input_add_key_fd(vo->input_ctx, ConnectionNumber(x11->display), 1, + x11_fd_callback, NULL, vo); + ctx->event_fd_registered = 1; return 0; + + error: + uninit(vo); // free resources + return -1; } -static int control(uint32_t request, void *data, ...) +static int control(struct vo *vo, uint32_t request, void *data) { - switch (request) - { - case VOCTRL_PAUSE: - return int_pause = 1; - case VOCTRL_RESUME: - return int_pause = 0; - case VOCTRL_QUERY_FORMAT: - return query_format(*((uint32_t *) data)); - case VOCTRL_GET_IMAGE: - return get_image(data); - case VOCTRL_DRAW_IMAGE: - return draw_image(data); - case VOCTRL_GUISUPPORT: - return VO_TRUE; - case VOCTRL_GET_PANSCAN: - return VO_TRUE; - case VOCTRL_FULLSCREEN: - vo_x11_fullscreen(); - /* indended, fallthrough to update panscan on fullscreen/windowed switch */ - case VOCTRL_SET_PANSCAN: - resize(); - return VO_TRUE; - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - - va_end(ap); - - return vo_xv_set_eq(xv_port, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - - va_end(ap); - - return vo_xv_get_eq(xv_port, data, value); - } - case VOCTRL_ONTOP: - vo_x11_ontop(); - return VO_TRUE; - case VOCTRL_UPDATE_SCREENINFO: - update_xinerama_info(); - return VO_TRUE; + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; + switch (request) { + case VOCTRL_PAUSE: + return (ctx->is_paused = 1); + case VOCTRL_RESUME: + return (ctx->is_paused = 0); + case VOCTRL_QUERY_FORMAT: + return query_format(ctx, *((uint32_t *) data)); + case VOCTRL_GET_IMAGE: + return get_image(ctx, data); + case VOCTRL_DRAW_IMAGE: + return draw_image(vo, data); + case VOCTRL_GET_PANSCAN: + return VO_TRUE; + case VOCTRL_FULLSCREEN: + vo_x11_fullscreen(vo); + /* indended, fallthrough to update panscan on fullscreen/windowed switch */ + case VOCTRL_SET_PANSCAN: + resize(vo); + return VO_TRUE; + case VOCTRL_SET_EQUALIZER: + { + struct voctrl_set_equalizer_args *args = data; + return vo_xv_set_eq(vo, x11->xv_port, args->name, args->value); + } + case VOCTRL_GET_EQUALIZER: + { + struct voctrl_get_equalizer_args *args = data; + return vo_xv_get_eq(vo, x11->xv_port, args->name, args->valueptr); + } + case VOCTRL_SET_YUV_COLORSPACE:; + int given_cspc = *(int *)data % 2; + return vo_xv_set_eq(vo, x11->xv_port, "bt_709", given_cspc * 200 - 100); + case VOCTRL_GET_YUV_COLORSPACE:; + int bt709_enabled; + if (!vo_xv_get_eq(vo, x11->xv_port, "bt_709", &bt709_enabled)) + return false; + *(int *)data = bt709_enabled == 100; + return true; + case VOCTRL_ONTOP: + vo_x11_ontop(vo); + return VO_TRUE; + case VOCTRL_UPDATE_SCREENINFO: + update_xinerama_info(vo); + return VO_TRUE; + case VOCTRL_REDRAW_OSD: + return redraw_osd(vo, data); } return VO_NOTIMPL; } + +const struct vo_driver video_out_xv = { + .is_new = 1, + .info = &info, + .preinit = preinit, + .config = config, + .control = control, + .draw_slice = draw_slice, + .draw_osd = draw_osd, + .flip_page = flip_page, + .check_events = check_events, + .uninit = uninit +}; diff --git a/libvo/vo_xvidix.c b/libvo/vo_xvidix.c index b48168e6d5..c7481ae613 100644 --- a/libvo/vo_xvidix.c +++ b/libvo/vo_xvidix.c @@ -49,11 +49,6 @@ #include "vosub_vidix.h" #include "vidix/vidix.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#endif - - static const vo_info_t info = { "X11 (VIDIX)", "xvidix", @@ -252,13 +247,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, } mp_msg(MSGT_VO, MSGL_V, "Using colorkey: %x\n", colorkey); -#ifdef CONFIG_GUI - if (use_gui) - guiGetEvent(guiSetShVideo, 0); // the GUI will set up / resize the window - else - { -#endif - #ifdef X11_FULLSCREEN if ((flags & VOFLAG_FULLSCREEN) || (flags & VOFLAG_SWSCALE)) aspect(&d_width, &d_height, A_ZOOM); @@ -289,10 +277,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, CopyFromParent, "xvidix", title); XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); -#ifdef CONFIG_GUI - } -#endif - if ((!WinID) && (flags & VOFLAG_FULLSCREEN)) { vo_dx = 0; @@ -409,20 +393,18 @@ static int preinit(const char *arg) if (!vo_init()) return -1; - if (vidix_preinit(vidix_name, &video_out_xvidix) != 0) + if (vidix_preinit(vidix_name, video_out_xvidix.old_functions) != 0) return 1; return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t *) data)); - case VOCTRL_GUISUPPORT: - return VO_TRUE; case VOCTRL_GET_PANSCAN: if (!vo_config_count || !vo_fs) return VO_FALSE; @@ -439,30 +421,6 @@ static int control(uint32_t request, void *data, ...) set_window(0); } return VO_TRUE; - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - - va_end(ap); - - return vidix_control(request, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - - va_end(ap); - - return vidix_control(request, data, value); - } case VOCTRL_UPDATE_SCREENINFO: aspect_save_screenres(vo_screenwidth, vo_screenheight); return VO_TRUE; diff --git a/libvo/vo_xvmc.c b/libvo/vo_xvmc.c index 1673fa8774..968b11aa0d 100644 --- a/libvo/vo_xvmc.c +++ b/libvo/vo_xvmc.c @@ -49,7 +49,6 @@ #include "aspect.h" #include "subopt-helper.h" -#include "gui/interface.h" #include "libavutil/common.h" @@ -623,11 +622,6 @@ found_subpic: skip_surface_allocation: -#ifdef CONFIG_GUI - if(use_gui) - guiGetEvent( guiSetShVideo,0 ); // let the GUI to setup/resize our window - else -#endif { #ifdef CONFIG_XF86VM if ( vm ) @@ -1269,7 +1263,7 @@ assert(rndr->next_free_data_block_num == 0); return VO_TRUE; } -static int control(uint32_t request, void *data, ... ) +static int control(uint32_t request, void *data) { switch (request){ case VOCTRL_GET_DEINTERLACE: @@ -1285,8 +1279,6 @@ static int control(uint32_t request, void *data, ... ) case VOCTRL_GET_IMAGE: return get_image((mp_image_t *)data); //vo_xv - case VOCTRL_GUISUPPORT: - return VO_TRUE; case VOCTRL_ONTOP: vo_x11_ontop(); return VO_TRUE; @@ -1311,26 +1303,14 @@ static int control(uint32_t request, void *data, ... ) return VO_TRUE; case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vo_xv_set_eq(xv_port, data, value); + struct voctrl_set_equalizer_args *args = data; + return vo_xv_set_eq(xv_port, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vo_xv_get_eq(xv_port, data, value); + struct voctrl_get_equalizer_args *args = data; + return vo_xv_get_eq(xv_port, args->name, args->valueptr); } case VOCTRL_UPDATE_SCREENINFO: update_xinerama_info(); diff --git a/libvo/vo_xvr100.c b/libvo/vo_xvr100.c index 476744729c..7a82c436fb 100644 --- a/libvo/vo_xvr100.c +++ b/libvo/vo_xvr100.c @@ -428,7 +428,7 @@ static int query_format(uint32_t format) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_GET_IMAGE: diff --git a/libvo/vo_yuv4mpeg.c b/libvo/vo_yuv4mpeg.c index f4cbfb1639..0cc7f9a62c 100644 --- a/libvo/vo_yuv4mpeg.c +++ b/libvo/vo_yuv4mpeg.c @@ -56,7 +56,9 @@ #include "fastmemcpy.h" #include "libswscale/swscale.h" +#ifdef CONFIG_LIBSWSCALE_INTERNALS #include "libswscale/rgb2rgb.h" +#endif #include "libmpcodecs/vf_scale.h" #include "libavutil/rational.h" @@ -122,42 +124,44 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, { if (height % 4) { - mp_msg(MSGT_VO,MSGL_FATAL, - MSGTR_VO_YUV4MPEG_InterlacedHeightDivisibleBy4); + mp_tmsg(MSGT_VO,MSGL_FATAL, + "Interlaced mode requires image height to be divisible by 4."); return -1; } rgb_line_buffer = malloc(image_width * 3); if (!rgb_line_buffer) { - mp_msg(MSGT_VO,MSGL_FATAL, - MSGTR_VO_YUV4MPEG_InterlacedLineBufAllocFail); + mp_tmsg(MSGT_VO,MSGL_FATAL, + "Unable to allocate line buffer for interlaced mode."); return -1; } if (using_format == IMGFMT_YV12) - mp_msg(MSGT_VO,MSGL_WARN, - MSGTR_VO_YUV4MPEG_InterlacedInputNotRGB); + mp_tmsg(MSGT_VO,MSGL_WARN, + "Input not RGB, can't separate chrominance by fields!"); } if (width % 2) { - mp_msg(MSGT_VO,MSGL_FATAL, - MSGTR_VO_YUV4MPEG_WidthDivisibleBy2); + mp_tmsg(MSGT_VO,MSGL_FATAL, + "Image width must be divisible by 2."); return -1; } +#ifdef CONFIG_LIBSWSCALE_INTERNALS if(using_format != IMGFMT_YV12) { sws_rgb2rgb_init(get_sws_cpuflags()); rgb_buffer = malloc(image_width * image_height * 3); if (!rgb_buffer) { - mp_msg(MSGT_VO,MSGL_FATAL, - MSGTR_VO_YUV4MPEG_NoMemRGBFrameBuf); + mp_tmsg(MSGT_VO,MSGL_FATAL, + "Not enough memory to allocate RGB framebuffer."); return -1; } } +#endif write_bytes = image_width * image_height * 3 / 2; image = malloc(write_bytes); @@ -165,8 +169,8 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, yuv_out = fopen(yuv_filename, "wb"); if (!yuv_out || image == 0) { - mp_msg(MSGT_VO,MSGL_FATAL, - MSGTR_VO_YUV4MPEG_OutFileOpenError, + mp_tmsg(MSGT_VO,MSGL_FATAL, + "Can't get memory or file handle to write \"%s\"!", yuv_filename); return -1; } @@ -228,6 +232,7 @@ static void draw_osd(void) vo_draw_text(image_width, image_height, draw_alpha); } +#ifdef CONFIG_LIBSWSCALE_INTERNALS static void deinterleave_fields(uint8_t *ptr, const int stride, const int img_height) { @@ -258,12 +263,13 @@ static void deinterleave_fields(uint8_t *ptr, const int stride, } free(line_state); } +#endif static void vo_y4m_write(const void *ptr, const size_t num_bytes) { if (fwrite(ptr, 1, num_bytes, yuv_out) != num_bytes) - mp_msg(MSGT_VO,MSGL_ERR, - MSGTR_VO_YUV4MPEG_OutFileWriteError); + mp_tmsg(MSGT_VO,MSGL_ERR, + "Error writing image to output!"); } static int write_last_frame(void) @@ -318,14 +324,15 @@ static int write_last_frame(void) static void flip_page (void) { - uint8_t *upper_y, *upper_u, *upper_v, *rgb_buffer_lower; - int rgb_stride, uv_stride, field_height; - unsigned int i, low_ofs; - fprintf(yuv_out, "FRAME\n"); +#ifdef CONFIG_LIBSWSCALE_INTERNALS if (using_format != IMGFMT_YV12) { + uint8_t *upper_y, *upper_u, *upper_v, *rgb_buffer_lower; + int rgb_stride, uv_stride, field_height; + unsigned int i, low_ofs; + rgb_stride = image_width * 3; uv_stride = image_width / 2; @@ -374,6 +381,7 @@ static void flip_page (void) image_width, image_height, image_width, uv_stride, rgb_stride); } +#endif /* Write progressive frame */ vo_y4m_write(image, write_bytes); @@ -458,9 +466,11 @@ static int query_format(uint32_t format) { case IMGFMT_YV12: return VFCAP_CSP_SUPPORTED|VFCAP_OSD|VFCAP_ACCEPT_STRIDE; +#ifdef CONFIG_LIBSWSCALE_INTERNALS case IMGFMT_BGR|24: case IMGFMT_RGB|24: return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_OSD|VFCAP_ACCEPT_STRIDE; +#endif } } else @@ -470,9 +480,11 @@ static int query_format(uint32_t format) { case IMGFMT_YV12: return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_OSD|VFCAP_ACCEPT_STRIDE; +#ifdef CONFIG_LIBSWSCALE_INTERNALS case IMGFMT_BGR|24: case IMGFMT_RGB|24: return VFCAP_CSP_SUPPORTED|VFCAP_OSD|VFCAP_ACCEPT_STRIDE; +#endif } } return 0; @@ -524,7 +536,7 @@ static int preinit(const char *arg) il_bf = 0; yuv_filename = strdup("stream.yuv"); if (subopt_parse(arg, subopts) != 0) { - mp_msg(MSGT_VO, MSGL_FATAL, MSGTR_VO_YUV4MPEG_UnknownSubDev, arg); + mp_tmsg(MSGT_VO, MSGL_FATAL, "Unknown subdevice: %s", arg); return -1; } @@ -538,22 +550,22 @@ static int preinit(const char *arg) switch (config_interlace) { case Y4M_ILACE_TOP_FIRST: - mp_msg(MSGT_VO,MSGL_STATUS, - MSGTR_VO_YUV4MPEG_InterlacedTFFMode); + mp_tmsg(MSGT_VO,MSGL_STATUS, + "Using interlaced output mode, top-field first."); break; case Y4M_ILACE_BOTTOM_FIRST: - mp_msg(MSGT_VO,MSGL_STATUS, - MSGTR_VO_YUV4MPEG_InterlacedBFFMode); + mp_tmsg(MSGT_VO,MSGL_STATUS, + "Using interlaced output mode, bottom-field first."); break; default: - mp_msg(MSGT_VO,MSGL_STATUS, - MSGTR_VO_YUV4MPEG_ProgressiveMode); + mp_tmsg(MSGT_VO,MSGL_STATUS, + "Using (default) progressive frame mode."); break; } return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_zr.c b/libvo/vo_zr.c index e8d1f23e11..9b7968a6ba 100644 --- a/libvo/vo_zr.c +++ b/libvo/vo_zr.c @@ -830,7 +830,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_zr2.c b/libvo/vo_zr2.c index 21347cb1d7..2bad93a731 100644 --- a/libvo/vo_zr2.c +++ b/libvo/vo_zr2.c @@ -449,7 +449,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, return 0; } -static int control(uint32_t request, void *data, ...) { +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); diff --git a/libvo/vosub_vidix.c b/libvo/vosub_vidix.c index a6f261130b..9b3c941c4d 100644 --- a/libvo/vosub_vidix.c +++ b/libvo/vosub_vidix.c @@ -44,6 +44,7 @@ #include "video_out.h" #include "sub.h" #include "vosub_vidix.h" +#include "old_vo_wrapper.h" #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" @@ -59,7 +60,7 @@ static int video_on=0; static vidix_capability_t vidix_cap; static vidix_playback_t vidix_play; static vidix_fourcc_t vidix_fourcc; -static vo_functions_t * vo_server; +static struct vo_old_functions *vo_server; static vidix_yuv_t dstrides; /*static uint32_t (*server_control)(uint32_t request, void *data, ...);*/ @@ -68,7 +69,7 @@ int vidix_start(void) int err; if((err=vdlPlaybackOn(vidix_handler))!=0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_CantStartPlayback,strerror(err)); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Can't start playback: %s\n",strerror(err)); return -1; } video_on=1; @@ -80,7 +81,7 @@ int vidix_stop(void) int err; if((err=vdlPlaybackOff(vidix_handler))!=0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_CantStopPlayback,strerror(err)); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Can't stop playback: %s\n",strerror(err)); return -1; } video_on=0; @@ -96,7 +97,7 @@ void vidix_term( void ) // vo_server->control=server_control; } -static uint32_t vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -160,7 +161,7 @@ static uint32_t vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h return -1; } -static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -178,7 +179,7 @@ static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h if (vidix_play.flags & VID_PLAY_INTERLEAVED_UV) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SUB_VIDIX_InterleavedUvForYuv410pNotSupported); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SUB_VIDIX] Interleaved UV for YUV410P not supported.\n"); } else { @@ -206,7 +207,7 @@ static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h return -1; } -static uint32_t vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -223,7 +224,7 @@ static uint32_t vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,in return 0; } -static uint32_t vidix_draw_slice_nv12(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_nv12(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -251,9 +252,9 @@ static uint32_t vidix_draw_slice_nv12(uint8_t *image[], int stride[], int w,int return 0; } -static uint32_t vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawsliceWasCalled); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SUB_VIDIX] Dummy vidix_draw_slice() was called.\n"); return -1; } @@ -269,9 +270,9 @@ static uint32_t vidix_draw_image(mp_image_t *mpi){ return VO_TRUE; } -static uint32_t vidix_draw_frame(uint8_t *image[]) +static int vidix_draw_frame(uint8_t *image[]) { - mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawframeWasCalled); + mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_SUB_VIDIX] Dummy vidix_draw_frame() was called.\n"); return -1; } @@ -391,7 +392,7 @@ int vidix_init(unsigned src_width,unsigned src_height, if(vidix_query_fourcc(format) == 0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_UnsupportedFourccForThisVidixDriver, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Unsupported FourCC for this VIDIX driver: %x (%s).\n", format,vo_format_name(format)); return -1; } @@ -401,7 +402,7 @@ int vidix_init(unsigned src_width,unsigned src_height, ((vidix_cap.maxheight != -1) && (vid_h > vidix_cap.maxheight)) || ((vidix_cap.minwidth != -1 ) && (vid_h < vidix_cap.minheight))) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedResolution, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Video server has unsupported resolution (%dx%d), supported: %dx%d-%dx%d.\n", vid_w, vid_h, vidix_cap.minwidth, vidix_cap.minheight, vidix_cap.maxwidth, vidix_cap.maxheight); return -1; @@ -423,19 +424,19 @@ int vidix_init(unsigned src_width,unsigned src_height, } if(err) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedColorDepth + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Video server has unsupported color depth by vidix (%d).\n" ,vidix_fourcc.depth); return -1; } if((dst_width > src_width || dst_height > src_height) && (vidix_cap.flags & FLAG_UPSCALER) != FLAG_UPSCALER) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_DriverCantUpscaleImage, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] VIDIX driver can't upscale image (%d%d -> %d%d).\n", src_width, src_height, dst_width, dst_height); return -1; } if((dst_width > src_width || dst_height > src_height) && (vidix_cap.flags & FLAG_DOWNSCALER) != FLAG_DOWNSCALER) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_DriverCantDownscaleImage, + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] VIDIX driver can't downscale image (%d%d -> %d%d).\n", src_width, src_height, dst_width, dst_height); return -1; } @@ -463,7 +464,7 @@ int vidix_init(unsigned src_width,unsigned src_height, if((err=vdlConfigPlayback(vidix_handler,&vidix_play))!=0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_CantConfigurePlayback,strerror(err)); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Can't configure playback: %s.\n",strerror(err)); return -1; } if ( mp_msg_test(MSGT_VO,MSGL_V) ) { @@ -576,7 +577,7 @@ static uint32_t vidix_get_image(mp_image_t *mpi) return VO_FALSE; } -uint32_t vidix_control(uint32_t request, void *data, ...) +uint32_t vidix_control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -596,36 +597,31 @@ uint32_t vidix_control(uint32_t request, void *data, ...) return VO_TRUE; case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; vidix_video_eq_t info; if(!video_on) return VO_FALSE; - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); -// printf("vidix seteq %s -> %d \n",data,value); + struct voctrl_set_equalizer_args *args = data; /* vidix eq ranges are -1000..1000 */ - if (!strcasecmp(data, "brightness")) + if (!strcasecmp(args->name, "brightness")) { - info.brightness = value*10; + info.brightness = args->value*10; info.cap = VEQ_CAP_BRIGHTNESS; } - else if (!strcasecmp(data, "contrast")) + else if (!strcasecmp(args->name, "contrast")) { - info.contrast = value*10; + info.contrast = args->value*10; info.cap = VEQ_CAP_CONTRAST; } - else if (!strcasecmp(data, "saturation")) + else if (!strcasecmp(args->name, "saturation")) { - info.saturation = value*10; + info.saturation = args->value*10; info.cap = VEQ_CAP_SATURATION; } - else if (!strcasecmp(data, "hue")) + else if (!strcasecmp(args->name, "hue")) { - info.hue = value*10; + info.hue = args->value*10; info.cap = VEQ_CAP_HUE; } @@ -635,38 +631,34 @@ uint32_t vidix_control(uint32_t request, void *data, ...) } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; vidix_video_eq_t info; if(!video_on) return VO_FALSE; if (vdlPlaybackGetEq(vidix_handler, &info) != 0) return VO_FALSE; - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); + struct voctrl_get_equalizer_args *args = data; /* vidix eq ranges are -1000..1000 */ - if (!strcasecmp(data, "brightness")) + if (!strcasecmp(args->name, "brightness")) { if (info.cap & VEQ_CAP_BRIGHTNESS) - *value = info.brightness/10; + *args->valueptr = info.brightness/10; } - else if (!strcasecmp(data, "contrast")) + else if (!strcasecmp(args->name, "contrast")) { if (info.cap & VEQ_CAP_CONTRAST) - *value = info.contrast/10; + *args->valueptr = info.contrast/10; } - else if (!strcasecmp(data, "saturation")) + else if (!strcasecmp(args->name, "saturation")) { if (info.cap & VEQ_CAP_SATURATION) - *value = info.saturation/10; + *args->valueptr = info.saturation/10; } - else if (!strcasecmp(data, "hue")) + else if (!strcasecmp(args->name, "hue")) { if (info.cap & VEQ_CAP_HUE) - *value = info.hue/10; + *args->valueptr = info.hue/10; } return VO_TRUE; @@ -677,7 +669,7 @@ uint32_t vidix_control(uint32_t request, void *data, ...) // return server_control(request,data); //VO_NOTIMPL; } -int vidix_preinit(const char *drvname,vo_functions_t *server) +int vidix_preinit(const char *drvname, struct vo_old_functions *server) { int err; if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { @@ -689,12 +681,12 @@ int vidix_preinit(const char *drvname,vo_functions_t *server) if(vidix_handler == NULL) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_CouldntFindWorkingVidixDriver); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Couldn't find working VIDIX driver.\n"); return -1; } if((err=vdlGetCapability(vidix_handler,&vidix_cap)) != 0) { - mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_CouldntGetCapability,strerror(err)); + mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_SUB_VIDIX] Couldn't get capability: %s.\n",strerror(err)); return -1; } mp_msg(MSGT_VO,MSGL_V, "[VO_SUB_VIDIX] Description: %s.\n", vidix_cap.name); diff --git a/libvo/vosub_vidix.h b/libvo/vosub_vidix.h index 128409e95a..7b05607de6 100644 --- a/libvo/vosub_vidix.h +++ b/libvo/vosub_vidix.h @@ -27,7 +27,7 @@ #include "video_out.h" /* drvname can be NULL */ -int vidix_preinit(const char *drvname,vo_functions_t *server); +int vidix_preinit(const char *drvname, struct vo_old_functions *server); int vidix_init(unsigned src_width,unsigned src_height, unsigned dest_x,unsigned dest_y,unsigned dst_width, unsigned dst_height,unsigned format,unsigned dest_bpp, @@ -35,7 +35,7 @@ int vidix_init(unsigned src_width,unsigned src_height, int vidix_start(void); int vidix_stop(void); void vidix_term( void ); -uint32_t vidix_control(uint32_t request, void *data, ...); +uint32_t vidix_control(uint32_t request, void *data); uint32_t vidix_query_fourcc(uint32_t fourcc); #include "vidix/vidix.h" diff --git a/libvo/w32_common.c b/libvo/w32_common.c index 56c56977f0..99ebd76979 100644 --- a/libvo/w32_common.c +++ b/libvo/w32_common.c @@ -21,6 +21,8 @@ #include <windows.h> #include <windowsx.h> +// To get "#define vo_ontop global_vo->opts->vo_ontop" etc +#include "old_vo_defines.h" #include "osdep/keycodes.h" #include "input/input.h" #include "input/mouse.h" @@ -39,6 +41,7 @@ extern int enable_mouse_movements; static const char classname[] = "MPlayer - The Movie Player"; int vo_vm = 0; +static int depthonscreen; // last non-fullscreen extends static int prev_width; static int prev_height; @@ -116,7 +119,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l xborder = (r.right - r.left) - wpos->cx; yborder = (r.bottom - r.top) - wpos->cy; wpos->cx -= xborder; wpos->cy -= yborder; - aspect_fit(&wpos->cx, &wpos->cy, wpos->cx, wpos->cy); + aspect_fit(global_vo, &wpos->cx, &wpos->cy, wpos->cx, wpos->cy); wpos->cx += xborder; wpos->cy += yborder; } return 0; @@ -163,7 +166,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l char cmd_str[40]; snprintf(cmd_str, sizeof(cmd_str), "set_mouse_pos %i %i", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - mp_input_queue_cmd(mp_input_parse_cmd(cmd_str)); + mp_input_queue_cmd(global_vo->input_ctx, mp_input_parse_cmd(cmd_str)); } break; case WM_MOUSEWHEEL: @@ -283,7 +286,7 @@ static void updateScreenProperties(void) { vo_screenwidth = dm.dmPelsWidth; vo_screenheight = dm.dmPelsHeight; - vo_depthonscreen = dm.dmBitsPerPel; + depthonscreen = dm.dmBitsPerPel; w32_update_xinerama_info(); } @@ -293,7 +296,7 @@ static void changeMode(void) { dm.dmDriverExtra = 0; dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - dm.dmBitsPerPel = vo_depthonscreen; + dm.dmBitsPerPel = depthonscreen; dm.dmPelsWidth = vo_screenwidth; dm.dmPelsHeight = vo_screenheight; @@ -303,7 +306,7 @@ static void changeMode(void) { int i; for (i = 0; EnumDisplaySettings(0, i, &dm); ++i) { int score = (dm.dmPelsWidth - o_dwidth) * (dm.dmPelsHeight - o_dheight); - if (dm.dmBitsPerPel != vo_depthonscreen) continue; + if (dm.dmBitsPerPel != depthonscreen) continue; if (dm.dmPelsWidth < o_dwidth) continue; if (dm.dmPelsHeight < o_dheight) continue; @@ -393,7 +396,7 @@ static int createRenderingContext(void) { SetPixelFormat(vo_hdc, pf, &pfd); - mp_msg(MSGT_VO, MSGL_V, "vo: win32: running at %dx%d with depth %d\n", vo_screenwidth, vo_screenheight, vo_depthonscreen); + mp_msg(MSGT_VO, MSGL_V, "vo: win32: running at %dx%d with depth %d\n", vo_screenwidth, vo_screenheight, depthonscreen); ReleaseDC(vo_window, vo_hdc); return 1; @@ -563,7 +566,7 @@ void vo_w32_uninit(void) { mp_msg(MSGT_VO, MSGL_V, "vo: win32: uninit\n"); resetMode(); ShowCursor(1); - vo_depthonscreen = 0; + depthonscreen = 0; DestroyWindow(vo_window); vo_window = 0; UnregisterClass(classname, 0); diff --git a/libvo/x11_common.c b/libvo/x11_common.c index d1911401ce..66af7feabd 100644 --- a/libvo/x11_common.c +++ b/libvo/x11_common.c @@ -23,10 +23,12 @@ #include <limits.h> #include "config.h" +#include "options.h" #include "mp_msg.h" #include "mp_fifo.h" #include "libavutil/common.h" #include "x11_common.h" +#include "talloc.h" #ifdef X11_FULLSCREEN @@ -75,11 +77,6 @@ #include "input/input.h" #include "input/mouse.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#include "mplayer.h" -#endif - #define WIN_LAYER_ONBOTTOM 2 #define WIN_LAYER_NORMAL 4 #define WIN_LAYER_ONTOP 6 @@ -87,56 +84,26 @@ extern int enable_mouse_movements; int fs_layer = WIN_LAYER_ABOVE_DOCK; -static int orig_layer = 0; -static int old_gravity = NorthWestGravity; int stop_xscreensaver = 0; static int dpms_disabled = 0; char *mDisplayName = NULL; -Display *mDisplay = NULL; -Window mRootWin; -int mScreen; -int mLocalDisplay; - -/* output window id */ -int vo_mouse_autohide = 0; -int vo_wm_type = 0; -int vo_fs_type = 0; // needs to be accessible for GUI X11 code -static int vo_fs_flip = 0; + char **vo_fstype_list; /* 1 means that the WM is metacity (broken as hell) */ int metacity_hack = 0; -static Atom XA_NET_SUPPORTED; -static Atom XA_NET_WM_STATE; -static Atom XA_NET_WM_STATE_FULLSCREEN; -static Atom XA_NET_WM_STATE_ABOVE; -static Atom XA_NET_WM_STATE_STAYS_ON_TOP; -static Atom XA_NET_WM_STATE_BELOW; -static Atom XA_NET_WM_PID; -static Atom XA_WIN_PROTOCOLS; -static Atom XA_WIN_LAYER; -static Atom XA_WIN_HINTS; -static Atom XAWM_PROTOCOLS; -static Atom XAWM_DELETE_WINDOW; - -#define XA_INIT(x) XA##x = XInternAtom(mDisplay, #x, False) - -static int vo_old_x = 0; -static int vo_old_y = 0; -static int vo_old_width = 0; -static int vo_old_height = 0; - #ifdef CONFIG_XF86VM XF86VidModeModeInfo **vidmodes = NULL; XF86VidModeModeLine modeline; #endif static int vo_x11_get_fs_type(int supported); - +static void saver_off(Display *); +static void saver_on(Display *); /* * Sends the EWMH fullscreen state event. @@ -145,12 +112,12 @@ static int vo_x11_get_fs_type(int supported); * _NET_WM_STATE_ADD -- add state * _NET_WM_STATE_TOGGLE -- toggle */ -void vo_x11_ewmh_fullscreen(int action) +void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action) { assert(action == _NET_WM_STATE_REMOVE || action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); - if (vo_fs_type & vo_wm_FULLSCREEN) + if (x11->fs_type & vo_wm_FULLSCREEN) { XEvent xev; @@ -158,32 +125,32 @@ void vo_x11_ewmh_fullscreen(int action) xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; - xev.xclient.message_type = XA_NET_WM_STATE; - xev.xclient.window = vo_window; + xev.xclient.message_type = x11->XA_NET_WM_STATE; + xev.xclient.window = x11->window; xev.xclient.format = 32; xev.xclient.data.l[0] = action; - xev.xclient.data.l[1] = XA_NET_WM_STATE_FULLSCREEN; + xev.xclient.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; /* finally send that damn thing */ - if (!XSendEvent(mDisplay, DefaultRootWindow(mDisplay), False, + if (!XSendEvent(x11->display, DefaultRootWindow(x11->display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev)) { - mp_msg(MSGT_VO, MSGL_ERR, MSGTR_EwmhFullscreenStateFailed); + mp_tmsg(MSGT_VO, MSGL_ERR, "\nX11: Couldn't send EWMH fullscreen event!\n"); } } } -void vo_hidecursor(Display * disp, Window win) +static void vo_hidecursor(Display * disp, Window win) { Cursor no_ptr; Pixmap bm_no; XColor black, dummy; Colormap colormap; - static char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + const char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (WinID == 0) return; // do not hide if playing on the root window @@ -202,7 +169,7 @@ void vo_hidecursor(Display * disp, Window win) XFreeColors(disp,colormap,&black.pixel,1,0); } -void vo_showcursor(Display * disp, Window win) +static void vo_showcursor(Display * disp, Window win) { if (WinID == 0) return; @@ -233,7 +200,7 @@ static int x11_errorhandler(Display * display, XErrorEvent * event) void fstype_help(void) { - mp_msg(MSGT_VO, MSGL_INFO, MSGTR_AvailableFsType); + mp_tmsg(MSGT_VO, MSGL_INFO, "Available fullscreen layer change modes:\n"); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FULL_SCREEN_TYPES\n"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "none", @@ -278,9 +245,9 @@ static void fstype_dump(int fstype) "[x11] Current fstype setting doesn't honour any X atoms\n"); } -static int net_wm_support_state_test(Atom atom) +static int net_wm_support_state_test(struct vo_x11_state *x11, Atom atom) { -#define NET_WM_STATE_TEST(x) { if (atom == XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } } +#define NET_WM_STATE_TEST(x) { if (atom == x11->XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } } NET_WM_STATE_TEST(FULLSCREEN); NET_WM_STATE_TEST(ABOVE); @@ -289,20 +256,22 @@ static int net_wm_support_state_test(Atom atom) return 0; } -static int x11_get_property(Atom type, Atom ** args, unsigned long *nitems) +static int x11_get_property(struct vo_x11_state *x11, Atom type, Atom ** args, + unsigned long *nitems) { int format; unsigned long bytesafter; return Success == - XGetWindowProperty(mDisplay, mRootWin, type, 0, 16384, False, + XGetWindowProperty(x11->display, x11->rootwin, type, 0, 16384, False, AnyPropertyType, &type, &format, nitems, &bytesafter, (unsigned char **) args) && *nitems > 0; } -static int vo_wm_detect(void) +static int vo_wm_detect(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; int i; int wm = 0; unsigned long nitems; @@ -312,12 +281,12 @@ static int vo_wm_detect(void) return 0; // -- supports layers - if (x11_get_property(XA_WIN_PROTOCOLS, &args, &nitems)) + if (x11_get_property(x11, x11->XA_WIN_PROTOCOLS, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports layers.\n"); for (i = 0; i < nitems; i++) { - if (args[i] == XA_WIN_LAYER) + if (args[i] == x11->XA_WIN_LAYER) { wm |= vo_wm_LAYER; metacity_hack |= 1; @@ -337,11 +306,11 @@ static int vo_wm_detect(void) } } // --- netwm - if (x11_get_property(XA_NET_SUPPORTED, &args, &nitems)) + if (x11_get_property(x11, x11->XA_NET_SUPPORTED, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports NetWM.\n"); for (i = 0; i < nitems; i++) - wm |= net_wm_support_state_test(args[i]); + wm |= net_wm_support_state_test(vo->x11, args[i]); XFree(args); } @@ -350,7 +319,8 @@ static int vo_wm_detect(void) return wm; } -static void init_atoms(void) +#define XA_INIT(x) x11->XA##x = XInternAtom(x11->display, #x, False) +static void init_atoms(struct vo_x11_state *x11) { XA_INIT(_NET_SUPPORTED); XA_INIT(_NET_WM_STATE); @@ -366,21 +336,22 @@ static void init_atoms(void) XA_INIT(WM_DELETE_WINDOW); } -void update_xinerama_info(void) { +void update_xinerama_info(struct vo *vo) { + struct MPOpts *opts = vo->opts; int screen = xinerama_screen; xinerama_x = xinerama_y = 0; #ifdef CONFIG_XINERAMA - if (screen >= -1 && XineramaIsActive(mDisplay)) + if (screen >= -1 && XineramaIsActive(vo->x11->display)) { XineramaScreenInfo *screens; int num_screens; - screens = XineramaQueryScreens(mDisplay, &num_screens); + screens = XineramaQueryScreens(vo->x11->display, &num_screens); if (screen >= num_screens) screen = num_screens - 1; if (screen == -1) { - int x = vo_dx + vo_dwidth / 2; - int y = vo_dy + vo_dheight / 2; + int x = vo->dx + vo->dwidth / 2; + int y = vo->dy + vo->dheight / 2; for (screen = num_screens - 1; screen > 0; screen--) { int left = screens[screen].x_org; int right = left + screens[screen].width; @@ -392,19 +363,21 @@ void update_xinerama_info(void) { } if (screen < 0) screen = 0; - vo_screenwidth = screens[screen].width; - vo_screenheight = screens[screen].height; + opts->vo_screenwidth = screens[screen].width; + opts->vo_screenheight = screens[screen].height; xinerama_x = screens[screen].x_org; xinerama_y = screens[screen].y_org; XFree(screens); } #endif - aspect_save_screenres(vo_screenwidth, vo_screenheight); + aspect_save_screenres(vo, opts->vo_screenwidth, opts->vo_screenheight); } -int vo_init(void) +int vo_init(struct vo *vo) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; // int mScreen; int depth, bpp; unsigned int mask; @@ -420,9 +393,9 @@ int vo_init(void) if (vo_rootwin) WinID = 0; // use root window - if (vo_depthonscreen) + if (x11->depthonscreen) { - saver_off(mDisplay); + saver_off(x11->display); return 1; // already called } @@ -438,52 +411,52 @@ int vo_init(void) mp_msg(MSGT_VO, MSGL_V, "X11 opening display: %s\n", dispName); - mDisplay = XOpenDisplay(dispName); - if (!mDisplay) + x11->display = XOpenDisplay(dispName); + if (!x11->display) { mp_msg(MSGT_VO, MSGL_ERR, "vo: couldn't open the X11 display (%s)!\n", dispName); return 0; } - mScreen = DefaultScreen(mDisplay); // screen ID - mRootWin = RootWindow(mDisplay, mScreen); // root window ID + x11->screen = DefaultScreen(x11->display); // screen ID + x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID - init_atoms(); + init_atoms(vo->x11); #ifdef CONFIG_XF86VM { int clock; - XF86VidModeGetModeLine(mDisplay, mScreen, &clock, &modeline); - if (!vo_screenwidth) - vo_screenwidth = modeline.hdisplay; - if (!vo_screenheight) - vo_screenheight = modeline.vdisplay; + XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline); + if (!opts->vo_screenwidth) + opts->vo_screenwidth = modeline.hdisplay; + if (!opts->vo_screenheight) + opts->vo_screenheight = modeline.vdisplay; } #endif { - if (!vo_screenwidth) - vo_screenwidth = DisplayWidth(mDisplay, mScreen); - if (!vo_screenheight) - vo_screenheight = DisplayHeight(mDisplay, mScreen); + if (!opts->vo_screenwidth) + opts->vo_screenwidth = DisplayWidth(x11->display, x11->screen); + if (!opts->vo_screenheight) + opts->vo_screenheight = DisplayHeight(x11->display, x11->screen); } // get color depth (from root window, or the best visual): - XGetWindowAttributes(mDisplay, mRootWin, &attribs); + XGetWindowAttributes(x11->display, x11->rootwin, &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) { Visual *visual; - depth = vo_find_depth_from_visuals(mDisplay, mScreen, &visual); + depth = vo_find_depth_from_visuals(x11->display, x11->screen, &visual); if (depth != -1) - mXImage = XCreateImage(mDisplay, visual, depth, ZPixmap, + mXImage = XCreateImage(x11->display, visual, depth, ZPixmap, 0, NULL, 1, 1, 8, 1); } else mXImage = - XGetImage(mDisplay, mRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); + XGetImage(x11->display, x11->rootwin, 0, 0, 1, 1, AllPlanes, ZPixmap); - vo_depthonscreen = depth; // display depth on screen + x11->depthonscreen = depth; // display depth on screen // get bits/pixel from XImage structure: if (mXImage == NULL) @@ -493,15 +466,15 @@ int vo_init(void) { /* * for the depth==24 case, the XImage structures might use - * 24 or 32 bits of data per pixel. The global variable - * vo_depthonscreen stores the amount of data per pixel in the + * 24 or 32 bits of data per pixel. The x11->depthonscreen + * field stores the amount of data per pixel in the * XImage structure! * * Maybe we should rename vo_depthonscreen to (or add) vo_bpp? */ bpp = mXImage->bits_per_pixel; - if ((vo_depthonscreen + 7) / 8 != (bpp + 7) / 8) - vo_depthonscreen = bpp; // by A'rpi + if ((x11->depthonscreen + 7) / 8 != (bpp + 7) / 8) + x11->depthonscreen = bpp; // by A'rpi mask = mXImage->red_mask | mXImage->green_mask | mXImage->blue_mask; mp_msg(MSGT_VO, MSGL_V, @@ -509,12 +482,12 @@ int vo_init(void) mXImage->red_mask, mXImage->green_mask, mXImage->blue_mask); XDestroyImage(mXImage); } - if (((vo_depthonscreen + 7) / 8) == 2) + if (((x11->depthonscreen + 7) / 8) == 2) { if (mask == 0x7FFF) - vo_depthonscreen = 15; + x11->depthonscreen = 15; else if (mask == 0xFFFF) - vo_depthonscreen = 16; + x11->depthonscreen = 16; } // XCloseDisplay( mDisplay ); /* slightly improved local display detection AST */ @@ -523,27 +496,27 @@ int vo_init(void) else if (strncmp(dispName, "localhost:", 10) == 0) dispName += 9; if (*dispName == ':' && atoi(dispName + 1) < 10) - mLocalDisplay = 1; + x11->display_is_local = 1; else - mLocalDisplay = 0; + x11->display_is_local = 0; mp_msg(MSGT_VO, MSGL_V, "vo: X11 running at %dx%d with depth %d and %d bpp (\"%s\" => %s display)\n", - vo_screenwidth, vo_screenheight, depth, vo_depthonscreen, - dispName, mLocalDisplay ? "local" : "remote"); + opts->vo_screenwidth, opts->vo_screenheight, depth, x11->depthonscreen, + dispName, x11->display_is_local ? "local" : "remote"); - vo_wm_type = vo_wm_detect(); + x11->wm_type = vo_wm_detect(vo); - vo_fs_type = vo_x11_get_fs_type(vo_wm_type); + x11->fs_type = vo_x11_get_fs_type(x11->wm_type); - fstype_dump(vo_fs_type); + fstype_dump(x11->fs_type); - saver_off(mDisplay); + saver_off(x11->display); return 1; } -void vo_uninit(void) +void vo_uninit(struct vo_x11_state *x11) { - if (!mDisplay) + if (!x11->display) { mp_msg(MSGT_VO, MSGL_V, "vo: x11 uninit called but X11 not initialized..\n"); @@ -552,9 +525,10 @@ void vo_uninit(void) // if( !vo_depthonscreen ) return; mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n"); XSetErrorHandler(NULL); - XCloseDisplay(mDisplay); - vo_depthonscreen = 0; - mDisplay = NULL; + XCloseDisplay(x11->display); + x11->depthonscreen = 0; + x11->display = NULL; + talloc_free(x11); } #include "osdep/keycodes.h" @@ -569,11 +543,12 @@ static const struct keymap keysym_map[] = { {0, 0} }; -static void vo_x11_putkey_ext(int keysym) +static void vo_x11_putkey_ext(struct vo *vo, int keysym) { + struct mp_fifo *f = vo->key_fifo; int mpkey = lookup_keymap_table(keysym_map, keysym); if (mpkey) - mplayer_put_key(mpkey); + mplayer_put_key(f, mpkey); } #endif @@ -612,7 +587,7 @@ static const struct keymap keymap[] = { {0, 0} }; -void vo_x11_putkey(int key) +void vo_x11_putkey(struct vo *vo, int key) { static const char *passthrough_keys = " -+*/<>`~!@#$%^&()_{}:;\"\',.?\\|=[]"; int mpkey = 0; @@ -626,7 +601,7 @@ void vo_x11_putkey(int key) mpkey = lookup_keymap_table(keymap, key); if (mpkey) - mplayer_put_key(mpkey); + mplayer_put_key(vo->key_fifo, mpkey); } @@ -672,12 +647,9 @@ typedef struct static MotifWmHints vo_MotifWmHints; static Atom vo_MotifHints = None; -void vo_x11_decoration(Display * vo_Display, Window w, int d) +void vo_x11_decoration(struct vo *vo, int d) { - static unsigned int olddecor = MWM_DECOR_ALL; - static unsigned int oldfuncs = - MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | - MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE; + struct vo_x11_state *x11 = vo->x11; Atom mtype; int mformat; unsigned long mn, mb; @@ -687,26 +659,27 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) if (vo_fsmode & 8) { - XSetTransientForHint(vo_Display, w, - RootWindow(vo_Display, mScreen)); + XSetTransientForHint(x11->display, x11->window, + RootWindow(x11->display, x11->screen)); } - vo_MotifHints = XInternAtom(vo_Display, "_MOTIF_WM_HINTS", 0); + vo_MotifHints = XInternAtom(x11->display, "_MOTIF_WM_HINTS", 0); if (vo_MotifHints != None) { if (!d) { MotifWmHints *mhints = NULL; - XGetWindowProperty(vo_Display, w, vo_MotifHints, 0, 20, False, + XGetWindowProperty(x11->display, x11->window, + vo_MotifHints, 0, 20, False, vo_MotifHints, &mtype, &mformat, &mn, &mb, (unsigned char **) &mhints); if (mhints) { if (mhints->flags & MWM_HINTS_DECORATIONS) - olddecor = mhints->decorations; + x11->olddecor = mhints->decorations; if (mhints->flags & MWM_HINTS_FUNCTIONS) - oldfuncs = mhints->functions; + x11->oldfuncs = mhints->functions; XFree(mhints); } } @@ -716,8 +689,8 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; if (d) { - vo_MotifWmHints.functions = oldfuncs; - d = olddecor; + vo_MotifWmHints.functions = x11->oldfuncs; + d = x11->olddecor; } #if 0 vo_MotifWmHints.decorations = @@ -726,113 +699,90 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) vo_MotifWmHints.decorations = d | ((vo_fsmode & 2) ? MWM_DECOR_MENU : 0); #endif - XChangeProperty(vo_Display, w, vo_MotifHints, vo_MotifHints, 32, + XChangeProperty(x11->display, x11->window, vo_MotifHints, + vo_MotifHints, 32, PropModeReplace, (unsigned char *) &vo_MotifWmHints, (vo_fsmode & 4) ? 4 : 5); } } -void vo_x11_classhint(Display * display, Window window, char *name) +void vo_x11_classhint(struct vo *vo, Window window, char *name) { + struct vo_x11_state *x11 = vo->x11; XClassHint wmClass; pid_t pid = getpid(); wmClass.res_name = vo_winname ? vo_winname : name; wmClass.res_class = "MPlayer"; - XSetClassHint(display, window, &wmClass); - XChangeProperty(display, window, XA_NET_WM_PID, XA_CARDINAL, 32, - PropModeReplace, (unsigned char *) &pid, 1); + XSetClassHint(x11->display, window, &wmClass); + XChangeProperty(x11->display, window, x11->XA_NET_WM_PID, XA_CARDINAL, + 32, PropModeReplace, (unsigned char *) &pid, 1); } -Window vo_window = None; -GC vo_gc = NULL; -GC f_gc = NULL; -XSizeHints vo_hint; - -#ifdef CONFIG_GUI -void vo_setwindow(Window w, GC g) -{ - vo_window = w; - vo_gc = g; -} -#endif - -void vo_x11_uninit(void) +void vo_x11_uninit(struct vo *vo) { - saver_on(mDisplay); - if (vo_window != None) - vo_showcursor(mDisplay, vo_window); + struct vo_x11_state *x11 = vo->x11; + saver_on(x11->display); + if (x11->window != None) + vo_showcursor(x11->display, x11->window); - if (f_gc) + if (x11->f_gc) { - XFreeGC(mDisplay, f_gc); - f_gc = NULL; + XFreeGC(vo->x11->display, x11->f_gc); + x11->f_gc = NULL; } -#ifdef CONFIG_GUI - /* destroy window only if it's not controlled by the GUI */ - if (!use_gui) -#endif { - if (vo_gc) + if (x11->vo_gc) { - XSetBackground(mDisplay, vo_gc, 0); - XFreeGC(mDisplay, vo_gc); - vo_gc = NULL; + XSetBackground(vo->x11->display, x11->vo_gc, 0); + XFreeGC(vo->x11->display, x11->vo_gc); + x11->vo_gc = NULL; } - if (vo_window != None) + if (x11->window != None) { - XClearWindow(mDisplay, vo_window); + XClearWindow(x11->display, x11->window); if (WinID < 0) { XEvent xev; - XUnmapWindow(mDisplay, vo_window); - XDestroyWindow(mDisplay, vo_window); + XUnmapWindow(x11->display, x11->window); + XDestroyWindow(x11->display, x11->window); do { - XNextEvent(mDisplay, &xev); + XNextEvent(x11->display, &xev); } while (xev.type != DestroyNotify - || xev.xdestroywindow.event != vo_window); + || xev.xdestroywindow.event != x11->window); } - vo_window = None; + x11->window = None; } vo_fs = 0; - vo_old_width = vo_old_height = 0; + x11->vo_old_width = x11->vo_old_height = 0; } } -static unsigned int mouse_timer; -static int mouse_waiting_hide; - -int vo_x11_check_events(Display * mydisplay) +int vo_x11_check_events(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *display = vo->x11->display; int ret = 0; XEvent Event; char buf[100]; KeySym keySym; - static XComposeStatus stat; // unsigned long vo_KeyTable[512]; - if ((vo_mouse_autohide) && mouse_waiting_hide && - (GetTimerMS() - mouse_timer >= 1000)) { - vo_hidecursor(mydisplay, vo_window); - mouse_waiting_hide = 0; + if ((x11->vo_mouse_autohide) && x11->mouse_waiting_hide && + (GetTimerMS() - x11->mouse_timer >= 1000)) { + vo_hidecursor(display, x11->window); + x11->mouse_waiting_hide = 0; } - while (XPending(mydisplay)) + while (XPending(display)) { - XNextEvent(mydisplay, &Event); -#ifdef CONFIG_GUI - if (use_gui) - { - guiGetEvent(0, (char *) &Event); - if (vo_window != Event.xany.window) - continue; - } -#endif + XNextEvent(display, &Event); // printf("\rEvent.type=%X \n",Event.type); switch (Event.type) { @@ -840,15 +790,14 @@ int vo_x11_check_events(Display * mydisplay) ret |= VO_EVENT_EXPOSE; break; case ConfigureNotify: -// if (!vo_fs && (Event.xconfigure.width == vo_screenwidth || Event.xconfigure.height == vo_screenheight)) break; -// if (vo_fs && Event.xconfigure.width != vo_screenwidth && Event.xconfigure.height != vo_screenheight) break; - if (vo_window == None) +// if (!vo_fs && (Event.xconfigure.width == opts->vo_screenwidth || Event.xconfigure.height == opts->vo_screenheight)) break; +// if (vo_fs && Event.xconfigure.width != opts->vo_screenwidth && Event.xconfigure.height != opts->vo_screenheight) break; + if (x11->window == None) break; { - int old_w = vo_dwidth, old_h = vo_dheight; - int old_x = vo_dx, old_y = vo_dy; - vo_x11_update_geometry(); - if (vo_dwidth != old_w || vo_dheight != old_h || vo_dx != old_x || vo_dy != old_y) + int old_w = vo->dwidth, old_h = vo->dheight; + vo_x11_update_geometry(vo); + if (vo->dwidth != old_w || vo->dheight != old_h) ret |= VO_EVENT_RESIZE; } break; @@ -856,19 +805,15 @@ int vo_x11_check_events(Display * mydisplay) { int key; -#ifdef CONFIG_GUI - if ( use_gui ) { break; } -#endif - XLookupString(&Event.xkey, buf, sizeof(buf), &keySym, - &stat); + &x11->compose_status); #ifdef XF86XK_AudioPause - vo_x11_putkey_ext(keySym); + vo_x11_putkey_ext(vo, keySym); #endif key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym)); - vo_x11_putkey(key); + vo_x11_putkey(vo, key); ret |= VO_EVENT_KEYPRESS; } break; @@ -877,51 +822,42 @@ int vo_x11_check_events(Display * mydisplay) { char cmd_str[40]; sprintf(cmd_str,"set_mouse_pos %i %i",Event.xmotion.x, Event.xmotion.y); - mp_input_queue_cmd(mp_input_parse_cmd(cmd_str)); + mp_input_queue_cmd(vo->input_ctx, + mp_input_parse_cmd(cmd_str)); } - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } break; case ButtonPress: - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } -#ifdef CONFIG_GUI - // Ignore mouse button 1-3 under GUI. - if (use_gui && (Event.xbutton.button >= 1) - && (Event.xbutton.button <= 3)) - break; -#endif - mplayer_put_key((MOUSE_BTN0 + Event.xbutton.button - - 1) | MP_KEY_DOWN); + mplayer_put_key(vo->key_fifo, + (MOUSE_BTN0 + Event.xbutton.button - 1) + | MP_KEY_DOWN); break; case ButtonRelease: - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } -#ifdef CONFIG_GUI - // Ignore mouse button 1-3 under GUI. - if (use_gui && (Event.xbutton.button >= 1) - && (Event.xbutton.button <= 3)) - break; -#endif - mplayer_put_key(MOUSE_BTN0 + Event.xbutton.button - 1); + mplayer_put_key(vo->key_fifo, + MOUSE_BTN0 + Event.xbutton.button - 1); break; case PropertyNotify: { char *name = - XGetAtomName(mydisplay, Event.xproperty.atom); + XGetAtomName(display, Event.xproperty.atom); if (!name) break; @@ -932,14 +868,14 @@ int vo_x11_check_events(Display * mydisplay) } break; case MapNotify: - vo_hint.win_gravity = old_gravity; - XSetWMNormalHints(mDisplay, vo_window, &vo_hint); - vo_fs_flip = 0; + x11->vo_hint.win_gravity = x11->old_gravity; + XSetWMNormalHints(display, x11->window, &x11->vo_hint); + x11->fs_flip = 0; break; case ClientMessage: - if (Event.xclient.message_type == XAWM_PROTOCOLS && - Event.xclient.data.l[0] == XAWM_DELETE_WINDOW) - mplayer_put_key(KEY_CLOSE_WIN); + if (Event.xclient.message_type == x11->XAWM_PROTOCOLS && + Event.xclient.data.l[0] == x11->XAWM_DELETE_WINDOW) + mplayer_put_key(vo->key_fifo, KEY_CLOSE_WIN); break; } } @@ -949,69 +885,76 @@ int vo_x11_check_events(Display * mydisplay) /** * \brief sets the size and position of the non-fullscreen window. */ -void vo_x11_nofs_sizepos(int x, int y, int width, int height) +static void vo_x11_nofs_sizepos(struct vo *vo, int x, int y, + int width, int height) { - vo_x11_sizehint(x, y, width, height, 0); + struct vo_x11_state *x11 = vo->x11; + vo_x11_sizehint(vo, x, y, width, height, 0); if (vo_fs) { - vo_old_x = x; - vo_old_y = y; - vo_old_width = width; - vo_old_height = height; + x11->vo_old_x = x; + x11->vo_old_y = y; + x11->vo_old_width = width; + x11->vo_old_height = height; } else { - vo_dwidth = width; - vo_dheight = height; - XMoveResizeWindow(mDisplay, vo_window, x, y, width, height); + vo->dwidth = width; + vo->dheight = height; + if (vo->opts->force_window_position) + XMoveResizeWindow(vo->x11->display, vo->x11->window, x, y, width, + height); + else + XResizeWindow(vo->x11->display, vo->x11->window, width, height); } } -void vo_x11_sizehint(int x, int y, int width, int height, int max) +void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max) { - vo_hint.flags = 0; + struct vo_x11_state *x11 = vo->x11; + x11->vo_hint.flags = 0; if (vo_keepaspect) { - vo_hint.flags |= PAspect; - vo_hint.min_aspect.x = width; - vo_hint.min_aspect.y = height; - vo_hint.max_aspect.x = width; - vo_hint.max_aspect.y = height; + x11->vo_hint.flags |= PAspect; + x11->vo_hint.min_aspect.x = width; + x11->vo_hint.min_aspect.y = height; + x11->vo_hint.max_aspect.x = width; + x11->vo_hint.max_aspect.y = height; } - vo_hint.flags |= PPosition | PSize; - vo_hint.x = x; - vo_hint.y = y; - vo_hint.width = width; - vo_hint.height = height; + x11->vo_hint.flags |= PPosition | PSize; + x11->vo_hint.x = x; + x11->vo_hint.y = y; + x11->vo_hint.width = width; + x11->vo_hint.height = height; if (max) { - vo_hint.flags |= PMaxSize; - vo_hint.max_width = width; - vo_hint.max_height = height; + x11->vo_hint.flags |= PMaxSize; + x11->vo_hint.max_width = width; + x11->vo_hint.max_height = height; } else { - vo_hint.max_width = 0; - vo_hint.max_height = 0; + x11->vo_hint.max_width = 0; + x11->vo_hint.max_height = 0; } // Set minimum height/width to 4 to avoid off-by-one errors // and because mga_vid requires a minimal size of 4 pixels. - vo_hint.flags |= PMinSize; - vo_hint.min_width = vo_hint.min_height = 4; + x11->vo_hint.flags |= PMinSize; + x11->vo_hint.min_width = x11->vo_hint.min_height = 4; // Set the base size. A window manager might display the window // size to the user relative to this. // Setting these to width/height might be nice, but e.g. fluxbox can't handle it. - vo_hint.flags |= PBaseSize; - vo_hint.base_width = 0 /*width*/; - vo_hint.base_height = 0 /*height*/; + x11->vo_hint.flags |= PBaseSize; + x11->vo_hint.base_width = 0 /*width*/; + x11->vo_hint.base_height = 0 /*height*/; - vo_hint.flags |= PWinGravity; - vo_hint.win_gravity = StaticGravity; - XSetWMNormalHints(mDisplay, vo_window, &vo_hint); + x11->vo_hint.flags |= PWinGravity; + x11->vo_hint.win_gravity = StaticGravity; + XSetWMNormalHints(x11->display, x11->window, &x11->vo_hint); } -static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) +static int vo_x11_get_gnome_layer(struct vo_x11_state *x11, Window win) { Atom type; int format; @@ -1019,7 +962,7 @@ static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) unsigned long bytesafter; unsigned short *args = NULL; - if (XGetWindowProperty(mDisplay, win, XA_WIN_LAYER, 0, 16384, + if (XGetWindowProperty(x11->display, win, x11->XA_WIN_LAYER, 0, 16384, False, AnyPropertyType, &type, &format, &nitems, &bytesafter, (unsigned char **) &args) == Success @@ -1033,7 +976,7 @@ static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) } // -Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, +static Window vo_x11_create_smooth_window(struct vo_x11_state *x11, Window mRoot, Visual * vis, int x, int y, unsigned int width, unsigned int height, int depth, Colormap col_map) @@ -1053,12 +996,12 @@ Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, xswa.bit_gravity = StaticGravity; ret_win = - XCreateWindow(mDisplay, mRootWin, x, y, width, height, 0, depth, + XCreateWindow(x11->display, x11->rootwin, x, y, width, height, 0, depth, CopyFromParent, vis, xswamask, &xswa); - XSetWMProtocols(mDisplay, ret_win, &XAWM_DELETE_WINDOW, 1); - if (!f_gc) - f_gc = XCreateGC(mDisplay, ret_win, 0, 0); - XSetForeground(mDisplay, f_gc, 0); + XSetWMProtocols(x11->display, ret_win, &x11->XAWM_DELETE_WINDOW, 1); + if (!x11->f_gc) + x11->f_gc = XCreateGC(x11->display, ret_win, 0, 0); + XSetForeground(x11->display, x11->f_gc, 0); return ret_win; } @@ -1079,171 +1022,180 @@ Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, * This also does the grunt-work like setting Window Manager hints etc. * If vo_window is already set it just moves and resizes it. */ -void vo_x11_create_vo_window(XVisualInfo *vis, int x, int y, +void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y, unsigned int width, unsigned int height, int flags, Colormap col_map, const char *classname, const char *title) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; + Display *mDisplay = vo->x11->display; XGCValues xgcv; if (WinID >= 0) { vo_fs = flags & VOFLAG_FULLSCREEN; - vo_window = WinID ? (Window)WinID : mRootWin; + x11->window = WinID ? (Window)WinID : x11->rootwin; if (col_map != CopyFromParent) { unsigned long xswamask = CWColormap; XSetWindowAttributes xswa; xswa.colormap = col_map; - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); + XChangeWindowAttributes(mDisplay, x11->window, xswamask, &xswa); XInstallColormap(mDisplay, col_map); } - if (WinID) vo_x11_update_geometry(); - vo_x11_selectinput_witherr(mDisplay, vo_window, + if (WinID) vo_x11_update_geometry(vo); + vo_x11_selectinput_witherr(mDisplay, x11->window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); goto final; } - if (vo_window == None) { + if (x11->window == None) { XSizeHints hint; XEvent xev; vo_fs = 0; - vo_dwidth = width; - vo_dheight = height; - vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vis->visual, + vo->dwidth = width; + vo->dheight = height; + x11->window = vo_x11_create_smooth_window(x11, x11->rootwin, vis->visual, x, y, width, height, vis->depth, col_map); - vo_x11_classhint(mDisplay, vo_window, classname); - XStoreName(mDisplay, vo_window, title); - vo_hidecursor(mDisplay, vo_window); - XSelectInput(mDisplay, vo_window, StructureNotifyMask); + vo_x11_classhint(vo, x11->window, classname); + XStoreName(mDisplay, x11->window, title); + vo_hidecursor(mDisplay, x11->window); + XSelectInput(mDisplay, x11->window, StructureNotifyMask); hint.x = x; hint.y = y; hint.width = width; hint.height = height; hint.flags = PPosition | PSize; - XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint); - vo_x11_sizehint(x, y, width, height, 0); - if (!vo_border) vo_x11_decoration(mDisplay, vo_window, 0); + XSetStandardProperties(mDisplay, x11->window, title, title, None, NULL, 0, &hint); + vo_x11_sizehint(vo, x, y, width, height, 0); + if (!vo_border) vo_x11_decoration(vo, 0); // map window - XMapWindow(mDisplay, vo_window); - XClearWindow(mDisplay, vo_window); + XMapWindow(mDisplay, x11->window); + XClearWindow(mDisplay, x11->window); // wait for map do { XNextEvent(mDisplay, &xev); - } while (xev.type != MapNotify || xev.xmap.event != vo_window); - XSelectInput(mDisplay, vo_window, NoEventMask); + } while (xev.type != MapNotify || xev.xmap.event != x11->window); + XSelectInput(mDisplay, x11->window, NoEventMask); XSync(mDisplay, False); - vo_x11_selectinput_witherr(mDisplay, vo_window, + vo_x11_selectinput_witherr(mDisplay, x11->window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); } - if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop); - vo_x11_nofs_sizepos(vo_dx, vo_dy, width, height); + if (opts->vo_ontop) vo_x11_setlayer(vo, x11->window, opts->vo_ontop); + vo_x11_nofs_sizepos(vo, vo->dx, vo->dy, width, height); if (!!vo_fs != !!(flags & VOFLAG_FULLSCREEN)) - vo_x11_fullscreen(); + vo_x11_fullscreen(vo); else if (vo_fs) { // if we are already in fullscreen do not switch back and forth, just // set the size values right. - vo_dwidth = vo_screenwidth; - vo_dheight = vo_screenheight; + vo->dwidth = vo->opts->vo_screenwidth; + vo->dheight = vo->opts->vo_screenheight; } final: - if (vo_gc != None) - XFreeGC(mDisplay, vo_gc); - vo_gc = XCreateGC(mDisplay, vo_window, GCForeground, &xgcv); + if (x11->vo_gc != None) + XFreeGC(mDisplay, x11->vo_gc); + x11->vo_gc = XCreateGC(mDisplay, x11->window, GCForeground, &xgcv); XSync(mDisplay, False); - vo_mouse_autohide = 1; + x11->vo_mouse_autohide = 1; } -void vo_x11_clearwindow_part(Display * mDisplay, Window vo_window, +void vo_x11_clearwindow_part(struct vo *vo, Window vo_window, int img_width, int img_height, int use_fs) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *mDisplay = vo->x11->display; int u_dheight, u_dwidth, left_ov, left_ov2; - if (!f_gc) + if (!x11->f_gc) return; - u_dheight = use_fs ? vo_screenheight : vo_dheight; - u_dwidth = use_fs ? vo_screenwidth : vo_dwidth; + u_dheight = use_fs ? opts->vo_screenheight : vo->dheight; + u_dwidth = use_fs ? opts->vo_screenwidth : vo->dwidth; if ((u_dheight <= img_height) && (u_dwidth <= img_width)) return; left_ov = (u_dheight - img_height) / 2; left_ov2 = (u_dwidth - img_width) / 2; - XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, u_dwidth, left_ov); - XFillRectangle(mDisplay, vo_window, f_gc, 0, u_dheight - left_ov - 1, + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, 0, u_dwidth, left_ov); + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, u_dheight - left_ov - 1, u_dwidth, left_ov + 1); if (u_dwidth > img_width) { - XFillRectangle(mDisplay, vo_window, f_gc, 0, left_ov, left_ov2, + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, left_ov, left_ov2, img_height); - XFillRectangle(mDisplay, vo_window, f_gc, u_dwidth - left_ov2 - 1, + XFillRectangle(mDisplay, vo_window, x11->f_gc, u_dwidth - left_ov2 - 1, left_ov, left_ov2 + 1, img_height); } XFlush(mDisplay); } -void vo_x11_clearwindow(Display * mDisplay, Window vo_window) +void vo_x11_clearwindow(struct vo *vo, Window vo_window) { - if (!f_gc) + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + if (!x11->f_gc) return; - XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, vo_screenwidth, - vo_screenheight); + XFillRectangle(x11->display, vo_window, x11->f_gc, 0, 0, + opts->vo_screenwidth, opts->vo_screenheight); // - XFlush(mDisplay); + XFlush(x11->display); } -void vo_x11_setlayer(Display * mDisplay, Window vo_window, int layer) +void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer) { + struct vo_x11_state *x11 = vo->x11; if (WinID >= 0) return; - if (vo_fs_type & vo_wm_LAYER) + if (x11->fs_type & vo_wm_LAYER) { XClientMessageEvent xev; - if (!orig_layer) - orig_layer = vo_x11_get_gnome_layer(mDisplay, vo_window); + if (!x11->orig_layer) + x11->orig_layer = vo_x11_get_gnome_layer(x11, vo_window); memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; - xev.display = mDisplay; + xev.display = x11->display; xev.window = vo_window; - xev.message_type = XA_WIN_LAYER; + xev.message_type = x11->XA_WIN_LAYER; xev.format = 32; - xev.data.l[0] = layer ? fs_layer : orig_layer; // if not fullscreen, stay on default layer + xev.data.l[0] = layer ? fs_layer : x11->orig_layer; // if not fullscreen, stay on default layer xev.data.l[1] = CurrentTime; mp_msg(MSGT_VO, MSGL_V, "[x11] Layered style stay on top (layer %ld).\n", xev.data.l[0]); - XSendEvent(mDisplay, mRootWin, False, SubstructureNotifyMask, + XSendEvent(x11->display, x11->rootwin, False, SubstructureNotifyMask, (XEvent *) & xev); - } else if (vo_fs_type & vo_wm_NETWM) + } else if (x11->fs_type & vo_wm_NETWM) { XClientMessageEvent xev; char *state; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; - xev.message_type = XA_NET_WM_STATE; - xev.display = mDisplay; + xev.message_type = x11->XA_NET_WM_STATE; + xev.display = x11->display; xev.window = vo_window; xev.format = 32; xev.data.l[0] = layer; - if (vo_fs_type & vo_wm_STAYS_ON_TOP) - xev.data.l[1] = XA_NET_WM_STATE_STAYS_ON_TOP; - else if (vo_fs_type & vo_wm_ABOVE) - xev.data.l[1] = XA_NET_WM_STATE_ABOVE; - else if (vo_fs_type & vo_wm_FULLSCREEN) - xev.data.l[1] = XA_NET_WM_STATE_FULLSCREEN; - else if (vo_fs_type & vo_wm_BELOW) + if (x11->fs_type & vo_wm_STAYS_ON_TOP) + xev.data.l[1] = x11->XA_NET_WM_STATE_STAYS_ON_TOP; + else if (x11->fs_type & vo_wm_ABOVE) + xev.data.l[1] = x11->XA_NET_WM_STATE_ABOVE; + else if (x11->fs_type & vo_wm_FULLSCREEN) + xev.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; + else if (x11->fs_type & vo_wm_BELOW) // This is not fallback. We can safely assume that the situation // where only NETWM_STATE_BELOW is supported doesn't exist. - xev.data.l[1] = XA_NET_WM_STATE_BELOW; + xev.data.l[1] = x11->XA_NET_WM_STATE_BELOW; - XSendEvent(mDisplay, mRootWin, False, SubstructureRedirectMask, + XSendEvent(x11->display, x11->rootwin, False, SubstructureRedirectMask, (XEvent *) & xev); - state = XGetAtomName(mDisplay, xev.data.l[1]); + state = XGetAtomName(x11->display, xev.data.l[1]); mp_msg(MSGT_VO, MSGL_V, "[x11] NET style stay on top (layer %d). Using state %s.\n", layer, state); @@ -1323,109 +1275,117 @@ static int vo_x11_get_fs_type(int supported) } /** - * \brief update vo_dx, vo_dy, vo_dwidth and vo_dheight with current values of vo_window - * \return returns current color depth of vo_window + * \brief update vo->dx, vo->dy, vo->dwidth and vo->dheight with current values of vo->x11->window + * \return returns current color depth of vo->x11->window */ -int vo_x11_update_geometry(void) { +int vo_x11_update_geometry(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; unsigned depth, w, h; int dummy_int; Window dummy_win; - XGetGeometry(mDisplay, vo_window, &dummy_win, &dummy_int, &dummy_int, + XGetGeometry(x11->display, x11->window, &dummy_win, &dummy_int, &dummy_int, &w, &h, &dummy_int, &depth); - if (w <= INT_MAX && h <= INT_MAX) { vo_dwidth = w; vo_dheight = h; } - XTranslateCoordinates(mDisplay, vo_window, mRootWin, 0, 0, &vo_dx, &vo_dy, - &dummy_win); + if (w <= INT_MAX && h <= INT_MAX) { + vo->dwidth = w; + vo->dheight = h; + } + XTranslateCoordinates(x11->display, x11->window, x11->rootwin, 0, 0, + &vo->dx, &vo->dy, &dummy_win); if (vo_wintitle) - XStoreName(mDisplay, vo_window, vo_wintitle); + XStoreName(x11->display, x11->window, vo_wintitle); return depth <= INT_MAX ? depth : 0; } -void vo_x11_fullscreen(void) +void vo_x11_fullscreen(struct vo *vo) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; int x, y, w, h; - x = vo_old_x; - y = vo_old_y; - w = vo_old_width; - h = vo_old_height; + x = x11->vo_old_x; + y = x11->vo_old_y; + w = x11->vo_old_width; + h = x11->vo_old_height; if (WinID >= 0) { vo_fs = !vo_fs; return; } - if (vo_fs_flip) + if (x11->fs_flip) return; if (vo_fs) { - vo_x11_ewmh_fullscreen(_NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH + vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH vo_fs = VO_FALSE; } else { // win->fs - vo_x11_ewmh_fullscreen(_NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH + vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH vo_fs = VO_TRUE; - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs { - vo_old_x = vo_dx; - vo_old_y = vo_dy; - vo_old_width = vo_dwidth; - vo_old_height = vo_dheight; + x11->vo_old_x = vo->dx; + x11->vo_old_y = vo->dy; + x11->vo_old_width = vo->dwidth; + x11->vo_old_height = vo->dheight; } - update_xinerama_info(); + update_xinerama_info(vo); x = xinerama_x; y = xinerama_y; - w = vo_screenwidth; - h = vo_screenheight; + w = opts->vo_screenwidth; + h = opts->vo_screenheight; } { long dummy; - XGetWMNormalHints(mDisplay, vo_window, &vo_hint, &dummy); - if (!(vo_hint.flags & PWinGravity)) - old_gravity = NorthWestGravity; + XGetWMNormalHints(x11->display, x11->window, &x11->vo_hint, &dummy); + if (!(x11->vo_hint.flags & PWinGravity)) + x11->old_gravity = NorthWestGravity; else - old_gravity = vo_hint.win_gravity; + x11->old_gravity = x11->vo_hint.win_gravity; } - if (vo_wm_type == 0 && !(vo_fsmode & 16)) + if (x11->wm_type == 0 && !(vo_fsmode & 16)) { - XUnmapWindow(mDisplay, vo_window); // required for MWM - XWithdrawWindow(mDisplay, vo_window, mScreen); - vo_fs_flip = 1; + XUnmapWindow(x11->display, x11->window); // required for MWM + XWithdrawWindow(x11->display, x11->window, x11->screen); + x11->fs_flip = 1; } - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs { - vo_x11_decoration(mDisplay, vo_window, vo_border && !vo_fs); - vo_x11_sizehint(x, y, w, h, 0); - vo_x11_setlayer(mDisplay, vo_window, vo_fs); + vo_x11_decoration(vo, vo_border && !vo_fs); + vo_x11_sizehint(vo, x, y, w, h, 0); + vo_x11_setlayer(vo, x11->window, vo_fs); - XMoveResizeWindow(mDisplay, vo_window, x, y, w, h); + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); } /* some WMs lose ontop after fullscreen */ - if ((!(vo_fs)) & vo_ontop) - vo_x11_setlayer(mDisplay, vo_window, vo_ontop); - - XMapRaised(mDisplay, vo_window); - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // some WMs change window pos on map - XMoveResizeWindow(mDisplay, vo_window, x, y, w, h); - XRaiseWindow(mDisplay, vo_window); - XFlush(mDisplay); + if ((!(vo_fs)) & opts->vo_ontop) + vo_x11_setlayer(vo, x11->window, opts->vo_ontop); + + XMapRaised(x11->display, x11->window); + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // some WMs change window pos on map + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); + XRaiseWindow(x11->display, x11->window); + XFlush(x11->display); } -void vo_x11_ontop(void) +void vo_x11_ontop(struct vo *vo) { - vo_ontop = (!(vo_ontop)); + struct MPOpts *opts = vo->opts; + opts->vo_ontop = !opts->vo_ontop; - vo_x11_setlayer(mDisplay, vo_window, vo_ontop); + vo_x11_setlayer(vo, vo->x11->window, opts->vo_ontop); } -void vo_x11_border(void) +void vo_x11_border(struct vo *vo) { vo_border = !vo_border; - vo_x11_decoration(mDisplay, vo_window, vo_border && !vo_fs); + vo_x11_decoration(vo, vo_border && !vo_fs); } /* @@ -1435,19 +1395,19 @@ void vo_x11_border(void) static int screensaver_off; static unsigned int time_last; -void xscreensaver_heartbeat(void) +void xscreensaver_heartbeat(struct vo_x11_state *x11) { unsigned int time = GetTimerMS(); - if (mDisplay && screensaver_off && (time - time_last) > 30000) + if (x11->display && screensaver_off && (time - time_last) > 30000) { time_last = time; - XResetScreenSaver(mDisplay); + XResetScreenSaver(x11->display); } } -static int xss_suspend(Bool suspend) +static int xss_suspend(Display *mDisplay, Bool suspend) { #ifndef CONFIG_XSS return 0; @@ -1467,13 +1427,13 @@ static int xss_suspend(Bool suspend) * End of XScreensaver stuff */ -void saver_on(Display * mDisplay) +static void saver_on(Display * mDisplay) { if (!screensaver_off) return; screensaver_off = 0; - if (xss_suspend(False)) + if (xss_suspend(mDisplay, False)) return; #ifdef CONFIG_XDPMS if (dpms_disabled) @@ -1507,14 +1467,14 @@ void saver_on(Display * mDisplay) #endif } -void saver_off(Display * mDisplay) +static void saver_off(Display * mDisplay) { int nothing; if (screensaver_off) return; screensaver_off = 1; - if (xss_suspend(True)) + if (xss_suspend(mDisplay, True)) return; #ifdef CONFIG_XDPMS if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) @@ -1589,12 +1549,15 @@ void vo_x11_selectinput_witherr(Display * display, Window w, } #ifdef CONFIG_XF86VM -void vo_vm_switch(void) +void vo_vm_switch(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *mDisplay = x11->display; int vm_event, vm_error; int vm_ver, vm_rev; int i, j, have_vm = 0; - int X = vo_dwidth, Y = vo_dheight; + int X = vo->dwidth, Y = vo->dheight; int modeline_width, modeline_height; int modecount; @@ -1613,7 +1576,7 @@ void vo_vm_switch(void) if (have_vm) { if (vidmodes == NULL) - XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, + XF86VidModeGetAllModeLines(mDisplay, x11->screen, &modecount, &vidmodes); j = 0; modeline_width = vidmodes[0]->hdisplay; @@ -1630,54 +1593,64 @@ void vo_vm_switch(void) j = i; } - mp_msg(MSGT_VO, MSGL_INFO, MSGTR_SelectedVideoMode, + mp_tmsg(MSGT_VO, MSGL_INFO, "XF86VM: Selected video mode %dx%d for image size %dx%d.\n", modeline_width, modeline_height, X, Y); - XF86VidModeLockModeSwitch(mDisplay, mScreen, 0); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[j]); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[j]); + XF86VidModeLockModeSwitch(mDisplay, x11->screen, 0); + XF86VidModeSwitchToMode(mDisplay, x11->screen, vidmodes[j]); + XF86VidModeSwitchToMode(mDisplay, x11->screen, vidmodes[j]); // FIXME: all this is more of a hack than proper solution - X = (vo_screenwidth - modeline_width) / 2; - Y = (vo_screenheight - modeline_height) / 2; - XF86VidModeSetViewPort(mDisplay, mScreen, X, Y); - vo_dx = X; - vo_dy = Y; - vo_dwidth = modeline_width; - vo_dheight = modeline_height; - aspect_save_screenres(modeline_width, modeline_height); + X = (opts->vo_screenwidth - modeline_width) / 2; + Y = (opts->vo_screenheight - modeline_height) / 2; + XF86VidModeSetViewPort(mDisplay, x11->screen, X, Y); + vo->dx = X; + vo->dy = Y; + vo->dwidth = modeline_width; + vo->dheight = modeline_height; + aspect_save_screenres(vo, modeline_width, modeline_height); } } -void vo_vm_close(void) +void vo_vm_close(struct vo *vo) { -#ifdef CONFIG_GUI - if (vidmodes != NULL && vo_window != None) -#else + Display *dpy = vo->x11->display; + struct MPOpts *opts = vo->opts; if (vidmodes != NULL) -#endif { int i, modecount; free(vidmodes); vidmodes = NULL; - XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, + XF86VidModeGetAllModeLines(dpy, vo->x11->screen, &modecount, &vidmodes); for (i = 0; i < modecount; i++) - if ((vidmodes[i]->hdisplay == vo_screenwidth) - && (vidmodes[i]->vdisplay == vo_screenheight)) + if ((vidmodes[i]->hdisplay == opts->vo_screenwidth) + && (vidmodes[i]->vdisplay == opts->vo_screenheight)) { mp_msg(MSGT_VO, MSGL_INFO, "Returning to original mode %dx%d\n", - vo_screenwidth, vo_screenheight); + opts->vo_screenwidth, opts->vo_screenheight); break; } - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[i]); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); free(vidmodes); vidmodes = NULL; } } + +double vo_vm_get_fps(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; + int clock; + XF86VidModeModeLine modeline; + if (!XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline)) + return 0; + if (modeline.privsize) + XFree(modeline.private); + return 1e3 * clock / modeline.htotal / modeline.vtotal; +} #endif #endif /* X11_FULLSCREEN */ @@ -1741,12 +1714,13 @@ static XColor cols[256]; static int cm_size, red_mask, green_mask, blue_mask; -Colormap vo_x11_create_colormap(XVisualInfo * vinfo) +Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo) { + struct vo_x11_state *x11 = vo->x11; unsigned k, r, g, b, ru, gu, bu, m, rv, gv, bv, rvu, gvu, bvu; if (vinfo->class != DirectColor) - return XCreateColormap(mDisplay, mRootWin, vinfo->visual, + return XCreateColormap(x11->display, x11->rootwin, vinfo->visual, AllocNone); /* can this function get called twice or more? */ @@ -1790,8 +1764,8 @@ Colormap vo_x11_create_colormap(XVisualInfo * vinfo) gv += gvu; bv += bvu; } - cmap = XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocAll); - XStoreColors(mDisplay, cmap, cols, cm_size); + cmap = XCreateColormap(x11->display, x11->rootwin, vinfo->visual, AllocAll); + XStoreColors(x11->display, cmap, cols, cm_size); return cmap; } @@ -1818,7 +1792,7 @@ static int transform_color(float val, return (unsigned short) (s * 65535); } -uint32_t vo_x11_set_equalizer(char *name, int value) +uint32_t vo_x11_set_equalizer(struct vo *vo, char *name, int value) { float gamma, brightness, contrast; float rf, gf, bf; @@ -1864,8 +1838,8 @@ uint32_t vo_x11_set_equalizer(char *name, int value) cols[k].blue = transform_color(bf * k, brightness, contrast, gamma); } - XStoreColors(mDisplay, cmap, cols, cm_size); - XFlush(mDisplay); + XStoreColors(vo->x11->display, cmap, cols, cm_size); + XFlush(vo->x11->display); return VO_TRUE; } @@ -1885,7 +1859,7 @@ uint32_t vo_x11_get_equalizer(char *name, int *value) } #ifdef CONFIG_XV -int vo_xv_set_eq(uint32_t xv_port, char *name, int value) +int vo_xv_set_eq(struct vo *vo, uint32_t xv_port, char *name, int value) { XvAttribute *attributes; int i, howmany, xv_atom; @@ -1893,11 +1867,11 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) mp_dbg(MSGT_VO, MSGL_V, "xv_set_eq called! (%s, %d)\n", name, value); /* get available attributes */ - attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany); + attributes = XvQueryPortAttributes(vo->x11->display, xv_port, &howmany); for (i = 0; i < howmany && attributes; i++) if (attributes[i].flags & XvSettable) { - xv_atom = XInternAtom(mDisplay, attributes[i].name, True); + xv_atom = XInternAtom(vo->x11->display, attributes[i].name, True); /* since we have SET_DEFAULTS first in our list, we can check if it's available then trigger it if it's ok so that the other values are at default upon query */ if (xv_atom != None) @@ -1929,6 +1903,9 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) else if (!strcmp(attributes[i].name, "XV_BLUE_INTENSITY") && (!strcasecmp(name, "blue_intensity"))) port_value = value; + else if (!strcmp(attributes[i].name, "XV_ITURBT_709") + && (!strcasecmp(name, "bt_709"))) + port_value = value; else continue; @@ -1948,32 +1925,32 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) port_value = (port_value + 100) * (port_max - port_min) / 200 + port_min; - XvSetPortAttribute(mDisplay, xv_port, xv_atom, port_value); + XvSetPortAttribute(vo->x11->display, xv_port, xv_atom, port_value); return VO_TRUE; } } return VO_FALSE; } -int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) +int vo_xv_get_eq(struct vo *vo, uint32_t xv_port, char *name, int *value) { XvAttribute *attributes; int i, howmany, xv_atom; /* get available attributes */ - attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany); + attributes = XvQueryPortAttributes(vo->x11->display, xv_port, &howmany); for (i = 0; i < howmany && attributes; i++) if (attributes[i].flags & XvGettable) { - xv_atom = XInternAtom(mDisplay, attributes[i].name, True); + xv_atom = XInternAtom(vo->x11->display, attributes[i].name, True); /* since we have SET_DEFAULTS first in our list, we can check if it's available then trigger it if it's ok so that the other values are at default upon query */ if (xv_atom != None) { int val, port_value = 0, port_min, port_max; - XvGetPortAttribute(mDisplay, xv_port, xv_atom, + XvGetPortAttribute(vo->x11->display, xv_port, xv_atom, &port_value); port_min = attributes[i].min_value; @@ -2010,6 +1987,9 @@ int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) else if (!strcmp(attributes[i].name, "XV_BLUE_INTENSITY") && (!strcasecmp(name, "blue_intensity"))) *value = val; + else if (!strcmp(attributes[i].name, "XV_ITURBT_709") + && (!strcasecmp(name, "bt_709"))) + *value = val; else continue; @@ -2021,11 +2001,6 @@ int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) return VO_FALSE; } -/** \brief contains flags changing the execution of the colorkeying code */ -xv_ck_info_t xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR }; -unsigned long xv_colorkey; ///< The color used for manual colorkeying. -unsigned int xv_port; ///< The selected Xv port. - /** * \brief Interns the requested atom if it is available. * @@ -2034,20 +2009,21 @@ unsigned int xv_port; ///< The selected Xv port. * \return Returns the atom if available, else None is returned. * */ -static Atom xv_intern_atom_if_exists( char const * atom_name ) +static Atom xv_intern_atom_if_exists(struct vo_x11_state *x11, + char const *atom_name) { XvAttribute * attributes; int attrib_count,i; Atom xv_atom = None; - attributes = XvQueryPortAttributes( mDisplay, xv_port, &attrib_count ); + attributes = XvQueryPortAttributes(x11->display, x11->xv_port, &attrib_count ); if( attributes!=NULL ) { for ( i = 0; i < attrib_count; ++i ) { if ( strcmp(attributes[i].name, atom_name ) == 0 ) { - xv_atom = XInternAtom( mDisplay, atom_name, False ); + xv_atom = XInternAtom(x11->display, atom_name, False ); break; // found what we want, break out } } @@ -2061,12 +2037,13 @@ static Atom xv_intern_atom_if_exists( char const * atom_name ) * \brief Try to enable vsync for xv. * \return Returns -1 if not available, 0 on failure and 1 on success. */ -int vo_xv_enable_vsync(void) +int vo_xv_enable_vsync(struct vo *vo) { - Atom xv_atom = xv_intern_atom_if_exists("XV_SYNC_TO_VBLANK"); + struct vo_x11_state *x11 = vo->x11; + Atom xv_atom = xv_intern_atom_if_exists(x11, "XV_SYNC_TO_VBLANK"); if (xv_atom == None) return -1; - return XvSetPortAttribute(mDisplay, xv_port, xv_atom, 1) == Success; + return XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 1) == Success; } /** @@ -2080,13 +2057,14 @@ int vo_xv_enable_vsync(void) * \param height [out] The maximum height gets stored here. * */ -void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ) +void vo_xv_get_max_img_dim(struct vo *vo, uint32_t * width, uint32_t * height) { + struct vo_x11_state *x11 = vo->x11; XvEncodingInfo * encodings; //unsigned long num_encodings, idx; to int or too long?! unsigned int num_encodings, idx; - XvQueryEncodings( mDisplay, xv_port, &num_encodings, &encodings); + XvQueryEncodings(x11->display, x11->xv_port, &num_encodings, &encodings); if ( encodings ) { @@ -2117,11 +2095,11 @@ void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ) * Outputs the content of |ck_handling| as a readable message. * */ -void vo_xv_print_ck_info(void) +static void vo_xv_print_ck_info(struct vo_x11_state *x11) { mp_msg( MSGT_VO, MSGL_V, "[xv common] " ); - switch ( xv_ck_info.method ) + switch ( x11->xv_ck_info.method ) { case CK_METHOD_NONE: mp_msg( MSGT_VO, MSGL_V, "Drawing no colorkey.\n" ); return; @@ -2135,32 +2113,32 @@ void vo_xv_print_ck_info(void) mp_msg( MSGT_VO, MSGL_V, "\n[xv common] " ); - switch ( xv_ck_info.source ) + switch ( x11->xv_ck_info.source ) { case CK_SRC_CUR: mp_msg( MSGT_VO, MSGL_V, "Using colorkey from Xv (0x%06lx).\n", - xv_colorkey ); + x11->xv_colorkey ); break; case CK_SRC_USE: - if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + if ( x11->xv_ck_info.method == CK_METHOD_AUTOPAINT ) { mp_msg( MSGT_VO, MSGL_V, "Ignoring colorkey from MPlayer (0x%06lx).\n", - xv_colorkey ); + x11->xv_colorkey ); } else { mp_msg( MSGT_VO, MSGL_V, "Using colorkey from MPlayer (0x%06lx)." " Use -colorkey to change.\n", - xv_colorkey ); + x11->xv_colorkey ); } break; case CK_SRC_SET: mp_msg( MSGT_VO, MSGL_V, "Setting and using colorkey from MPlayer (0x%06lx)." " Use -colorkey to change.\n", - xv_colorkey ); + x11->xv_colorkey ); break; } } @@ -2185,28 +2163,29 @@ void vo_xv_print_ck_info(void) * NOTE: If vo_colorkey has bits set after the first 3 low order bytes * we don't draw anything as this means it was forced to off. */ -int vo_xv_init_colorkey(void) +int vo_xv_init_colorkey(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; Atom xv_atom; int rez; /* check if colorkeying is needed */ - xv_atom = xv_intern_atom_if_exists( "XV_COLORKEY" ); + xv_atom = xv_intern_atom_if_exists(vo->x11, "XV_COLORKEY"); /* if we have to deal with colorkeying ... */ if( xv_atom != None && !(vo_colorkey & 0xFF000000) ) { /* check if we should use the colorkey specified in vo_colorkey */ - if ( xv_ck_info.source != CK_SRC_CUR ) + if ( x11->xv_ck_info.source != CK_SRC_CUR ) { - xv_colorkey = vo_colorkey; + x11->xv_colorkey = vo_colorkey; /* check if we have to set the colorkey too */ - if ( xv_ck_info.source == CK_SRC_SET ) + if ( x11->xv_ck_info.source == CK_SRC_SET ) { - xv_atom = XInternAtom(mDisplay, "XV_COLORKEY",False); + xv_atom = XInternAtom(x11->display, "XV_COLORKEY",False); - rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, vo_colorkey ); + rez = XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, vo_colorkey); if ( rez != Success ) { mp_msg( MSGT_VO, MSGL_FATAL, @@ -2219,10 +2198,10 @@ int vo_xv_init_colorkey(void) { int colorkey_ret; - rez=XvGetPortAttribute(mDisplay,xv_port, xv_atom, &colorkey_ret); + rez=XvGetPortAttribute(x11->display,x11->xv_port, xv_atom, &colorkey_ret); if ( rez == Success ) { - xv_colorkey = colorkey_ret; + x11->xv_colorkey = colorkey_ret; } else { @@ -2233,39 +2212,39 @@ int vo_xv_init_colorkey(void) } } - xv_atom = xv_intern_atom_if_exists( "XV_AUTOPAINT_COLORKEY" ); + xv_atom = xv_intern_atom_if_exists(vo->x11, "XV_AUTOPAINT_COLORKEY"); /* should we draw the colorkey ourselves or activate autopainting? */ - if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + if ( x11->xv_ck_info.method == CK_METHOD_AUTOPAINT ) { rez = !Success; // reset rez to something different than Success if ( xv_atom != None ) // autopaint is supported { - rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, 1 ); + rez = XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 1); } if ( rez != Success ) { // fallback to manual colorkey drawing - xv_ck_info.method = CK_METHOD_MANUALFILL; + x11->xv_ck_info.method = CK_METHOD_MANUALFILL; } } else // disable colorkey autopainting if supported { if ( xv_atom != None ) // we have autopaint attribute { - XvSetPortAttribute( mDisplay, xv_port, xv_atom, 0 ); + XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 0); } } } else // do no colorkey drawing at all { - xv_ck_info.method = CK_METHOD_NONE; + x11->xv_ck_info.method = CK_METHOD_NONE; } /* end: should we draw colorkey */ /* output information about the current colorkey settings */ - vo_xv_print_ck_info(); + vo_xv_print_ck_info(x11); return 1; // success } @@ -2280,14 +2259,16 @@ int vo_xv_init_colorkey(void) * It doesn't call XFlush. * */ -void vo_xv_draw_colorkey( int32_t x, int32_t y, - int32_t w, int32_t h ) +void vo_xv_draw_colorkey(struct vo *vo, int32_t x, int32_t y, + int32_t w, int32_t h) { - if( xv_ck_info.method == CK_METHOD_MANUALFILL || - xv_ck_info.method == CK_METHOD_BACKGROUND )//less tearing than XClearWindow() + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; + if( x11->xv_ck_info.method == CK_METHOD_MANUALFILL || + x11->xv_ck_info.method == CK_METHOD_BACKGROUND )//less tearing than XClearWindow() { - XSetForeground( mDisplay, vo_gc, xv_colorkey ); - XFillRectangle( mDisplay, vo_window, vo_gc, + XSetForeground(x11->display, x11->vo_gc, x11->xv_colorkey ); + XFillRectangle(x11->display, x11->window, x11->vo_gc, x, y, w, h ); } @@ -2296,24 +2277,24 @@ void vo_xv_draw_colorkey( int32_t x, int32_t y, /* TODO! move this to vo_x11_clearwindow_part() */ if ( vo_fs ) { - XSetForeground( mDisplay, vo_gc, 0 ); + XSetForeground(x11->display, x11->vo_gc, 0 ); /* making non-overlap fills, requires 8 checks instead of 4 */ if ( y > 0 ) - XFillRectangle( mDisplay, vo_window, vo_gc, + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, 0, - vo_screenwidth, y); + opts->vo_screenwidth, y); if (x > 0) - XFillRectangle( mDisplay, vo_window, vo_gc, + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, 0, - x, vo_screenheight); - if (x + w < vo_screenwidth) - XFillRectangle( mDisplay, vo_window, vo_gc, + x, opts->vo_screenheight); + if (x + w < opts->vo_screenwidth) + XFillRectangle(x11->display, x11->window, x11->vo_gc, x + w, 0, - vo_screenwidth, vo_screenheight); - if (y + h < vo_screenheight) - XFillRectangle( mDisplay, vo_window, vo_gc, + opts->vo_screenwidth, opts->vo_screenheight); + if (y + h < opts->vo_screenheight) + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, y + h, - vo_screenwidth, vo_screenheight); + opts->vo_screenwidth, opts->vo_screenheight); } } @@ -2358,19 +2339,20 @@ int xv_test_ckm( void * arg ) * \param str Pointer to the string or NULL * */ -void xv_setup_colorkeyhandling( char const * ck_method_str, - char const * ck_str ) +void xv_setup_colorkeyhandling(struct vo *vo, const char *ck_method_str, + const char *ck_str) { + struct vo_x11_state *x11 = vo->x11; /* check if a valid pointer to the string was passed */ if ( ck_str ) { if ( strncmp( ck_str, "use", 3 ) == 0 ) { - xv_ck_info.source = CK_SRC_USE; + x11->xv_ck_info.source = CK_SRC_USE; } else if ( strncmp( ck_str, "set", 3 ) == 0 ) { - xv_ck_info.source = CK_SRC_SET; + x11->xv_ck_info.source = CK_SRC_SET; } } /* check if a valid pointer to the string was passed */ @@ -2378,17 +2360,30 @@ void xv_setup_colorkeyhandling( char const * ck_method_str, { if ( strncmp( ck_method_str, "bg", 2 ) == 0 ) { - xv_ck_info.method = CK_METHOD_BACKGROUND; + x11->xv_ck_info.method = CK_METHOD_BACKGROUND; } else if ( strncmp( ck_method_str, "man", 3 ) == 0 ) { - xv_ck_info.method = CK_METHOD_MANUALFILL; + x11->xv_ck_info.method = CK_METHOD_MANUALFILL; } else if ( strncmp( ck_method_str, "auto", 4 ) == 0 ) { - xv_ck_info.method = CK_METHOD_AUTOPAINT; + x11->xv_ck_info.method = CK_METHOD_AUTOPAINT; } } } #endif + +struct vo_x11_state *vo_x11_init_state(void) +{ + struct vo_x11_state *s = talloc_ptrtype(NULL, s); + *s = (struct vo_x11_state){ + .xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR }, + .olddecor = MWM_DECOR_ALL, + .oldfuncs = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | + MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE, + .old_gravity = NorthWestGravity, + }; + return s; +} diff --git a/libvo/x11_common.h b/libvo/x11_common.h index c7221d2577..fccad90ced 100644 --- a/libvo/x11_common.h +++ b/libvo/x11_common.h @@ -24,6 +24,60 @@ #include "config.h" +struct vo; + +struct vo_x11_state { + Display *display; + Window window; + Window rootwin; + int screen; + int display_is_local; + int depthonscreen; + + GC vo_gc; + + struct xv_ck_info_s { + int method; ///< CK_METHOD_* constants + int source; ///< CK_SRC_* constants + } xv_ck_info; + unsigned long xv_colorkey; + unsigned int xv_port; + + int vo_mouse_autohide; + int wm_type; + int fs_type; + int fs_flip; + + GC f_gc; + XSizeHints vo_hint; + unsigned int mouse_timer; + int mouse_waiting_hide; + int orig_layer; + int old_gravity; + int vo_old_x; + int vo_old_y; + int vo_old_width; + int vo_old_height; + + + unsigned int olddecor; + unsigned int oldfuncs; + XComposeStatus compose_status; + + Atom XA_NET_SUPPORTED; + Atom XA_NET_WM_STATE; + Atom XA_NET_WM_STATE_FULLSCREEN; + Atom XA_NET_WM_STATE_ABOVE; + Atom XA_NET_WM_STATE_STAYS_ON_TOP; + Atom XA_NET_WM_STATE_BELOW; + Atom XA_NET_WM_PID; + Atom XA_WIN_PROTOCOLS; + Atom XA_WIN_LAYER; + Atom XA_WIN_HINTS; + Atom XAWM_PROTOCOLS; + Atom XAWM_DELETE_WINDOW; +}; + #if defined(CONFIG_GL) || defined(CONFIG_X11) || defined(CONFIG_XV) #define X11_FULLSCREEN 1 #endif @@ -51,67 +105,43 @@ extern int vo_fs_type; extern char** vo_fstype_list; extern char *mDisplayName; -extern Display *mDisplay; -extern Window mRootWin; -extern int mScreen; -extern int mLocalDisplay; - -extern int vo_mouse_autohide; - -int vo_init( void ); -void vo_uninit( void ); -void vo_hidecursor ( Display* , Window ); -void vo_showcursor( Display *disp, Window win ); -void vo_x11_decoration( Display * vo_Display,Window w,int d ); -void vo_x11_classhint( Display * display,Window window,char *name ); -void vo_x11_nofs_sizepos(int x, int y, int width, int height); -void vo_x11_sizehint( int x, int y, int width, int height, int max ); -int vo_x11_check_events(Display *mydisplay); + +struct vo_x11_state *vo_x11_init_state(void); +int vo_init(struct vo *vo); +void vo_uninit(struct vo_x11_state *x11); +void vo_x11_decoration(struct vo *vo, int d ); +void vo_x11_classhint(struct vo *vo, Window window, char *name); +void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max); +int vo_x11_check_events(struct vo *vo); void vo_x11_selectinput_witherr(Display *display, Window w, long event_mask); -int vo_x11_update_geometry(void); -void vo_x11_fullscreen( void ); -void vo_x11_setlayer( Display * mDisplay,Window vo_window,int layer ); -void vo_x11_uninit(void); -Colormap vo_x11_create_colormap(XVisualInfo *vinfo); -uint32_t vo_x11_set_equalizer(char *name, int value); +void vo_x11_fullscreen(struct vo *vo); +int vo_x11_update_geometry(struct vo *vo); +void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer); +void vo_x11_uninit(struct vo *vo); +Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo); +uint32_t vo_x11_set_equalizer(struct vo *vo, char *name, int value); uint32_t vo_x11_get_equalizer(char *name, int *value); void fstype_help(void); -Window vo_x11_create_smooth_window( Display *mDisplay, Window mRoot, - Visual *vis, int x, int y, unsigned int width, unsigned int height, - int depth, Colormap col_map); -void vo_x11_create_vo_window(XVisualInfo *vis, int x, int y, - unsigned int width, unsigned int height, int flags, +void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, + int x, int y, unsigned int width, unsigned int height, int flags, Colormap col_map, const char *classname, const char *title); -void vo_x11_clearwindow_part(Display *mDisplay, Window vo_window, +void vo_x11_clearwindow_part(struct vo *vo, Window vo_window, int img_width, int img_height, int use_fs); -void vo_x11_clearwindow( Display *mDisplay, Window vo_window ); -void vo_x11_ontop(void); -void vo_x11_border(void); -void vo_x11_ewmh_fullscreen( int action ); +void vo_x11_clearwindow(struct vo *vo, Window vo_window); +void vo_x11_ontop(struct vo *vo); +void vo_x11_border(struct vo *vo); +void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action); #endif -extern Window vo_window; -extern GC vo_gc; -extern XSizeHints vo_hint; - -#ifdef CONFIG_XV -//XvPortID xv_port; -extern unsigned int xv_port; - -int vo_xv_set_eq(uint32_t xv_port, char * name, int value); -int vo_xv_get_eq(uint32_t xv_port, char * name, int *value); +int vo_xv_set_eq(struct vo *vo, uint32_t xv_port, char * name, int value); +int vo_xv_get_eq(struct vo *vo, uint32_t xv_port, char * name, int *value); -int vo_xv_enable_vsync(void); +int vo_xv_enable_vsync(struct vo *vo); -void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ); +void vo_xv_get_max_img_dim(struct vo *vo, uint32_t * width, uint32_t * height); /*** colorkey handling ***/ -typedef struct xv_ck_info_s -{ - int method; ///< CK_METHOD_* constants - int source; ///< CK_SRC_* constants -} xv_ck_info_t; #define CK_METHOD_NONE 0 ///< no colorkey drawing #define CK_METHOD_BACKGROUND 1 ///< set colorkey as window background @@ -121,31 +151,67 @@ typedef struct xv_ck_info_s #define CK_SRC_SET 1 ///< use and set specified / default colorkey #define CK_SRC_CUR 2 ///< use current colorkey ( get it from xv ) -extern xv_ck_info_t xv_ck_info; -extern unsigned long xv_colorkey; - -int vo_xv_init_colorkey(void); -void vo_xv_draw_colorkey(int32_t x, int32_t y, int32_t w, int32_t h); -void xv_setup_colorkeyhandling(char const * ck_method_str, char const * ck_str); +int vo_xv_init_colorkey(struct vo *vo); +void vo_xv_draw_colorkey(struct vo *vo, int32_t x, int32_t y, int32_t w, int32_t h); +void xv_setup_colorkeyhandling(struct vo *vo, const char *ck_method_str, const char *ck_str); /*** test functions for common suboptions ***/ int xv_test_ck( void * arg ); int xv_test_ckm( void * arg ); -#endif -void vo_setwindow( Window w,GC g ); -void vo_x11_putkey(int key); - -void saver_off( Display * ); -void saver_on( Display * ); +void vo_x11_putkey(struct vo *vo, int key); #ifdef CONFIG_XF86VM -void vo_vm_switch(void); -void vo_vm_close(void); +void vo_vm_switch(struct vo *vo); +void vo_vm_close(struct vo *vo); +double vo_vm_get_fps(struct vo *vo); #endif -void update_xinerama_info(void); +void update_xinerama_info(struct vo *vo); int vo_find_depth_from_visuals(Display *dpy, int screen, Visual **visual_return); +void xscreensaver_heartbeat(struct vo_x11_state *x11); + +// Old VOs use incompatible function calls, translate them to new +// prototypes +#ifdef IS_OLD_VO +#define vo_x11_create_vo_window(...) vo_x11_create_vo_window(global_vo, __VA_ARGS__) +#define vo_x11_fullscreen() vo_x11_fullscreen(global_vo) +#define vo_x11_update_geometry() vo_x11_update_geometry(global_vo) +#define vo_x11_ontop() vo_x11_ontop(global_vo) +#define vo_init() vo_init(global_vo) +#define vo_x11_ewmh_fullscreen(action) vo_x11_ewmh_fullscreen(global_vo->x11->display, action) +#define update_xinerama_info() update_xinerama_info(global_vo) +#define vo_x11_uninit() vo_x11_uninit(global_vo) +#define vo_x11_check_events(display) vo_x11_check_events(global_vo) +#define vo_x11_sizehint(...) vo_x11_sizehint(global_vo, __VA_ARGS__) +#define vo_vm_switch() vo_vm_switch(global_vo) +#define vo_x11_create_colormap(vinfo) vo_x11_create_colormap(global_vo, vinfo) +#define vo_x11_set_equalizer(...) vo_x11_set_equalizer(global_vo, __VA_ARGS__) +#define vo_xv_set_eq(...) vo_xv_set_eq(global_vo, __VA_ARGS__) +#define vo_xv_get_eq(...) vo_xv_get_eq(global_vo, __VA_ARGS__) +#define vo_xv_enable_vsync() vo_xv_enable_vsync(global_vo) +#define vo_xv_get_max_img_dim(...) vo_xv_get_max_img_dim(global_vo, __VA_ARGS__) +#define vo_xv_init_colorkey() vo_xv_init_colorkey(global_vo) +#define vo_xv_draw_colorkey(...) vo_xv_draw_colorkey(global_vo, __VA_ARGS__) +#define vo_x11_clearwindow_part(display, ...) vo_x11_clearwindow_part(global_vo, __VA_ARGS__) +#define vo_vm_close() vo_vm_close(global_vo) +#define vo_x11_clearwindow(display, window) vo_x11_clearwindow(global_vo, window) +#define vo_x11_classhint(display, window, name) vo_x11_classhint(global_vo, window, name) +#define vo_x11_setlayer(display, window, layer) vo_x11_setlayer(global_vo, window, layer) +#define xv_setup_colorkeyhandling(a, b) xv_setup_colorkeyhandling(global_vo, a, b) +#define vo_x11_border() vo_x11_border(global_vo) + +#define mDisplay global_vo->x11->display +#define vo_depthonscreen global_vo->x11->depthonscreen +#define vo_window global_vo->x11->window +#define xv_ck_info global_vo->x11->xv_ck_info +#define xv_colorkey global_vo->x11->xv_colorkey +#define xv_port global_vo->x11->xv_port +#define vo_gc global_vo->x11->vo_gc +#define mRootWin global_vo->x11->rootwin +#define mScreen global_vo->x11->screen +#define mLocalDisplay global_vo->x11->display_is_local +#endif #endif /* MPLAYER_X11_COMMON_H */ |