Mercurial > mplayer.hg
changeset 14742:76d461a061df
Unified colorkey code for vo xv and vo xvmc.
Made the code also more flexible.
Colorkey drawing is now by default done as
proposed by Marko Macek.
Patch also approved by iive.
author | al |
---|---|
date | Sun, 20 Feb 2005 22:43:25 +0000 |
parents | c29a660e8bd7 |
children | 465c8617cbe5 |
files | libvo/vo_xv.c libvo/vo_xvmc.c libvo/x11_common.c libvo/x11_common.h |
diffstat | 4 files changed, 417 insertions(+), 131 deletions(-) [+] |
line wrap: on
line diff
--- a/libvo/vo_xv.c Sun Feb 20 18:34:06 2005 +0000 +++ b/libvo/vo_xv.c Sun Feb 20 22:43:25 2005 +0000 @@ -36,6 +36,8 @@ #include "sub.h" #include "aspect.h" +#include "subopt-helper.h" + #ifdef HAVE_NEW_GUI #include "Gui/interface.h" #endif @@ -66,7 +68,7 @@ // FIXME: dynamically allocate this stuff static void allocate_xvimage(int); static unsigned int ver, rel, req, ev, err; -static unsigned int formats, adaptors, xv_port, xv_format; +static unsigned int formats, adaptors, xv_format; static XvAdaptorInfo *ai = NULL; static XvImageFormatValues *fo=NULL; @@ -270,6 +272,10 @@ XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); xswa.background_pixel = 0; + if (xv_ck_info.method == CK_METHOD_BACKGROUND) + { + xswa.background_pixel = xv_colorkey; + } xswa.border_pixel = 0; xswamask = CWBackPixel | CWBorderPixel; @@ -302,6 +308,7 @@ vinfo.visual, hint.x, hint.y, hint.width, hint.height, depth, CopyFromParent); + XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); vo_x11_classhint(mDisplay, vo_window, "xv"); vo_hidecursor(mDisplay, vo_window); @@ -519,18 +526,8 @@ { int e = vo_x11_check_events(mDisplay); - if (e & VO_EVENT_EXPOSE && vo_fs) - vo_x11_clearwindow(mDisplay, vo_window); - if (e & VO_EVENT_RESIZE) { - if (vo_fs) - { - e |= VO_EVENT_EXPOSE; - XClearWindow(mDisplay, vo_window); - XFlush(mDisplay); - } - XGetGeometry(mDisplay, vo_window, &mRoot, &drwX, &drwY, &vo_dwidth, &vo_dheight, &drwBorderWidth, &drwDepth); drwX = drwY = 0; @@ -558,6 +555,11 @@ } } + if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) + { + vo_xv_draw_colorkey(drwX,drwY,vo_dwidth,vo_dheight); + } + if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause) flip_page(); } @@ -778,21 +780,29 @@ XvPortID xv_p; int busy_ports = 0; unsigned int i; + strarg_t ck_src_arg = { 0, NULL }; + strarg_t ck_method_arg = { 0, NULL }; + + opt_t subopts[] = + { + /* name arg type arg var test */ + { "port", OPT_ARG_INT, &xv_port, (opt_test_f)int_pos }, + { "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; - if (arg) + /* parse suboptions */ + if ( subopt_parse( arg, subopts ) != 0 ) { - if ((strlen(arg) >= 6) && !strncmp(arg, "port=", 5)) - { - xv_port = atoi(arg + 5); - } else - { - mp_msg(MSGT_VO, MSGL_ERR, "vo_xv: Unknown subdevice: %s\n", - arg); - return ENOSYS; - } + return -1; } + + /* modify colorkey settings according to the given options */ + xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); + if (!vo_init()) return -1; @@ -880,20 +890,9 @@ return -1; } + if ( !vo_xv_init_colorkey() ) { - int howmany, i; - XvAttribute * const attributes = - XvQueryPortAttributes(mDisplay, xv_port, &howmany); - - for (i = 0; i < howmany && attributes; i++) - if (!strcmp(attributes[i].name, "XV_AUTOPAINT_COLORKEY")) - { - const Atom autopaint = - XInternAtom(mDisplay, "XV_AUTOPAINT_COLORKEY", False); - XvSetPortAttribute(mDisplay, xv_port, autopaint, 1); - break; - } - XFree(attributes); + return -1; // bail out, colorkey setup failed } fo = XvListImageFormats(mDisplay, xv_port, (int *) &formats);
--- a/libvo/vo_xvmc.c Sun Feb 20 18:34:06 2005 +0000 +++ b/libvo/vo_xvmc.c Sun Feb 20 22:43:25 2005 +0000 @@ -30,6 +30,8 @@ #include "sub.h" #include "aspect.h" +#include "subopt-helper.h" + #ifdef HAVE_NEW_GUI #include "Gui/interface.h" #endif @@ -48,21 +50,13 @@ extern int vo_verbose; static int benchmark; -static int busy_wait; +static int use_sleep; static int use_queue; +static int xv_port_request = 0; static int image_width,image_height; static uint32_t drwX,drwY; -static XvPortID xv_port; - -#define AUTO_COLORKEY 0 -#define BACKGROUND_COLORKEY 1 -#define AUTOPAINT_COLORKEY 2 -#define MANUALFILL_COLORKEY 3 -static int keycolor_handling; -static unsigned long keycolor; - #define NO_SUBPICTURE 0 #define OVERLAY_SUBPICTURE 1 #define BLEND_SUBPICTURE 2 @@ -194,58 +188,6 @@ } //end of vo_xv shm/xvimage code - -static void init_keycolor(){ -Atom xv_atom; -XvAttribute * attributes; -int colorkey; -int rez; -int attrib_count,i; - - keycolor=2110; - - if(keycolor_handling == AUTO_COLORKEY){ - //XV_AUTOPING_COLORKEY doesn't work for XvMC yet(NVidia 43.63) - attributes = XvQueryPortAttributes(mDisplay, xv_port, &attrib_count); - if(attributes!=NULL){ - for (i = 0; i < attrib_count; i++){ - if (!strcmp(attributes[i].name, "XV_COLORKEY")) - { - xv_atom = XInternAtom(mDisplay, "XV_COLORKEY", False); - if(xv_atom!=None) - { - rez=XvGetPortAttribute(mDisplay,xv_port, xv_atom, &colorkey); - if(rez == Success){ - keycolor = colorkey; - keycolor_handling = MANUALFILL_COLORKEY; - } - } - break; - } - } - XFree(attributes); - } - } -} - -//from vo_xmga -static void mDrawColorKey(uint32_t x,uint32_t y, uint32_t w, uint32_t h) -{ - if( (keycolor_handling != AUTOPAINT_COLORKEY) && - (keycolor_handling != MANUALFILL_COLORKEY) ) - return; - - XSetBackground( mDisplay,vo_gc,0 ); - XClearWindow( mDisplay,vo_window ); - - if(keycolor_handling == MANUALFILL_COLORKEY){ - XSetForeground( mDisplay,vo_gc,keycolor ); - XFillRectangle( mDisplay,vo_window,vo_gc,x,y,w,h); - } - XFlush( mDisplay ); -} - - static int xvmc_check_surface_format(uint32_t format, XvMCSurfaceInfo * surf_info){ if ( format == IMGFMT_XVMC_IDCT_MPEG2 ){ if( surf_info->mc_type != (XVMC_IDCT|XVMC_MPEG_2) ) return -1; @@ -350,6 +292,11 @@ if( height > mc_surf_list[s].max_height ) continue; if( xvmc_check_surface_format(format,&mc_surf_list[s])<0 ) continue; //we have match! + /* respect the users wish */ + if ( xv_port_request != 0 && xv_port_request != p ) + { + continue; + } if(!query){ rez = XvGrabPort(mDisplay,p,CurrentTime); @@ -401,6 +348,19 @@ int xv_version,xv_release,xv_request_base,xv_event_base,xv_error_base; int mc_eventBase,mc_errorBase; int mc_ver,mc_rev; +strarg_t ck_src_arg = { 0, NULL }; +strarg_t ck_method_arg = { 0, NULL }; +opt_t subopts [] = +{ + /* name arg type arg var test */ + { "port", OPT_ARG_INT, &xv_port_request, (opt_test_f)int_pos }, + { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck }, + { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm }, + { "benchmark", OPT_ARG_BOOL, &benchmark, NULL }, + { "sleep", OPT_ARG_BOOL, &use_sleep, NULL }, + { "queue", OPT_ARG_BOOL, &use_queue, NULL }, + { NULL } +}; //Obtain display handler if (!vo_init()) return -1;//vo_xv @@ -431,40 +391,19 @@ surface_render = NULL; xv_port = 0; number_of_surfaces = 0; - keycolor_handling = AUTO_COLORKEY; subpicture_alloc = 0; benchmark = 0; //disable PutImageto allow faster display than screen refresh - busy_wait = 1; + use_sleep = 0; use_queue = 0; - if(arg) - while(*arg){ - if(strncmp(arg,"benchmark",9) == 0){ - arg+=9; - if(*arg == ':') arg++; - benchmark = 1;//disable PutImageto allow faster display than screen refresh - continue; - } - if(strncmp(arg,"wait",4) == 0){ - arg+=4; - if(*arg == ':') arg++; - busy_wait = 1; - continue; - } - if(strncmp(arg,"sleep",5) == 0){ - arg+=5; - if(*arg == ':') arg++; - busy_wait = 0; - continue; - } - if(strncmp(arg,"queue",5) == 0){ - arg+=5; - if(*arg == ':') arg++; - use_queue = 1; - continue; - } - break; - } + + /* parse suboptions */ + if ( subopt_parse( arg, subopts ) != 0 ) + { + return -1; + } + + xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); return 0; } @@ -505,6 +444,10 @@ numblocks=((width+15)/16)*((height+15)/16); // Find Supported Surface Type mode_id = xvmc_find_surface_by_format(format,width,height,&surface_info,0);//false=1 to grab port, not query + if ( mode_id == 0 ) + { + return -1; + } rez = XvMCCreateContext(mDisplay, xv_port,mode_id,width,height,XVMC_DIRECT,&ctx); if( rez != Success ) return -1; @@ -635,7 +578,12 @@ break; } - init_keycolor();// take keycolor value and choose method for handling it +//take keycolor value and choose method for handling it + if ( !vo_xv_init_colorkey() ) + { + return -1; // bail out, colorkey setup failed + } + //taken from vo_xv panscan_init(); @@ -708,8 +656,8 @@ XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); xswa.background_pixel = 0; - if (keycolor_handling == BACKGROUND_COLORKEY) - xswa.background_pixel = keycolor;// 2110; + if (xv_ck_info.method == CK_METHOD_BACKGROUND) + xswa.background_pixel = xv_colorkey; xswa.border_pixel = 0; xswamask = CWBackPixel | CWBorderPixel; @@ -1034,7 +982,7 @@ assert(rez==Success); if((status & XVMC_RENDERING) == 0) return;//surface is already complete - if(!busy_wait){ + if(use_sleep){ rez = XvMCFlushSurface(mDisplay, srf); assert(rez==Success); @@ -1140,7 +1088,7 @@ } if ( e & VO_EVENT_EXPOSE ) { - mDrawColorKey(drwX,drwY,vo_dwidth,vo_dheight); + vo_xv_draw_colorkey(drwX,drwY,vo_dwidth,vo_dheight); if(p_render_surface_visible != NULL) XvMCPutSurface(mDisplay, p_render_surface_visible->p_surface,vo_window, 0, 0, image_width, image_height,
--- a/libvo/x11_common.c Sun Feb 20 18:34:06 2005 +0000 +++ b/libvo/x11_common.c Sun Feb 20 22:43:25 2005 +0000 @@ -46,6 +46,8 @@ #ifdef HAVE_XV #include <X11/extensions/Xv.h> #include <X11/extensions/Xvlib.h> + +#include "subopt-helper.h" #endif #include "input/input.h" @@ -2242,4 +2244,313 @@ 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. + * + * \param atom_name String containing the name of the requested atom. + * + * \return Returns the atom if available, else None is returned. + * + */ +static Atom xv_intern_atom_if_exists( char const * atom_name ) +{ + XvAttribute * attributes; + int attrib_count,i; + Atom xv_atom = None; + + attributes = XvQueryPortAttributes( mDisplay, 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 ); + break; // found what we want, break out + } + } + XFree( attributes ); + } + + return xv_atom; +} +/** + * \brief Print information about the colorkey method and source. + * + * \param ck_handling Integer value containing the information about + * colorkey handling (see x11_common.h). + * + * Outputs the content of |ck_handling| as a readable message. + * + */ +void vo_xv_print_ck_info() +{ + mp_msg( MSGT_VO, MSGL_V, "[xv common] " ); + + switch ( xv_ck_info.method ) + { + case CK_METHOD_NONE: + mp_msg( MSGT_VO, MSGL_V, "Drawing no colorkey.\n" ); return; + case CK_METHOD_AUTOPAINT: + mp_msg( MSGT_VO, MSGL_V, "Colorkey is drawn by Xv." ); break; + case CK_METHOD_MANUALFILL: + mp_msg( MSGT_VO, MSGL_V, "Drawing colorkey manually." ); break; + case CK_METHOD_BACKGROUND: + mp_msg( MSGT_VO, MSGL_V, "Colorkey is drawn as window background." ); break; + } + + mp_msg( MSGT_VO, MSGL_V, "\n[xv common] " ); + + switch ( xv_ck_info.source ) + { + case CK_SRC_CUR: + mp_msg( MSGT_VO, MSGL_V, "Using colorkey from Xv (0x%06x).\n", + xv_colorkey ); + break; + case CK_SRC_USE: + if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + { + mp_msg( MSGT_VO, MSGL_V, + "Ignoring colorkey from MPlayer (0x%06x).\n", + xv_colorkey ); + } + else + { + mp_msg( MSGT_VO, MSGL_V, + "Using colorkey from MPlayer (0x%06x)." + " Use -colorkey to change.\n", + xv_colorkey ); + } + break; + case CK_SRC_SET: + mp_msg( MSGT_VO, MSGL_V, + "Setting and using colorkey from MPlayer (0x%06x)." + " Use -colorkey to change.\n", + xv_colorkey ); + break; + } +} +/** + * \brief Init colorkey depending on the settings in xv_ck_info. + * + * \return Returns 0 on failure and 1 on success. + * + * Sets the colorkey variable according to the CK_SRC_* and CK_METHOD_* + * flags in xv_ck_info. + * + * Possiblilities: + * * Methods + * - manual colorkey drawing ( CK_METHOD_MANUALFILL ) + * - set colorkey as window background ( CK_METHOD_BACKGROUND ) + * - let Xv paint the colorkey ( CK_METHOD_AUTOPAINT ) + * * Sources + * - use currently set colorkey ( CK_SRC_CUR ) + * - use colorkey in vo_colorkey ( CK_SRC_USE ) + * - use and set colorkey in vo_colorkey ( CK_SRC_SET ) + * + * 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() +{ + Atom xv_atom; + int rez; + + /* check if colorkeying is needed */ + xv_atom = xv_intern_atom_if_exists( "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 ) + { + xv_colorkey = vo_colorkey; + + /* check if we have to set the colorkey too */ + if ( xv_ck_info.source == CK_SRC_SET ) + { + xv_atom = XInternAtom(mDisplay, "XV_COLORKEY",False); + + rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, vo_colorkey ); + if ( rez != Success ) + { + mp_msg( MSGT_VO, MSGL_FATAL, + "[xv common] Couldn't set colorkey!\n" ); + return 0; // error setting colorkey + } + } + } + else + { + int colorkey_ret; + + rez=XvGetPortAttribute(mDisplay,xv_port, xv_atom, &colorkey_ret); + if ( rez == Success ) + { + xv_colorkey = colorkey_ret; + } + else + { + mp_msg( MSGT_VO, MSGL_FATAL, + "[xv common] Couldn't get colorkey!" + "Maybe the selected Xv port has no overlay.\n" ); + return 0; // error getting colorkey + } + } + + /* should we draw the colorkey ourselves or activate autopainting? */ + if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + { + rez = !Success; // reset rez to something different than Success + xv_atom = xv_intern_atom_if_exists( "XV_AUTOPAINT_COLORKEY" ); + + if ( xv_atom != None ) // autopaint is supported + { + rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, 1 ); + } + + if ( rez != Success ) + { + // fallback to manual colorkey drawing + xv_ck_info.method = CK_METHOD_MANUALFILL; + } + } + } + else // do no colorkey drawing at all + { + xv_ck_info.method = CK_METHOD_NONE; + } /* end: should we draw colorkey */ + + /* output information about the curren colorkey settings */ + vo_xv_print_ck_info(); + + return 1; // success +} + +/** + * \brief Draw the colorkey on the video window. + * + * Draws the colorkey depending on the set method ( colorkey_handling ). + * + * It also draws the black bars ( when the video doesn't fit to the + * display in full screen ) seperately, so they don't overlap with the + * video area. + * + */ +inline void vo_xv_draw_colorkey( uint32_t x, uint32_t y, + uint32_t w, uint32_t h ) +{ + if( xv_ck_info.method == CK_METHOD_MANUALFILL ) + { + XSetForeground( mDisplay, vo_gc, xv_colorkey ); + XFillRectangle( mDisplay, vo_window, vo_gc, + x, y, + w, h ); + } + + /* draw black bars if needed */ + if ( vo_fs ) + { + XSetForeground( mDisplay, vo_gc, 0 ); + if ( y > 0 ) + XFillRectangle( mDisplay, vo_window, vo_gc, + 0, 0, + vo_screenwidth, y); + if (x > 0) + XFillRectangle( mDisplay, vo_window, vo_gc, + 0, y, + x, h ); + if (x + w < vo_screenwidth) + XFillRectangle( mDisplay, vo_window, vo_gc, + x + w, y, + vo_screenwidth - (x + w), h ); + if (y + h < vo_screenheight) + XFillRectangle( mDisplay, vo_window, vo_gc, + 0, y + h, + vo_screenwidth, vo_screenheight - (y + h) ); + } + + XFlush( mDisplay ); +} + +/** \brief tests if a valid arg for the ck suboption was given */ +int xv_test_ck( void * arg ) +{ + strarg_t * strarg = (strarg_t *)arg; + + if ( strncmp( "use", strarg->str, 3 ) == 0 || + strncmp( "set", strarg->str, 3 ) == 0 || + strncmp( "cur", strarg->str, 3 ) == 0 ) + { + return 1; + } + + return 0; +} +/** \brief tests if a valid arg for the ck-method suboption was given */ +int xv_test_ckm( void * arg ) +{ + strarg_t * strarg = (strarg_t *)arg; + + if ( strncmp( "bg", strarg->str, 2 ) == 0 || + strncmp( "man", strarg->str, 3 ) == 0 || + strncmp( "auto", strarg->str, 4 ) == 0 ) + { + return 1; + } + + return 0; +} + +/** + * \brief Modify the colorkey_handling var according to str + * + * Checks if a valid pointer ( not NULL ) to the string + * was given. And in that case modifies the colorkey_handling + * var to reflect the requested behaviour. + * If nothing happens the content of colorkey_handling stays + * the same. + * + * \param str Pointer to the string or NULL + * + */ +void xv_setup_colorkeyhandling( char const * ck_method_str, + char const * ck_str ) +{ + /* 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; + } + else if ( strncmp( ck_str, "set", 3 ) == 0 ) + { + xv_ck_info.source = CK_SRC_SET; + } + } + /* check if a valid pointer to the string was passed */ + if ( ck_method_str ) + { + if ( strncmp( ck_method_str, "bg", 2 ) == 0 ) + { + xv_ck_info.method = CK_METHOD_BACKGROUND; + } + else if ( strncmp( ck_method_str, "man", 3 ) == 0 ) + { + xv_ck_info.method = CK_METHOD_MANUALFILL; + } + else if ( strncmp( ck_method_str, "auto", 4 ) == 0 ) + { + xv_ck_info.method = CK_METHOD_AUTOPAINT; + } + } +} + #endif
--- a/libvo/x11_common.h Sun Feb 20 18:34:06 2005 +0000 +++ b/libvo/x11_common.h Sun Feb 20 22:43:25 2005 +0000 @@ -79,8 +79,36 @@ extern XSizeHints vo_hint; #ifdef HAVE_XV +//XvPortID xv_port; +extern unsigned int xv_port; + extern int vo_xv_set_eq(uint32_t xv_port, char * name, int value); extern int vo_xv_get_eq(uint32_t xv_port, char * name, int *value); + +/*** 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 +#define CK_METHOD_AUTOPAINT 2 ///< let xv draw the colorkey +#define CK_METHOD_MANUALFILL 3 ///< manually draw the colorkey +#define CK_SRC_USE 0 ///< use specified / default colorkey +#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; + +extern int vo_xv_init_colorkey(); +extern void vo_xv_colorkey(uint32_t x,uint32_t y, uint32_t w, uint32_t h); + +/*** test functions for common suboptions ***/ +int xv_test_ck( void * arg ); +int xv_test_ckm( void * arg ); #endif #ifdef HAVE_NEW_GUI