From: Sam Hocevar Date: Sat, 5 Jan 2002 02:22:03 +0000 (+0000) Subject: * ./include/common.h: hton64 is now an inline function. X-Git-Tag: 0.3.0~274 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=aea6698debf9e83fa9fa8f332683ef0798728c2a;p=vlc * ./include/common.h: hton64 is now an inline function. * ./src/video_output/vout_pictures.c et al.: vout4 now automatically detects when two chroma formats are the same, such as UYVY/Y422, or roughly equivalent, such as I420/YV12. Plugins need not worry about conversion anymore. --- diff --git a/BUGS b/BUGS index 4381c446e1..dc4d0d9b67 100644 --- a/BUGS +++ b/BUGS @@ -1,5 +1,5 @@ List of known vlc bugs -$Id: BUGS,v 1.1 2002/01/04 14:01:33 sam Exp $ +$Id: BUGS,v 1.2 2002/01/05 02:22:02 sam Exp $ Please try to keep this file up to date. Also, grep for FIXME in the source files for more and more bugs to fix. @@ -23,10 +23,18 @@ Input: * vlc:foo targets don't work anymore. +Audio output: + + * Audio output stutters on some audio cards. For instance kwyxz's SB + 128 with an es1371 chip. + + Video output: * We don't render subtitles on RGB surfaces. + * Subtitle colors are just plain wrong. + * The DirectX video output plugin is broken because of vout4. * The GGI video output plugin is broken because of vout4. diff --git a/include/common.h b/include/common.h index 5261701065..96f19c5b99 100644 --- a/include/common.h +++ b/include/common.h @@ -3,7 +3,7 @@ * Collection of useful common types and macros definitions ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: common.h,v 1.64 2002/01/04 14:01:34 sam Exp $ + * $Id: common.h,v 1.65 2002/01/05 02:22:02 sam Exp $ * * Authors: Samuel Hocevar * Vincent Seguin @@ -286,8 +286,6 @@ struct probedata_s; * byte orders other than little and big endians are not supported, but only * the VAX seems to have such exotic properties - note that these 'functions' * needs or the local equivalent. */ -/* FIXME: hton64 should be declared as an extern inline function to avoid - * border effects (see byteorder.h) */ #if WORDS_BIGENDIAN # define hton16 htons # define hton32 htonl @@ -298,7 +296,12 @@ struct probedata_s; #else # define hton16 htons # define hton32 htonl -# define hton64(i) ( ((u64)(htonl((i) & 0xffffffff)) << 32) | htonl(((i) >> 32) & 0xffffffff ) ) + static __inline__ u64 __hton64( u64 i ) + { + return ((u64)(htonl((i) & 0xffffffff)) << 32) + | htonl(((i) >> 32) & 0xffffffff ); + } +# define hton64(i) __hton64( i ) # define ntoh16 ntohs # define ntoh32 ntohl # define ntoh64 hton64 diff --git a/include/video.h b/include/video.h index 00c6a11fb9..9e0fae6ef3 100644 --- a/include/video.h +++ b/include/video.h @@ -4,7 +4,7 @@ * includes all common video types and constants. ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video.h,v 1.39 2002/01/04 14:01:34 sam Exp $ + * $Id: video.h,v 1.40 2002/01/05 02:22:03 sam Exp $ * * Authors: Vincent Seguin * @@ -174,6 +174,62 @@ typedef struct picture_heap_s #define U_PIXELS p[U_PLANE].p_pixels #define V_PIXELS p[V_PLANE].p_pixels +static __inline__ int vout_ChromaCmp( u32 i_chroma, u32 i_amorhc ) +{ + /* If they are the same, they are the same ! */ + if( i_chroma == i_amorhc ) + { + return 1; + } + + /* Check for equivalence classes */ + switch( i_chroma ) + { + case FOURCC_I420: + case FOURCC_IYUV: + case FOURCC_YV12: + switch( i_amorhc ) + { + case FOURCC_I420: + case FOURCC_IYUV: + case FOURCC_YV12: + return 1; + + default: + return 0; + } + + case FOURCC_UYVY: + case FOURCC_UYNV: + case FOURCC_Y422: + switch( i_amorhc ) + { + case FOURCC_UYVY: + case FOURCC_UYNV: + case FOURCC_Y422: + return 1; + + default: + return 0; + } + + case FOURCC_YUY2: + case FOURCC_YUNV: + switch( i_amorhc ) + { + case FOURCC_YUY2: + case FOURCC_YUNV: + return 1; + + default: + return 0; + } + + default: + return 0; + } +} + /***************************************************************************** * vout_CopyPicture: copy a picture to another one ***************************************************************************** diff --git a/plugins/sdl/vout_sdl.c b/plugins/sdl/vout_sdl.c index 41f3e423eb..266fc24f00 100644 --- a/plugins/sdl/vout_sdl.c +++ b/plugins/sdl/vout_sdl.c @@ -2,7 +2,7 @@ * vout_sdl.c: SDL video output display method ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: vout_sdl.c,v 1.76 2002/01/04 14:01:34 sam Exp $ + * $Id: vout_sdl.c,v 1.77 2002/01/05 02:22:03 sam Exp $ * * Authors: Samuel Hocevar * Pierre Baillet @@ -61,13 +61,12 @@ typedef struct vout_sys_s { SDL_Surface * p_display; /* display device */ - SDL_Overlay * p_overlay; /* An overlay we keep to grab the XVideo port */ int i_width; int i_height; /* For YUV output */ - u32 i_chroma; /* The internally selected chroma */ + SDL_Overlay * p_overlay; /* An overlay we keep to grab the XVideo port */ /* For RGB output */ int i_surfaces; @@ -111,47 +110,6 @@ static __inline__ void vout_Seek( off_t i_seek ) #undef area } -/***************************************************************************** - * Return the best suited FourCC value for a given chroma. We use this - * because a decoder may output FOURCC_IYUV, which is exactly the same as - * FOURCC_I420, but X servers usually know FOURCC_I420 and not FOURCC_IYUV. - *****************************************************************************/ -static __inline__ u32 BestChroma( u32 i_chroma ) -{ - /* XXX: don't forget to update vout_Init if you change this */ - switch( i_chroma ) - { - /* These ones are almost the same */ - case FOURCC_I420: - case FOURCC_IYUV: - case FOURCC_YV12: - return SDL_YV12_OVERLAY; - - /* These ones are all the same */ - case FOURCC_UYVY: - case FOURCC_UYNV: - case FOURCC_Y422: - return SDL_UYVY_OVERLAY; - - /* These ones are all the same */ - case FOURCC_YUY2: - case FOURCC_YUNV: - return SDL_YUY2_OVERLAY; - - /* We know this one */ - case FOURCC_YVYU: - return SDL_YVYU_OVERLAY; - - /* This is seldom supported, but we know how to convert it */ - case FOURCC_I422: - return SDL_YUY2_OVERLAY; - - /* We don't know this chroma, but maybe SDL does */ - default: - return i_chroma; - } -} - /***************************************************************************** * Local prototypes. *****************************************************************************/ @@ -301,7 +259,6 @@ static int vout_Init( vout_thread_t *p_vout ) if( p_vout->p_sys->p_overlay == NULL ) { /* All we have is an RGB image with square pixels */ - p_vout->output.i_chroma = p_vout->p_sys->i_chroma; p_vout->output.i_width = p_vout->p_sys->i_width; p_vout->output.i_height = p_vout->p_sys->i_height; p_vout->output.i_aspect = p_vout->p_sys->i_width @@ -310,46 +267,11 @@ static int vout_Init( vout_thread_t *p_vout ) } else { - switch( p_vout->render.i_chroma ) - { - case FOURCC_I420: - case FOURCC_IYUV: - case FOURCC_YV12: - - case FOURCC_UYVY: - case FOURCC_UYNV: - case FOURCC_Y422: - - case FOURCC_YUY2: - case FOURCC_YUNV: - - case FOURCC_YVYU: - /* We can directly handle all these chromas */ - p_vout->output.i_chroma = p_vout->render.i_chroma; - p_vout->output.i_width = p_vout->render.i_width; - p_vout->output.i_height = p_vout->render.i_height; - p_vout->output.i_aspect = p_vout->render.i_aspect; - break; - - case FOURCC_I422: - /* We need to convert this one, but at least we keep the - * aspect ratio */ - p_vout->output.i_chroma = p_vout->p_sys->i_chroma; - p_vout->output.i_width = p_vout->render.i_width; - p_vout->output.i_height = p_vout->render.i_height; - p_vout->output.i_aspect = p_vout->render.i_aspect; - break; - - default: - /* All we have is an RGB image with square pixels */ - p_vout->output.i_chroma = p_vout->p_sys->i_chroma; - p_vout->output.i_width = p_vout->p_sys->i_width; - p_vout->output.i_height = p_vout->p_sys->i_height; - p_vout->output.i_aspect = p_vout->p_sys->i_width - * VOUT_ASPECT_FACTOR - / p_vout->p_sys->i_height; - break; - } + /* We may need to convert the chroma, but at least we keep the + * aspect ratio */ + p_vout->output.i_width = p_vout->render.i_width; + p_vout->output.i_height = p_vout->render.i_height; + p_vout->output.i_aspect = p_vout->render.i_aspect; } /* Try to initialize SDL_MAX_DIRECTBUFFERS direct buffers */ @@ -674,35 +596,80 @@ static int SDLOpenDisplay( vout_thread_t *p_vout ) SDL_LockSurface( p_vout->p_sys->p_display ); - /* Ask BestChroma what we should use as a chroma */ - p_vout->p_sys->i_chroma = BestChroma( p_vout->render.i_chroma ); + switch( p_vout->render.i_chroma ) + { + case FOURCC_I420: + case FOURCC_IYUV: + p_vout->output.i_chroma = SDL_IYUV_OVERLAY; + break; + case FOURCC_YUY2: + case FOURCC_YUNV: + p_vout->output.i_chroma = SDL_YUY2_OVERLAY; + break; + case FOURCC_UYVY: + case FOURCC_UYNV: + case FOURCC_Y422: + p_vout->output.i_chroma = SDL_UYVY_OVERLAY; + break; + case FOURCC_YVYU: + p_vout->output.i_chroma = SDL_YVYU_OVERLAY; + break; + case FOURCC_YV12: + default: + p_vout->output.i_chroma = SDL_YV12_OVERLAY; + break; + } p_vout->p_sys->p_overlay = - SDL_CreateYUVOverlay( 32, 32, p_vout->p_sys->i_chroma, + SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma, p_vout->p_sys->p_display ); - /* See if BestChroma's guess was valid */ if( p_vout->p_sys->p_overlay == NULL ) { - intf_WarnMsg( 3, "vout warning: cannot set SDL overlay 0x%.8llx", - p_vout->p_sys->i_chroma ); + p_vout->output.i_chroma = SDL_IYUV_OVERLAY; + p_vout->p_sys->p_overlay = + SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma, + p_vout->p_sys->p_display ); + } + + if( p_vout->p_sys->p_overlay == NULL ) + { + p_vout->output.i_chroma = SDL_YV12_OVERLAY; + p_vout->p_sys->p_overlay = + SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma, + p_vout->p_sys->p_display ); + } + + if( p_vout->p_sys->p_overlay == NULL ) + { + p_vout->output.i_chroma = SDL_YUY2_OVERLAY; + p_vout->p_sys->p_overlay = + SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma, + p_vout->p_sys->p_display ); + } + + if( p_vout->p_sys->p_overlay == NULL ) + { + intf_WarnMsg( 3, "vout warning: no SDL overlay for 0x%.8x (%4.4s)", + p_vout->render.i_chroma, + (char*)&p_vout->render.i_chroma ); switch( p_vout->p_sys->p_display->format->BitsPerPixel ) { case 8: - p_vout->p_sys->i_chroma = FOURCC_BI_RGB; + p_vout->output.i_chroma = FOURCC_BI_RGB; break; case 15: - p_vout->p_sys->i_chroma = FOURCC_RV15; + p_vout->output.i_chroma = FOURCC_RV15; break; case 16: - p_vout->p_sys->i_chroma = FOURCC_RV16; + p_vout->output.i_chroma = FOURCC_RV16; break; case 24: - p_vout->p_sys->i_chroma = FOURCC_BI_BITFIELDS; + p_vout->output.i_chroma = FOURCC_BI_BITFIELDS; break; case 32: - p_vout->p_sys->i_chroma = FOURCC_BI_BITFIELDS; + p_vout->output.i_chroma = FOURCC_BI_BITFIELDS; break; default: intf_ErrMsg( "vout error: unknown screen depth" ); @@ -760,123 +727,121 @@ static int SDLNewPicture( vout_thread_t *p_vout, picture_t *p_pic ) int i_width = p_vout->output.i_width; int i_height = p_vout->output.i_height; - switch( p_vout->p_sys->i_chroma ) + if( p_vout->p_sys->p_overlay == NULL ) { - case SDL_YV12_OVERLAY: - case SDL_IYUV_OVERLAY: - case SDL_YUY2_OVERLAY: - case SDL_UYVY_OVERLAY: - case SDL_YVYU_OVERLAY: - p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); - - if( p_pic->p_sys == NULL ) - { - return -1; - } - - p_pic->p_sys->p_overlay = - SDL_CreateYUVOverlay( i_width, i_height, - p_vout->p_sys->i_chroma, - p_vout->p_sys->p_display ); - - if( p_pic->p_sys->p_overlay == NULL ) - { - free( p_pic->p_sys ); - return -1; - } - - SDL_LockYUVOverlay( p_pic->p_sys->p_overlay ); - - p_pic->Y_PIXELS = p_pic->p_sys->p_overlay->pixels[0]; - p_pic->p[Y_PLANE].i_lines = p_pic->p_sys->p_overlay->h; - p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[0]; + /* RGB picture */ + if( p_vout->p_sys->i_surfaces ) + { + /* We already allocated this surface, return */ + return -1; + } - switch( p_vout->p_sys->i_chroma ) - { - case SDL_YV12_OVERLAY: - p_pic->p[Y_PLANE].i_pixel_bytes = 1; - p_pic->p[Y_PLANE].b_margin = 0; - - p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[2]; - p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; - p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[2]; - p_pic->p[U_PLANE].i_pixel_bytes = 1; - p_pic->p[U_PLANE].b_margin = 0; - - p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[1]; - p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; - p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1]; - p_pic->p[V_PLANE].i_pixel_bytes = 1; - p_pic->p[V_PLANE].b_margin = 0; - - p_pic->i_planes = 3; - break; + p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); - case SDL_IYUV_OVERLAY: - p_pic->p[Y_PLANE].i_pixel_bytes = 1; - p_pic->p[Y_PLANE].b_margin = 0; + if( p_pic->p_sys == NULL ) + { + return -1; + } - p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[1]; - p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; - p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1]; - p_pic->p[U_PLANE].i_pixel_bytes = 1; - p_pic->p[U_PLANE].b_margin = 0; + p_pic->p->p_pixels = p_vout->p_sys->p_display->pixels; + p_pic->p->i_lines = p_vout->p_sys->p_display->h; + p_pic->p->i_pitch = p_vout->p_sys->p_display->pitch; + p_pic->p->i_pixel_bytes = 2; - p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[2]; - p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; - p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[2]; - p_pic->p[V_PLANE].i_pixel_bytes = 1; - p_pic->p[V_PLANE].b_margin = 0; + if( p_pic->p->i_pitch == 2 * p_vout->p_sys->p_display->w ) + { + p_pic->p->b_margin = 0; + } + else + { + p_pic->p->b_margin = 1; + p_pic->p->b_hidden = 1; + p_pic->p->i_visible_bytes = 2 * p_vout->p_sys->p_display->w; + } - p_pic->i_planes = 3; - break; + p_pic->p->i_red_mask = p_vout->p_sys->p_display->format->Rmask; + p_pic->p->i_green_mask = p_vout->p_sys->p_display->format->Gmask; + p_pic->p->i_blue_mask = p_vout->p_sys->p_display->format->Bmask; - default: - p_pic->p[Y_PLANE].i_pixel_bytes = 2; - p_pic->p[Y_PLANE].b_margin = 0; + p_vout->p_sys->i_surfaces++; - p_pic->i_planes = 1; - break; - } + p_pic->i_planes = 1; + } + else + { + p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); - return 0; + if( p_pic->p_sys == NULL ) + { + return -1; + } - default: - /* RGB picture */ - if( p_vout->p_sys->i_surfaces ) - { - /* We already allocated this surface, return */ - return -1; - } + p_pic->p_sys->p_overlay = + SDL_CreateYUVOverlay( i_width, i_height, + p_vout->output.i_chroma, + p_vout->p_sys->p_display ); - p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); + if( p_pic->p_sys->p_overlay == NULL ) + { + free( p_pic->p_sys ); + return -1; + } - if( p_pic->p_sys == NULL ) - { - return -1; - } + SDL_LockYUVOverlay( p_pic->p_sys->p_overlay ); - p_pic->p->p_pixels = p_vout->p_sys->p_display->pixels; - p_pic->p->i_lines = p_vout->p_sys->p_display->h; - p_pic->p->i_pitch = p_vout->p_sys->p_display->pitch; + p_pic->Y_PIXELS = p_pic->p_sys->p_overlay->pixels[0]; + p_pic->p[Y_PLANE].i_lines = p_pic->p_sys->p_overlay->h; + p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[0]; - p_pic->p->i_pixel_bytes = 2; - if( p_pic->p->i_pitch != 2 * p_vout->p_sys->p_display->w ) - { - intf_ErrMsg("OOO XXX OOO --- Wooooooohoooo !! --- OOO XXX OOO"); - intf_ErrMsg("%i != 2 * %i", p_pic->p->i_pitch, p_vout->p_sys->p_display->w ); - } - p_pic->p->b_margin = 0; + switch( p_vout->output.i_chroma ) + { + case SDL_YV12_OVERLAY: + p_pic->p[Y_PLANE].i_pixel_bytes = 1; + p_pic->p[Y_PLANE].b_margin = 0; + + p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[2]; + p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; + p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[2]; + p_pic->p[U_PLANE].i_pixel_bytes = 1; + p_pic->p[U_PLANE].b_margin = 0; + + p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[1]; + p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; + p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1]; + p_pic->p[V_PLANE].i_pixel_bytes = 1; + p_pic->p[V_PLANE].b_margin = 0; + + p_pic->i_planes = 3; + break; - p_pic->p->i_red_mask = p_vout->p_sys->p_display->format->Rmask; - p_pic->p->i_green_mask = p_vout->p_sys->p_display->format->Gmask; - p_pic->p->i_blue_mask = p_vout->p_sys->p_display->format->Bmask; + case SDL_IYUV_OVERLAY: + p_pic->p[Y_PLANE].i_pixel_bytes = 1; + p_pic->p[Y_PLANE].b_margin = 0; + + p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[1]; + p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; + p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1]; + p_pic->p[U_PLANE].i_pixel_bytes = 1; + p_pic->p[U_PLANE].b_margin = 0; + + p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[2]; + p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2; + p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[2]; + p_pic->p[V_PLANE].i_pixel_bytes = 1; + p_pic->p[V_PLANE].b_margin = 0; + + p_pic->i_planes = 3; + break; - p_vout->p_sys->i_surfaces++; + default: + p_pic->p[Y_PLANE].i_pixel_bytes = 2; + p_pic->p[Y_PLANE].b_margin = 0; p_pic->i_planes = 1; - - return 0; + break; + } } + + return 0; } diff --git a/plugins/x11/xcommon.c b/plugins/x11/xcommon.c index 9f4fe75dc8..94526078fd 100644 --- a/plugins/x11/xcommon.c +++ b/plugins/x11/xcommon.c @@ -2,7 +2,7 @@ * xcommon.c: Functions common to the X11 and XVideo plugins ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: xcommon.c,v 1.5 2002/01/04 14:01:34 sam Exp $ + * $Id: xcommon.c,v 1.6 2002/01/05 02:22:03 sam Exp $ * * Authors: Vincent Seguin * Samuel Hocevar @@ -112,7 +112,7 @@ static void DestroyCursor ( vout_thread_t * ); static void ToggleCursor ( vout_thread_t * ); #ifdef MODULE_NAME_IS_xvideo -static int XVideoGetPort ( Display *, int ); +static int XVideoGetPort ( Display *, u32, u32 * ); static void XVideoReleasePort ( Display *, int ); #endif @@ -138,7 +138,6 @@ typedef struct vout_sys_s Window yuv_window; /* sub-window for displaying yuv video data */ int i_xvport; - u32 i_chroma; /* the chroma we will select */ #else Colormap colormap; /* colormap used (8bpp only) */ @@ -236,41 +235,6 @@ static __inline__ void vout_Seek( off_t i_seek ) #undef area } -/***************************************************************************** - * Return the best suited FourCC value for a given chroma. We use this - * because a decoder may output FOURCC_IYUV, which is exactly the same as - * FOURCC_I420, but X servers usually know FOURCC_I420 and not FOURCC_IYUV. - *****************************************************************************/ -static __inline__ u32 BestChroma( u32 i_chroma ) -{ - /* XXX: don't forget to update vout_Init if you change this */ - switch( i_chroma ) - { - /* These ones are all the same */ - case FOURCC_I420: - case FOURCC_IYUV: - case FOURCC_YV12: - return FOURCC_I420; - - /* These ones are all the same */ - case FOURCC_YUY2: - case FOURCC_YUNV: - return FOURCC_YUY2; - - /* We know this one */ - case FOURCC_Y211: - return FOURCC_Y211; - - /* This is seldom supported, but we know how to convert */ - case FOURCC_I422: - return FOURCC_YUY2; - - default: - return i_chroma; - break; - } -} - /***************************************************************************** * Functions exported as capabilities. They are declared as static so that * we don't pollute the namespace too much. @@ -299,7 +263,7 @@ static int vout_Probe( probedata_t *p_data ) Display *p_display; /* display pointer */ char *psz_display; #ifdef MODULE_NAME_IS_xvideo - int i_xvport; + int i_xvport, i_dummy; #endif /* Open display, unsing 'vlc_display' or DISPLAY environment variable */ @@ -312,17 +276,23 @@ static int vout_Probe( probedata_t *p_data ) } #ifdef MODULE_NAME_IS_xvideo - /* Check that there is an available XVideo port */ - i_xvport = XVideoGetPort( p_display, BestChroma( p_data->vout.i_chroma ) ); + /* Check that there is an available XVideo port for this format */ + i_xvport = XVideoGetPort( p_display, p_data->vout.i_chroma, &i_dummy ); if( i_xvport < 0 ) { /* It failed, but it's not completely lost ! We try to open an - * XVideo port for a simple 16bpp RGB picture */ - i_xvport = XVideoGetPort( p_display, FOURCC_RV16 ); + * XVideo port for a YUY2 picture */ + i_xvport = XVideoGetPort( p_display, FOURCC_YUY2, &i_dummy ); if( i_xvport < 0 ) { - XCloseDisplay( p_display ); - return( 0 ); + /* It failed, but it's not completely lost ! We try to open an + * XVideo port for a simple 16bpp RGB picture */ + i_xvport = XVideoGetPort( p_display, FOURCC_RV16, &i_dummy ); + if( i_xvport < 0 ) + { + XCloseDisplay( p_display ); + return( 0 ); + } } } XVideoReleasePort( p_display, i_xvport ); @@ -370,27 +340,33 @@ static int vout_Create( vout_thread_t *p_vout ) p_vout->p_sys->i_screen = DefaultScreen( p_vout->p_sys->p_display ); #ifdef MODULE_NAME_IS_xvideo - /* Try to guess the chroma format we will be using */ - p_vout->p_sys->i_chroma = BestChroma( p_vout->render.i_chroma ); - /* Check that we have access to an XVideo port providing this chroma */ p_vout->p_sys->i_xvport = XVideoGetPort( p_vout->p_sys->p_display, - p_vout->p_sys->i_chroma ); + p_vout->render.i_chroma, + &p_vout->output.i_chroma ); if( p_vout->p_sys->i_xvport < 0 ) { /* It failed, but it's not completely lost ! We try to open an - * XVideo port for a simple 16bpp RGB picture */ + * XVideo port for an YUY2 picture. We'll need to do an YUV + * conversion, but at least it has got scaling. */ p_vout->p_sys->i_xvport = XVideoGetPort( p_vout->p_sys->p_display, - FOURCC_RV16 ); + FOURCC_YUY2, + &p_vout->output.i_chroma ); if( p_vout->p_sys->i_xvport < 0 ) { - XCloseDisplay( p_vout->p_sys->p_display ); - free( p_vout->p_sys ); - return 1; + /* It failed, but it's not completely lost ! We try to open an + * XVideo port for a simple 16bpp RGB picture. We'll need to do + * an YUV conversion, but at least it has got scaling. */ + p_vout->p_sys->i_xvport = XVideoGetPort( p_vout->p_sys->p_display, + FOURCC_RV16, + &p_vout->output.i_chroma ); + if( p_vout->p_sys->i_xvport < 0 ) + { + XCloseDisplay( p_vout->p_sys->p_display ); + free( p_vout->p_sys ); + return 1; + } } - - /* This one worked ! That's better than nothing, it has HW scaling. */ - p_vout->p_sys->i_chroma = FOURCC_RV16; } #endif @@ -475,49 +451,12 @@ static int vout_Init( vout_thread_t *p_vout ) I_OUTPUTPICTURES = 0; #ifdef MODULE_NAME_IS_xvideo - /* Initialize the output structure ; we already found an XVideo port, - * which either suits p_vout->render.i_chroma or p_vout->p_sys->i_chroma - * if nothing was found at the first attempt. */ - switch( p_vout->render.i_chroma ) - { - /* These ones are equivalent to what we chose instead, for instance - * we tell the video output we can do FOURCC_IYUV even though we - * actually do FOURCC_I420. */ - case FOURCC_I420: - case FOURCC_IYUV: - case FOURCC_YV12: - - case FOURCC_YUY2: - case FOURCC_YUNV: - - case FOURCC_Y211: - p_vout->output.i_chroma = p_vout->render.i_chroma; - p_vout->output.i_width = p_vout->render.i_width; - p_vout->output.i_height = p_vout->render.i_height; - p_vout->output.i_aspect = p_vout->render.i_aspect; - break; - - /* These ones aren't equivalent to what we chose, so we need to - * warn the decoder that we chose another chroma and that it has - * conversion to do. */ - - /* At least for this one we can have the aspect ratio */ - case FOURCC_I422: - p_vout->output.i_chroma = p_vout->p_sys->i_chroma; - p_vout->output.i_width = p_vout->render.i_width; - p_vout->output.i_height = p_vout->render.i_height; - p_vout->output.i_aspect = p_vout->render.i_aspect; - break; - - /* Here we don't even control the aspect ratio */ - default: - p_vout->output.i_chroma = p_vout->p_sys->i_chroma; - p_vout->output.i_width = p_vout->render.i_width; - p_vout->output.i_height = p_vout->render.i_height; - p_vout->output.i_aspect = p_vout->p_sys->i_width - * VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height; - break; - } + /* Initialize the output structure; we already found an XVideo port, + * and the corresponding chroma we will be using. Since we can + * arbitrary scale, stick to the coordinates and aspect. */ + p_vout->output.i_width = p_vout->render.i_width; + p_vout->output.i_height = p_vout->render.i_height; + p_vout->output.i_aspect = p_vout->render.i_aspect; #else /* Initialize the output structure: RGB with square pixels, whatever @@ -1236,7 +1175,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) CreateShmImage( p_vout->p_sys->p_display, #ifdef MODULE_NAME_IS_xvideo p_vout->p_sys->i_xvport, - p_vout->p_sys->i_chroma, + p_vout->output.i_chroma, #else p_vout->p_sys->p_visual, p_vout->p_sys->i_screen_depth, @@ -1251,7 +1190,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) CreateImage( p_vout->p_sys->p_display, #ifdef MODULE_NAME_IS_xvideo p_vout->p_sys->i_xvport, - p_vout->p_sys->i_chroma, + p_vout->output.i_chroma, #else p_vout->p_sys->p_visual, p_vout->p_sys->i_screen_depth, @@ -1266,9 +1205,9 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) return -1; } -#ifdef MODULE_NAME_IS_xvideo - switch( p_vout->p_sys->i_chroma ) + switch( p_vout->output.i_chroma ) { +#ifdef MODULE_NAME_IS_xvideo case FOURCC_I420: p_pic->Y_PIXELS = p_pic->p_sys->p_image->data @@ -1295,19 +1234,59 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) p_pic->i_planes = 3; break; + case FOURCC_YV12: + + p_pic->Y_PIXELS = p_pic->p_sys->p_image->data + + p_pic->p_sys->p_image->offsets[0]; + p_pic->p[Y_PLANE].i_lines = p_vout->output.i_height; + p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[0]; + p_pic->p[Y_PLANE].i_pixel_bytes = 1; + p_pic->p[Y_PLANE].b_margin = 0; + + p_pic->U_PIXELS = p_pic->p_sys->p_image->data + + p_pic->p_sys->p_image->offsets[2]; + p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2; + p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[2]; + p_pic->p[Y_PLANE].i_pixel_bytes = 1; + p_pic->p[Y_PLANE].b_margin = 0; + + p_pic->V_PIXELS = p_pic->p_sys->p_image->data + + p_pic->p_sys->p_image->offsets[1]; + p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2; + p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[1]; + p_pic->p[Y_PLANE].i_pixel_bytes = 1; + p_pic->p[Y_PLANE].b_margin = 0; + + p_pic->i_planes = 3; + break; + case FOURCC_Y211: p_pic->p->p_pixels = p_pic->p_sys->p_image->data + p_pic->p_sys->p_image->offsets[0]; p_pic->p->i_lines = p_vout->output.i_height; - p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0]; - p_pic->p->i_pixel_bytes = 1; + /* XXX: this just looks so plain wrong... check it out ! */ + p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0] / 4; + p_pic->p->i_pixel_bytes = 4; p_pic->p->b_margin = 0; p_pic->i_planes = 1; break; case FOURCC_YUY2: + case FOURCC_UYVY: + + p_pic->p->p_pixels = p_pic->p_sys->p_image->data + + p_pic->p_sys->p_image->offsets[0]; + p_pic->p->i_lines = p_vout->output.i_height; + p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0]; + p_pic->p->i_pixel_bytes = 4; + p_pic->p->b_margin = 0; + + p_pic->i_planes = 1; + break; + + case FOURCC_RV15: p_pic->p->p_pixels = p_pic->p_sys->p_image->data + p_pic->p_sys->p_image->offsets[0]; @@ -1316,6 +1295,10 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) p_pic->p->i_pixel_bytes = 2; p_pic->p->b_margin = 0; + p_pic->p->i_red_mask = 0x001f; + p_pic->p->i_green_mask = 0x07e0; + p_pic->p->i_blue_mask = 0xf800; + p_pic->i_planes = 1; break; @@ -1335,18 +1318,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) p_pic->i_planes = 1; break; - default: - /* Unknown chroma, tell the guy to get lost */ - IMAGE_FREE( p_pic->p_sys->p_image ); - free( p_pic->p_sys ); - intf_ErrMsg( "vout error: never heard of chroma 0x%.8x", - p_vout->p_sys->i_chroma ); - p_pic->i_planes = 0; - return -1; - } #else - switch( p_vout->output.i_chroma ) - { case FOURCC_RV16: p_pic->p->p_pixels = p_pic->p_sys->p_image->data @@ -1373,17 +1345,18 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) p_pic->i_planes = 1; break; +#endif default: /* Unknown chroma, tell the guy to get lost */ IMAGE_FREE( p_pic->p_sys->p_image ); free( p_pic->p_sys ); - intf_ErrMsg( "vout error: never heard of chroma 0x%.8x", - p_vout->output.i_chroma ); + intf_ErrMsg( "vout error: never heard of chroma 0x%.8x (%4.4s)", + p_vout->output.i_chroma, + (char*)&p_vout->output.i_chroma ); p_pic->i_planes = 0; return -1; } -#endif return 0; } @@ -1565,7 +1538,9 @@ static void EnableXScreenSaver( vout_thread_t *p_vout ) if( DPMSQueryExtension( p_vout->p_sys->p_display, &dummy, &dummy ) ) { if( p_vout->p_sys->b_ss_dpms ) + { DPMSEnable( p_vout->p_sys->p_display ); + } } } @@ -1666,7 +1641,7 @@ static void ToggleCursor( vout_thread_t *p_vout ) /***************************************************************************** * XVideoGetPort: get YUV12 port *****************************************************************************/ -static int XVideoGetPort( Display *dpy, int i_id ) +static int XVideoGetPort( Display *dpy, u32 i_chroma, u32 *pi_newchroma ) { XvAdaptorInfo *p_adaptor; unsigned int i; @@ -1713,7 +1688,6 @@ static int XVideoGetPort( Display *dpy, int i_id ) i_selected_port = -1; i_requested_adaptor = main_GetIntVariable( VOUT_XVADAPTOR_VAR, -1 ); - /* No special xv port has been requested so try all of them */ for( i_adaptor = 0; i_adaptor < i_num_adaptors; ++i_adaptor ) { XvImageFormatValues *p_formats; @@ -1734,19 +1708,22 @@ static int XVideoGetPort( Display *dpy, int i_id ) continue; } - /* Check that port supports YUV12 planar format... */ + /* Check that adaptor supports our requested format... */ p_formats = XvListImageFormats( dpy, p_adaptor[i_adaptor].base_id, &i_num_formats ); - for( i_format = 0; i_format < i_num_formats; i_format++ ) + for( i_format = 0; + i_format < i_num_formats && ( i_selected_port == -1 ); + i_format++ ) { XvEncodingInfo *p_enc; int i_enc, i_num_encodings; XvAttribute *p_attr; int i_attr, i_num_attributes; - /* If this is not the format we want, forget it */ - if( p_formats[ i_format ].id != i_id ) + /* If this is not the format we want, or at least a + * similar one, forget it */ + if( !vout_ChromaCmp( p_formats[ i_format ].id, i_chroma ) ) { continue; } @@ -1761,6 +1738,7 @@ static int XVideoGetPort( Display *dpy, int i_id ) if( XvGrabPort( dpy, i_port, CurrentTime ) == Success ) { i_selected_port = i_port; + *pi_newchroma = p_formats[ i_format ].id; } } @@ -1840,13 +1818,13 @@ static int XVideoGetPort( Display *dpy, int i_id ) if( i_requested_adaptor == -1 ) { intf_WarnMsg( 3, "vout: no free XVideo port found for format " - "0x%.8x", i_id ); + "0x%.8x (%4.4s)", i_chroma, (char*)&i_chroma ); } else { intf_WarnMsg( 3, "vout: XVideo adaptor %i does not have a free " - "XVideo port for format 0x%.8x", - i_requested_adaptor, i_id ); + "XVideo port for format 0x%.8x (%4.4s)", + i_requested_adaptor, i_chroma, (char*)&i_chroma ); } } diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index f87a028568..3792da7313 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -5,7 +5,7 @@ * thread, and destroy a previously oppened video output thread. ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: video_output.c,v 1.152 2002/01/04 14:01:35 sam Exp $ + * $Id: video_output.c,v 1.153 2002/01/05 02:22:03 sam Exp $ * * Authors: Vincent Seguin * @@ -279,24 +279,26 @@ static int InitThread( vout_thread_t *p_vout ) intf_WarnMsg( 1, "vout info: got %i direct buffer(s)", I_OUTPUTPICTURES ); i_pgcd = ReduceHeight( p_vout->render.i_aspect ); - intf_WarnMsg( 1, "vout info: picture in %ix%i, chroma 0x%.8x, " + intf_WarnMsg( 1, "vout info: picture in %ix%i, chroma 0x%.8x (%4.4s), " "aspect ratio %i:%i", p_vout->render.i_width, p_vout->render.i_height, - p_vout->render.i_chroma, p_vout->render.i_aspect / i_pgcd, + p_vout->render.i_chroma, (char*)&p_vout->render.i_chroma, + p_vout->render.i_aspect / i_pgcd, VOUT_ASPECT_FACTOR / i_pgcd ); i_pgcd = ReduceHeight( p_vout->output.i_aspect ); - intf_WarnMsg( 1, "vout info: picture out %ix%i, chroma 0x%.8x, " + intf_WarnMsg( 1, "vout info: picture out %ix%i, chroma 0x%.8x (%4.4s), " "aspect ratio %i:%i", p_vout->output.i_width, p_vout->output.i_height, - p_vout->output.i_chroma, p_vout->output.i_aspect / i_pgcd, + p_vout->output.i_chroma, (char*)&p_vout->output.i_chroma, + p_vout->output.i_aspect / i_pgcd, VOUT_ASPECT_FACTOR / i_pgcd ); /* Check whether we managed to create direct buffers similar to * the render buffers, ie same size, chroma and aspect ratio */ if( ( p_vout->output.i_width == p_vout->render.i_width ) && ( p_vout->output.i_height == p_vout->render.i_height ) - && ( p_vout->output.i_chroma == p_vout->render.i_chroma ) + && ( vout_ChromaCmp( p_vout->output.i_chroma, p_vout->render.i_chroma ) ) && ( p_vout->output.i_aspect == p_vout->render.i_aspect ) ) { /* Cool ! We have direct buffers, we can ask the decoder to @@ -305,7 +307,7 @@ static int InitThread( vout_thread_t *p_vout ) * for memcpy operations */ p_vout->b_direct = 1; - intf_WarnMsg( 2, "vout info: mapping " + intf_WarnMsg( 2, "vout info: direct render, mapping " "render pictures 0-%i to system pictures 1-%i", VOUT_MAX_PICTURES - 2, VOUT_MAX_PICTURES - 1 ); @@ -351,7 +353,7 @@ static int InitThread( vout_thread_t *p_vout ) return( 1 ); } - intf_WarnMsg( 2, "vout info: mapping " + intf_WarnMsg( 2, "vout info: indirect render, mapping " "render pictures %i-%i to system pictures %i-%i", I_OUTPUTPICTURES - 1, VOUT_MAX_PICTURES - 2, I_OUTPUTPICTURES, VOUT_MAX_PICTURES - 1 ); diff --git a/src/video_output/vout_pictures.c b/src/video_output/vout_pictures.c index be6be660a0..0c73dca7a5 100644 --- a/src/video_output/vout_pictures.c +++ b/src/video_output/vout_pictures.c @@ -2,7 +2,7 @@ * vout_pictures.c : picture management functions ***************************************************************************** * Copyright (C) 2000 VideoLAN - * $Id: vout_pictures.c,v 1.8 2002/01/04 14:01:35 sam Exp $ + * $Id: vout_pictures.c,v 1.9 2002/01/05 02:22:03 sam Exp $ * * Authors: Vincent Seguin * Samuel Hocevar @@ -487,6 +487,7 @@ void vout_AllocatePicture( picture_t *p_pic, case FOURCC_Y211: p_pic->p->i_lines = i_height; p_pic->p->i_pitch = i_width; + p_pic->p->i_pixel_bytes = 4; p_pic->i_planes = 1; break; @@ -511,7 +512,8 @@ void vout_AllocatePicture( picture_t *p_pic, break; default: - intf_ErrMsg( "vout error: unknown chroma type %.8x", i_chroma ); + intf_ErrMsg( "vout error: unknown chroma type 0x%.8x (%4.4s)", + i_chroma, (char*)&i_chroma ); p_pic->i_planes = 0; return; }