Mercurial > mplayer.hg
diff libvo/vo_dga.c @ 680:fbd9327b899b
- now features 24->32 conversion (this is actually faster than letting the
codec produce depth 32 in the first place for avis :-))) )
author | acki2 |
---|---|
date | Tue, 01 May 2001 22:37:37 +0000 |
parents | ee2dac2cc633 |
children | 2094b195a9bc |
line wrap: on
line diff
--- a/libvo/vo_dga.c Tue May 01 22:28:01 2001 +0000 +++ b/libvo/vo_dga.c Tue May 01 22:37:37 2001 +0000 @@ -23,6 +23,10 @@ * - works only on x86 architectures * * $Log$ + * Revision 1.19 2001/05/01 22:37:37 acki2 + * - now features 24->32 conversion (this is actually faster than letting the + * codec produce depth 32 in the first place for avis :-))) ) + * * Revision 1.18 2001/05/01 20:24:31 acki2 * - now mpeg is fast again (no more offscreen buffer rubbish) But is it really ok? * @@ -125,11 +129,11 @@ //------------------------------------------------------------------ -#define BITSPP (vo_dga_modes[vo_dga_active_mode].vdm_bitspp) -#define BYTESPP (vo_dga_modes[vo_dga_active_mode].vdm_bytespp) +//#define BITSPP (vo_dga_modes[vo_dga_active_mode].vdm_bitspp) +//#define BYTESPP (vo_dga_modes[vo_dga_active_mode].vdm_bytespp) -#define HW_MODE (vo_dga_modes[vo_dga_active_mode]) - +#define HW_MODE (vo_dga_modes[vo_dga_hw_mode]) +#define SRC_MODE (vo_dga_modes[vo_dga_src_mode]) struct vd_modes { int vdm_mplayer_depth; @@ -140,21 +144,32 @@ int vdm_rmask; int vdm_gmask; int vdm_bmask; + int vdm_hw_mode; + int vdm_conversion_func; }; //------------------------------------------------------------------ -static struct vd_modes vo_dga_modes[] = { +#define VDM_CONV_NATIVE 0 +#define VDM_CONV_15TO16 1 +#define VDM_CONV_24TO32 2 - { 0, 0, 0, 0, 0, 0, 0, 0}, - { 15, 0, 15, 16, 2, 0x7c00, 0x03e0, 0x001f }, - { 16, 0, 16, 16, 2, 0xf800, 0x07e0, 0x001f }, - { 24, 0, 24, 24, 3, 0xff0000, 0x00ff00, 0x0000ff}, - { 32, 0, 24, 32, 4, 0x00ff0000, 0x0000ff00, 0x000000ff} +static struct vd_modes vo_dga_modes[] = { + // these entries describe HW modes + // however, we use the same entries to tell mplayer what we support + // so the last two values describe, which HW mode to use and which conversion + // function to use for a mode that is not supported by HW + + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 15, 0, 15, 16, 2, 0x7c00, 0x03e0, 0x001f, 2, VDM_CONV_15TO16 }, + { 16, 0, 16, 16, 2, 0xf800, 0x07e0, 0x001f, 2, VDM_CONV_NATIVE }, + { 24, 0, 24, 24, 3, 0xff0000, 0x00ff00, 0x0000ff, 4, VDM_CONV_24TO32}, + { 32, 0, 24, 32, 4, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, VDM_CONV_NATIVE} }; static int vo_dga_mode_num = sizeof(vo_dga_modes)/sizeof(struct vd_modes); +// enable a HW mode (by description) int vd_EnableMode( int depth, int bitspp, int rmask, int gmask, int bmask){ int i; @@ -165,6 +180,8 @@ vo_dga_modes[i].vdm_gmask == gmask && vo_dga_modes[i].vdm_bmask == bmask){ vo_dga_modes[i].vdm_supported = 1; + vo_dga_modes[i].vdm_hw_mode = i; + vo_dga_modes[i].vdm_conversion_func = VDM_CONV_NATIVE; return i; } } @@ -183,18 +200,22 @@ } +// enable a HW mode (mplayer_depth decides which) int vd_ValidateMode( int mplayer_depth){ int i; if(mplayer_depth == 0)return 0; for(i=1; i<vo_dga_mode_num; i++){ if(vo_dga_modes[i].vdm_mplayer_depth == mplayer_depth ){ vo_dga_modes[i].vdm_supported = 1; + vo_dga_modes[i].vdm_hw_mode = i; + vo_dga_modes[i].vdm_conversion_func = VDM_CONV_NATIVE; return i; } } return 0; } +// do we support this mode? (not important whether native or conversion) int vd_ModeValid( int mplayer_depth){ int i; if(mplayer_depth == 0)return 0; @@ -213,12 +234,16 @@ static char stringbuf[VO_DGA_MAX_STRING_LEN]; stringbuf[VO_DGA_MAX_STRING_LEN-1]=0; snprintf(stringbuf, VO_DGA_MAX_STRING_LEN-2, - "depth=%d, bpp=%d, r=%06x, g=%06x, b=%06x (-bpp %d)", + "depth=%d, bpp=%d, r=%06x, g=%06x, b=%06x, %s (-bpp %d)", vo_dga_modes[index].vdm_depth, vo_dga_modes[index].vdm_bitspp, vo_dga_modes[index].vdm_rmask, vo_dga_modes[index].vdm_gmask, vo_dga_modes[index].vdm_bmask, + vo_dga_modes[index].vdm_supported ? + (vo_dga_modes[index].vdm_conversion_func == VDM_CONV_NATIVE ? + "native (fast), " : "conversion (slow),") : + "not supported :-( ", vo_dga_modes[index].vdm_mplayer_depth); return stringbuf; } @@ -249,8 +274,10 @@ // (not supported yet) in src static int vo_dga_vp_skip; // dto. for dest static int vo_dga_lines; // num of lines to copy -static int vo_dga_active_mode = 0; // index in mode list that is used - // for movie +static int vo_dga_hw_mode = 0; // index in mode list that is actually + // used by framebuffer +static int vo_dga_src_mode = 0; // index in mode list that is used by + // codec static int vo_dga_XServer_mode = 0;// index in mode list for resolution // XServer is running @@ -354,8 +381,31 @@ s = *src; d = (&((char *)vo_dga_base)[vo_dga_vp_offset + vo_dga_dbf_current * vo_dga_dbf_mem_offset]); - rep_movsl(d, s, lpl, vo_dga_vp_skip, numlines ); - + + switch(SRC_MODE.vdm_conversion_func){ + case VDM_CONV_NATIVE: + rep_movsl(d, s, lpl, vo_dga_vp_skip, numlines ); + break; + case VDM_CONV_15TO16: + printf("vo_dga: 15 to 16 not implemented yet!!!\n"); + break; + case VDM_CONV_24TO32: + { + int i,k,l,m; + for(i = 0; i< vo_dga_lines; i++ ){ + for(k = 0; k< vo_dga_src_width; k+=2 ){ + l = *(((uint32_t *)s)++); + m = (l & 0xff000000)>> 24 ; + *(((uint32_t *)d)++) = l & 0x00ffffff; + m |= *(((uint16_t *)s)++) << 8; + *(((uint32_t *)d)++) = m; + } + d+= vp_skip; + } + } + //printf("vo_dga: 24 to 32 not implemented yet!!!\n"); + break; + } return 0; } @@ -396,9 +446,9 @@ { yuv2rgb( vo_dga_base + vo_dga_dbf_current * vo_dga_dbf_mem_offset + vo_dga_vp_offset + - (vo_dga_width * y +x) * BYTESPP, + (vo_dga_width * y +x) * HW_MODE.vdm_bytespp, src[0], src[1], src[2], - w,h, vo_dga_width * BYTESPP, + w,h, vo_dga_width * HW_MODE.vdm_bytespp, stride[0],stride[1] ); return 0; }; @@ -438,18 +488,18 @@ if( !vo_init() ){ vd_printf(VD_ERR, "vo_dga: vo_init() failed!\n"); return 1; - } - vo_dga_XServer_mode = vd_ValidateMode(vo_depthonscreen); + } + vo_dga_XServer_mode = vd_ValidateMode(vo_depthonscreen); if(vo_dga_XServer_mode ==0){ #ifndef HAVE_DGA2 vd_printf(VD_ERR, "vo_dga: Your X-Server is not running in a "); vd_printf(VD_ERR, "resolution supported by DGA driver!\n"); #endif - }else{ - vd_printf(VD_INFO, "vo_dga: X running at: %s\n", - vd_GetModeString(vo_dga_XServer_mode)); - } + }//else{ + // vd_printf(VD_INFO, "vo_dga: X running at: %s\n", + // vd_GetModeString(vo_dga_XServer_mode)); + //} #ifdef HAVE_DGA2 modelines=XDGAQueryModes(qdisp, XDefaultScreen(qdisp),&modecount); @@ -472,24 +522,31 @@ modelines[i].blueMask); } XFree(modelines); - dga_depths_init = 1; + } #endif - + dga_depths_init = 1; XCloseDisplay(qdisp); - for(i=0; i<vo_dga_mode_num; i++){ - if(vo_dga_modes[i].vdm_supported != 0){ - vd_printf(VD_INFO, "vo_dga: Supporting mode: %s", vd_GetModeString(i)); - if(vo_dbpp && vo_dbpp != vo_dga_modes[i].vdm_mplayer_depth){ - vo_dga_modes[i].vdm_supported = 0; - vd_printf(VD_INFO, " ...disabled by -bpp %d", vo_dbpp ); - } - vd_printf(VD_INFO, "\n"); + if( !vo_dga_modes[1].vdm_supported && vo_dga_modes[2].vdm_supported ){ + vo_dga_modes[1].vdm_supported = 1; + } + + if( !vo_dga_modes[3].vdm_supported && vo_dga_modes[4].vdm_supported ){ + vo_dga_modes[3].vdm_supported = 1; + } + + for(i=1; i<vo_dga_mode_num; i++){ + vd_printf(VD_INFO, "vo_dga: Mode: %s", vd_GetModeString(i)); + if(vo_dbpp && vo_dbpp != vo_dga_modes[i].vdm_mplayer_depth){ + vo_dga_modes[i].vdm_supported = 0; + vd_printf(VD_INFO, " ...disabled by -bpp %d", vo_dbpp ); } + vd_printf(VD_INFO, "\n"); } } + // TODO: respect bit for native/not native if( format==IMGFMT_YV12 ) return 7; if( (format&IMGFMT_BGR_MASK) == IMGFMT_BGR && @@ -649,15 +706,24 @@ if( !vo_dbpp ){ if (format == IMGFMT_YV12){ - vo_dga_active_mode = vo_dga_XServer_mode; + vo_dga_src_mode = vo_dga_XServer_mode; }else if((format & IMGFMT_BGR_MASK) == IMGFMT_BGR){ - vo_dga_active_mode = vd_ModeValid( format & 0xff ); + vo_dga_src_mode = vd_ModeValid( format & 0xff ); } }else{ - vo_dga_active_mode = vd_ModeValid(vo_dbpp); + vo_dga_src_mode = vd_ModeValid(vo_dbpp); + } + vo_dga_hw_mode = SRC_MODE.vdm_hw_mode; + + if( format == IMGFMT_YV12 && vo_dga_src_mode != vo_dga_hw_mode ){ + vd_printf(VD_ERR, + "vo_dga: YV12 supports native modes only. Using %d instead of selected %d.\n", + HW_MODE.vdm_mplayer_depth, + SRC_MODE.vdm_mplayer_depth ); + vo_dga_src_mode = vo_dga_hw_mode; } - if(!vo_dga_active_mode){ + if(!vo_dga_src_mode){ vd_printf(VD_ERR, "vo_dga: unsupported video format!\n"); return 1; } @@ -690,7 +756,7 @@ modelines[i].redMask, modelines[i].greenMask, modelines[i].blueMask, - vo_dga_active_mode)){ + vo_dga_hw_mode)){ vd_printf(VD_DBG, "maxy: %4d, depth: %2d, %4dx%4d, ", modelines[i].maxViewportY, modelines[i].depth, @@ -703,15 +769,18 @@ } } vd_printf(VD_INFO, - "vo_dga: Selected video mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d, video %3d x %3d.\n", + "vo_dga: Selected hardware mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d.\n", mX, mY, mVBI, - vo_dga_modes[vo_dga_active_mode].vdm_depth, - vo_dga_modes[vo_dga_active_mode].vdm_bitspp, - width, height); - + HW_MODE.vdm_depth, + HW_MODE.vdm_bitspp); + vd_printf(VD_INFO, + "vo_dga: Video parameters by codec: %3d x %3d, depth %2d, bitspp %2d.\n", + width, height, + SRC_MODE.vdm_depth, + SRC_MODE.vdm_bitspp); vo_dga_vp_width =mX; vo_dga_vp_height = mY; - vo_dga_width = modelines[j].bytesPerScanline / BYTESPP ; + vo_dga_width = modelines[j].bytesPerScanline / HW_MODE.vdm_bytespp ; dga_modenum = modelines[j].num; max_vpy_pos = modelines[j].maxViewportY; @@ -743,7 +812,7 @@ if(vo_dga_vidmodes != NULL ){ for (i=0; i<modecount; i++){ if ( check_res(i, wanted_width, wanted_height, - vo_dga_modes[vo_dga_active_mode].vdm_depth, + vo_dga_modes[vo_dga_hw_mode].vdm_depth, vo_dga_vidmodes[i]->hdisplay, vo_dga_vidmodes[i]->vdisplay, GET_VREFRESH(vo_dga_vidmodes[i]->dotclock, @@ -755,8 +824,8 @@ vd_printf(VD_INFO, "vo_dga: Selected video mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d, video %3d x %3d.\n", mX, mY, mVBI, - vo_dga_modes[vo_dga_active_mode].vdm_depth, - vo_dga_modes[vo_dga_active_mode].vdm_bitspp, + vo_dga_modes[vo_dga_hw_mode].vdm_depth, + vo_dga_modes[vo_dga_hw_mode].vdm_bitspp, width, height); }else{ vd_printf(VD_INFO, "vo_dga: XF86VidMode returned no screens - using current resolution.\n"); @@ -838,26 +907,26 @@ // do some more checkings here ... if( format==IMGFMT_YV12 ){ - yuv2rgb_init( vo_dga_modes[vo_dga_active_mode].vdm_mplayer_depth , MODE_RGB ); + yuv2rgb_init( vo_dga_modes[vo_dga_hw_mode].vdm_mplayer_depth , MODE_RGB ); vd_printf( VD_DBG, "vo_dga: Using mplayer depth %d for YV12\n", - vo_dga_modes[vo_dga_active_mode].vdm_mplayer_depth); + vo_dga_modes[vo_dga_hw_mode].vdm_mplayer_depth); } vd_printf(VD_DBG, "vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %08x, bpp: %d\n", vo_dga_width, vo_dga_vp_width, - vo_dga_vp_height, BYTESPP, vo_dga_base, - BITSPP); + vo_dga_vp_height, HW_MODE.vdm_bytespp, vo_dga_base, + HW_MODE.vdm_bitspp); x_off = (vo_dga_vp_width - vo_dga_src_width)>>1; y_off = (vo_dga_vp_height - vo_dga_src_height)>>1; - vo_dga_bytes_per_line = vo_dga_src_width * BYTESPP; + vo_dga_bytes_per_line = vo_dga_src_width * HW_MODE.vdm_bytespp; vo_dga_lines = vo_dga_src_height; vo_dga_src_offset = 0; - vo_dga_vp_offset = (y_off * vo_dga_width + x_off ) * BYTESPP; + vo_dga_vp_offset = (y_off * vo_dga_width + x_off ) * HW_MODE.vdm_bytespp; - vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * BYTESPP; // todo + vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * HW_MODE.vdm_bytespp; // todo vd_printf(VD_DBG, "vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n", vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line); @@ -874,7 +943,7 @@ // note: set vo_dga_dbf_mem_offset to NULL to disable doublebuffering vo_dga_dbf_y_offset = y_off + vo_dga_src_height; - vo_dga_dbf_mem_offset = vo_dga_width * BYTESPP * vo_dga_dbf_y_offset; + vo_dga_dbf_mem_offset = vo_dga_width * HW_MODE.vdm_bytespp * vo_dga_dbf_y_offset; vo_dga_dbf_current = 0; // if(format ==IMGFMT_YV12 ) @@ -893,13 +962,13 @@ int size = vo_dga_width * (vo_dga_vp_height + (vo_dga_dbf_mem_offset != 0 ? (vo_dga_src_height+y_off) : 0)) * - BYTESPP; + HW_MODE.vdm_bytespp; #ifndef HAVE_DGA2 vd_printf(VD_DBG, "vo_dga: wanted size=%d, fb-size=%d\n", size, ram); if(size>ram*1024){ vo_dga_dbf_mem_offset = 0; vd_printf(VD_INFO, "vo_dga: Not enough memory for double buffering!\n"); - size -= (vo_dga_src_height+y_off) * vo_dga_width * BYTESPP; + size -= (vo_dga_src_height+y_off) * vo_dga_width * HW_MODE.vdm_bytespp; } #endif