Mercurial > mplayer.hg
changeset 2519:6f3fa9bc3b27
yv12 to yv12 scaler
someone who knows a bit about vo_odivx could add support for it ...
author | michael |
---|---|
date | Sun, 28 Oct 2001 18:30:59 +0000 |
parents | a3f658d3c98c |
children | b58c43aab619 |
files | libvo/vo_vesa.c libvo/vo_x11.c postproc/swscale.c postproc/swscale.h postproc/swscale_template.c |
diffstat | 5 files changed, 92 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/libvo/vo_vesa.c Sun Oct 28 18:08:56 2001 +0000 +++ b/libvo/vo_vesa.c Sun Oct 28 18:30:59 2001 +0000 @@ -1,4 +1,4 @@ -/* +/* * video_out_vesa.c * * Copyright (C) Nick Kurshev <nickols_k@mail.ru> - Oct 2001 @@ -246,8 +246,9 @@ printf("vo_vesa: draw_slice was called: w=%u h=%u x=%u y=%u\n",w,h,x,y); if(vesa_zoom) { - SwScale_YV12slice_brg24(image,stride,y,h, - yuv_buffer, + uint8_t *dst[3]= {yuv_buffer, NULL, NULL}; + SwScale_YV12slice(image,stride,y,h, + dst, image_width*((video_mode_info.BitsPerPixel+7)/8), image_width, video_mode_info.BitsPerPixel, scale_xinc, scale_yinc);
--- a/libvo/vo_x11.c Sun Oct 28 18:08:56 2001 +0000 +++ b/libvo/vo_x11.c Sun Oct 28 18:30:59 2001 +0000 @@ -484,8 +484,9 @@ { if(scale_xinc){ - SwScale_YV12slice_brg24(src,stride,y,h, - ImageData, image_width*((bpp+7)/8), image_width, ( depth == 24 ) ? bpp : depth, + uint8_t *dst[3] = {ImageData, NULL, NULL}; + SwScale_YV12slice(src,stride,y,h, + dst, image_width*((bpp+7)/8), image_width, ( depth == 24 ) ? bpp : depth, scale_xinc, scale_yinc); } else { uint8_t *dst=ImageData + ( image_width * y + x ) * ( bpp/8 );
--- a/postproc/swscale.c Sun Oct 28 18:08:56 2001 +0000 +++ b/postproc/swscale.c Sun Oct 28 18:30:59 2001 +0000 @@ -440,6 +440,31 @@ " jb 1b \n\t" +static inline void yuv2yuv(uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1, + uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstw, int yalpha, int uvalpha) +{ + int yalpha1=yalpha^4095; + int uvalpha1=uvalpha^4095; + int i; + + for(i=0;i<dstw;i++) + { + ((uint8_t*)dest)[0] = (buf0[i]*yalpha1+buf1[i]*yalpha)>>19; + dest++; + } + + if(uvalpha != -1) + { + for(i=0; i<dstw/2; i++) + { + ((uint8_t*)uDest)[0] = (uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19; + ((uint8_t*)vDest)[0] = (uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19; + uDest++; + vDest++; + } + } +} + /** * vertical scale YV12 to RGB */ @@ -1126,13 +1151,13 @@ } -// *** bilinear scaling and yuv->rgb conversion of yv12 slices: +// *** bilinear scaling and yuv->rgb or yuv->yuv conversion of yv12 slices: // *** Note: it's called multiple times while decoding a frame, first time y==0 // *** Designed to upscale, but may work for downscale too. // s_xinc = (src_width << 16) / dst_width // s_yinc = (src_height << 16) / dst_height -void SwScale_YV12slice_brg24(unsigned char* srcptr[],int stride[], int y, int h, - unsigned char* dstptr, int dststride, int dstw, int dstbpp, +void SwScale_YV12slice(unsigned char* srcptr[],int stride[], int y, int h, + uint8_t* dstptr[], int dststride, int dstw, int dstbpp, unsigned int s_xinc,unsigned int s_yinc){ // scaling factors: @@ -1172,8 +1197,8 @@ if(canMMX2BeUsed) s_xinc+= 20; else s_xinc = ((srcWidth-2)<<16)/(dstw-2) - 20; -if(fullUVIpol) s_xinc2= s_xinc>>1; -else s_xinc2= s_xinc; +if(fullUVIpol && !dstbpp==12) s_xinc2= s_xinc>>1; +else s_xinc2= s_xinc; // force calculation of the horizontal interpolation of the first line if(y==0){ @@ -1318,10 +1343,14 @@ } // reset counters while(1){ - unsigned char *dest=dstptr+dststride*s_ypos; + unsigned char *dest =dstptr[0]+dststride*s_ypos; + unsigned char *uDest=dstptr[1]+(dststride>>1)*(s_ypos>>1); + unsigned char *vDest=dstptr[2]+(dststride>>1)*(s_ypos>>1); + int y0=(s_srcypos + 0xFFFF)>>16; // first luminance source line number below the dst line // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src) - int srcuvpos= s_srcypos + s_yinc/2 - 0x8000; + int srcuvpos= dstbpp==12 ? s_srcypos + s_yinc/2 - 0x8000 : + s_srcypos - 0x8000; int y1=(srcuvpos + 0x1FFFF)>>17; // first chrominance source line number below the dst line int yalpha=((s_srcypos-1)&0xFFFF)>>4; int uvalpha=((srcuvpos-1)&0x1FFFF)>>5; @@ -1333,18 +1362,7 @@ if(y0>=y+h) break; // FIXME wrong, skips last lines, but they are dupliactes anyway - // if this is after the last line than use only the last src line - /* if(y0>=y+h) - { - buf1= buf0; - s_last_ypos=y0; - } - if(y1>=(y+h)/2) - { - uvbuf1= uvbuf0; - s_last_y1pos=y1; - } -*/ + if((y0&1) && dstbpp==12) uvalpha=-1; // there is no alpha if there is no line s_ypos++; s_srcypos+=s_yinc; @@ -1404,8 +1422,9 @@ s_last_y1pos= MIN(y1, y/2+h/2-1); } - - if(ABS(s_yinc - 0x10000) < 10) + if(dstbpp==12) //YV12 + yuv2yuv(buf0, buf1, uvbuf0, uvbuf1, dest, uDest, vDest, dstw, yalpha, uvalpha); + else if(ABS(s_yinc - 0x10000) < 10) yuv2rgb1(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp); else yuv2rgbX(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp);
--- a/postproc/swscale.h Sun Oct 28 18:08:56 2001 +0000 +++ b/postproc/swscale.h Sun Oct 28 18:30:59 2001 +0000 @@ -1,12 +1,13 @@ -// *** bilinear scaling and yuv->rgb conversion of yv12 slices: +// *** bilinear scaling and yuv->rgb & yuv->yuv conversion of yv12 slices: // *** Note: it's called multiple times while decoding a frame, first time y==0 // *** Designed to upscale, but may work for downscale too. // s_xinc = (src_width << 8) / dst_width // s_yinc = (src_height << 16) / dst_height -void SwScale_YV12slice_brg24(unsigned char* srcptr[],int stride[], int y, int h, - unsigned char* dstptr, int dststride, int dstw, int dstbpp, - unsigned int s_xinc,unsigned int s_yinc); +// dstbpp == 12 -> yv12 output +void SwScale_YV12slice(unsigned char* srcptr[],int stride[], int y, int h, + uint8_t* dstptr[], int dststride, int dstw, int dstbpp, + unsigned int s_xinc,unsigned int s_yinc); // generating tables void SwScale_Init();
--- a/postproc/swscale_template.c Sun Oct 28 18:08:56 2001 +0000 +++ b/postproc/swscale_template.c Sun Oct 28 18:30:59 2001 +0000 @@ -440,6 +440,31 @@ " jb 1b \n\t" +static inline void yuv2yuv(uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1, + uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstw, int yalpha, int uvalpha) +{ + int yalpha1=yalpha^4095; + int uvalpha1=uvalpha^4095; + int i; + + for(i=0;i<dstw;i++) + { + ((uint8_t*)dest)[0] = (buf0[i]*yalpha1+buf1[i]*yalpha)>>19; + dest++; + } + + if(uvalpha != -1) + { + for(i=0; i<dstw/2; i++) + { + ((uint8_t*)uDest)[0] = (uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19; + ((uint8_t*)vDest)[0] = (uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19; + uDest++; + vDest++; + } + } +} + /** * vertical scale YV12 to RGB */ @@ -1126,13 +1151,13 @@ } -// *** bilinear scaling and yuv->rgb conversion of yv12 slices: +// *** bilinear scaling and yuv->rgb or yuv->yuv conversion of yv12 slices: // *** Note: it's called multiple times while decoding a frame, first time y==0 // *** Designed to upscale, but may work for downscale too. // s_xinc = (src_width << 16) / dst_width // s_yinc = (src_height << 16) / dst_height -void SwScale_YV12slice_brg24(unsigned char* srcptr[],int stride[], int y, int h, - unsigned char* dstptr, int dststride, int dstw, int dstbpp, +void SwScale_YV12slice(unsigned char* srcptr[],int stride[], int y, int h, + uint8_t* dstptr[], int dststride, int dstw, int dstbpp, unsigned int s_xinc,unsigned int s_yinc){ // scaling factors: @@ -1172,8 +1197,8 @@ if(canMMX2BeUsed) s_xinc+= 20; else s_xinc = ((srcWidth-2)<<16)/(dstw-2) - 20; -if(fullUVIpol) s_xinc2= s_xinc>>1; -else s_xinc2= s_xinc; +if(fullUVIpol && !dstbpp==12) s_xinc2= s_xinc>>1; +else s_xinc2= s_xinc; // force calculation of the horizontal interpolation of the first line if(y==0){ @@ -1318,10 +1343,14 @@ } // reset counters while(1){ - unsigned char *dest=dstptr+dststride*s_ypos; + unsigned char *dest =dstptr[0]+dststride*s_ypos; + unsigned char *uDest=dstptr[1]+(dststride>>1)*(s_ypos>>1); + unsigned char *vDest=dstptr[2]+(dststride>>1)*(s_ypos>>1); + int y0=(s_srcypos + 0xFFFF)>>16; // first luminance source line number below the dst line // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src) - int srcuvpos= s_srcypos + s_yinc/2 - 0x8000; + int srcuvpos= dstbpp==12 ? s_srcypos + s_yinc/2 - 0x8000 : + s_srcypos - 0x8000; int y1=(srcuvpos + 0x1FFFF)>>17; // first chrominance source line number below the dst line int yalpha=((s_srcypos-1)&0xFFFF)>>4; int uvalpha=((srcuvpos-1)&0x1FFFF)>>5; @@ -1333,18 +1362,7 @@ if(y0>=y+h) break; // FIXME wrong, skips last lines, but they are dupliactes anyway - // if this is after the last line than use only the last src line - /* if(y0>=y+h) - { - buf1= buf0; - s_last_ypos=y0; - } - if(y1>=(y+h)/2) - { - uvbuf1= uvbuf0; - s_last_y1pos=y1; - } -*/ + if((y0&1) && dstbpp==12) uvalpha=-1; // there is no alpha if there is no line s_ypos++; s_srcypos+=s_yinc; @@ -1404,8 +1422,9 @@ s_last_y1pos= MIN(y1, y/2+h/2-1); } - - if(ABS(s_yinc - 0x10000) < 10) + if(dstbpp==12) //YV12 + yuv2yuv(buf0, buf1, uvbuf0, uvbuf1, dest, uDest, vDest, dstw, yalpha, uvalpha); + else if(ABS(s_yinc - 0x10000) < 10) yuv2rgb1(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp); else yuv2rgbX(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp);