summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-10-28 18:30:59 +0000
committermichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-10-28 18:30:59 +0000
commita4ef78e9a19ef29c6f4446c7bbed103ea3e66681 (patch)
tree27e2ff89af5543be0a52e8ed53d46b2af5153454
parent07dcf8875b05bbc333820a7af32a17c723bcc258 (diff)
downloadmpv-a4ef78e9a19ef29c6f4446c7bbed103ea3e66681.tar.bz2
mpv-a4ef78e9a19ef29c6f4446c7bbed103ea3e66681.tar.xz
yv12 to yv12 scaler
someone who knows a bit about vo_odivx could add support for it ... git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2520 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--libvo/vo_vesa.c7
-rw-r--r--libvo/vo_x11.c5
-rw-r--r--postproc/swscale.c61
-rw-r--r--postproc/swscale.h9
-rw-r--r--postproc/swscale_template.c61
5 files changed, 92 insertions, 51 deletions
diff --git a/libvo/vo_vesa.c b/libvo/vo_vesa.c
index be0ba00c91..2a3f0366d5 100644
--- a/libvo/vo_vesa.c
+++ b/libvo/vo_vesa.c
@@ -1,4 +1,4 @@
-/*
+/*
* video_out_vesa.c
*
* Copyright (C) Nick Kurshev <nickols_k@mail.ru> - Oct 2001
@@ -246,8 +246,9 @@ static uint32_t draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int
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);
diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c
index 8a860b3ba8..aeb61d0fca 100644
--- a/libvo/vo_x11.c
+++ b/libvo/vo_x11.c
@@ -484,8 +484,9 @@ static uint32_t draw_slice( uint8_t *src[],int stride[],int w,int h,int x,int y
{
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 );
diff --git a/postproc/swscale.c b/postproc/swscale.c
index e475f43b55..476367d60b 100644
--- a/postproc/swscale.c
+++ b/postproc/swscale.c
@@ -440,6 +440,31 @@ static int canMMX2BeUsed=0;
" 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 @@ FUNNYUVCODE
}
-// *** 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 @@ canMMX2BeUsed= (s_xinc <= 0x10000 && (dstw&31)==0 && (srcWidth&15)==0) ? 1 : 0;
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 @@ else s_xinc2= s_xinc;
} // 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 @@ else s_xinc2= s_xinc;
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 @@ else s_xinc2= s_xinc;
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);
diff --git a/postproc/swscale.h b/postproc/swscale.h
index d770e02419..de71bfc5b6 100644
--- a/postproc/swscale.h
+++ b/postproc/swscale.h
@@ -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();
diff --git a/postproc/swscale_template.c b/postproc/swscale_template.c
index e475f43b55..476367d60b 100644
--- a/postproc/swscale_template.c
+++ b/postproc/swscale_template.c
@@ -440,6 +440,31 @@ static int canMMX2BeUsed=0;
" 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 @@ FUNNYUVCODE
}
-// *** 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 @@ canMMX2BeUsed= (s_xinc <= 0x10000 && (dstw&31)==0 && (srcWidth&15)==0) ? 1 : 0;
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 @@ else s_xinc2= s_xinc;
} // 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 @@ else s_xinc2= s_xinc;
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 @@ else s_xinc2= s_xinc;
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);