annotate postproc/swscale.c @ 2218:d9ea650b2c24

yv12 scaling at 24/32bpp with -zoom
author arpi
date Mon, 15 Oct 2001 19:33:26 +0000
parents 9da2a0515184
children ad393ff770f4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2216
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
1
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
2 // Software scaling and colorspace conversion routines for MPlayer
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
3
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
4 // temporary storage for 4 yuv lines:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
5 static unsigned int pix_buf_y[4][2048];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
6 static unsigned int pix_buf_uv[2][2048*2];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
7
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
8 // clipping helper table for C implementations:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
9 static unsigned char clip_table[768];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
10
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
11 // yuv->rgb conversion tables:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
12 static int yuvtab_2568[256];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
13 static int yuvtab_3343[256];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
14 static int yuvtab_0c92[256];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
15 static int yuvtab_1a1e[256];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
16 static int yuvtab_40cf[256];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
17
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
18 // *** bilinear scaling and yuv->rgb conversion of yv12 slices:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
19 // *** Note: it's called multiple times while decoding a frame, first time y==0
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
20 // *** Designed to upscale, but may work for downscale too.
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
21 // s_xinc = (src_width << 8) / dst_width
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
22 // s_yinc = (src_height << 16) / dst_height
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
23 void SwScale_YV12slice_brg24(unsigned char* srcptr[],int stride[], int y, int h,
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
24 unsigned char* dstptr, int dststride, int dstw, int dstbpp,
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
25 unsigned int s_xinc,unsigned int s_yinc){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
26
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
27 // scaling factors:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
28 //static int s_yinc=(vo_dga_src_height<<16)/vo_dga_vp_height;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
29 //static int s_xinc=(vo_dga_src_width<<8)/vo_dga_vp_width;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
30
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
31 unsigned int s_xinc2=s_xinc>>1;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
32
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
33 static int s_srcypos;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
34 static int s_ypos;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
35 static int s_last_ypos;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
36
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
37 if(y==0){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
38 s_srcypos=-2*s_yinc;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
39 s_ypos=-2;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
40 s_last_ypos=-2;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
41 } // reset counters
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
42
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
43 while(1){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
44 unsigned char *dest=dstptr+dststride*s_ypos;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
45 int y0=2+(s_srcypos>>16);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
46 int y1=1+(s_srcypos>>17);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
47 int yalpha=(s_srcypos&0xFFFF)>>8;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
48 int yalpha1=yalpha^255;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
49 int uvalpha=((s_srcypos>>1)&0xFFFF)>>8;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
50 int uvalpha1=uvalpha^255;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
51 unsigned int *buf0=pix_buf_y[y0&3];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
52 unsigned int *buf1=pix_buf_y[((y0+1)&3)];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
53 unsigned int *uvbuf0=pix_buf_uv[y1&1];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
54 unsigned int *uvbuf1=pix_buf_uv[(y1&1)^1];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
55 int i;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
56
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
57 if(y0>=y+h) break;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
58
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
59 s_ypos++; s_srcypos+=s_yinc;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
60
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
61 if(s_last_ypos!=y0){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
62 unsigned char *src=srcptr[0]+(y0-y)*stride[0];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
63 unsigned int xpos=0;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
64 s_last_ypos=y0;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
65 // *** horizontal scale Y line to temp buffer
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
66 // this loop should be rewritten in MMX assembly!!!!
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
67 for(i=0;i<dstw;i++){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
68 register unsigned int xx=xpos>>8;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
69 register unsigned int xalpha=xpos&0xFF;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
70 buf1[i]=(src[xx]*(xalpha^255)+src[xx+1]*xalpha);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
71 xpos+=s_xinc;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
72 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
73 // *** horizontal scale U and V lines to temp buffer
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
74 if(!(y0&1)){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
75 unsigned char *src1=srcptr[1]+(y1-y/2)*stride[1];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
76 unsigned char *src2=srcptr[2]+(y1-y/2)*stride[2];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
77 xpos=0;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
78 // this loop should be rewritten in MMX assembly!!!!
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
79 for(i=0;i<dstw;i++){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
80 register unsigned int xx=xpos>>8;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
81 register unsigned int xalpha=xpos&0xFF;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
82 uvbuf1[i]=(src1[xx]*(xalpha^255)+src1[xx+1]*xalpha);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
83 uvbuf1[i+2048]=(src2[xx]*(xalpha^255)+src2[xx+1]*xalpha);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
84 xpos+=s_xinc2;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
85 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
86 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
87 if(!y0) continue;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
88 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
89
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
90 // this loop should be rewritten in MMX assembly!!!!
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
91 // Note1: this code can be resticted to n*8 (or n*16) width lines to simplify optimization...
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
92 // Note2: instead of using lookup tabs, mmx version could do the multiply...
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
93 // Note3: maybe we should make separated 15/16, 24 and 32bpp version of this:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
94 for(i=0;i<dstw;i++){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
95 // vertical linear interpolation && yuv2rgb in a single step:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
96 int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>16)];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
97 int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>16);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
98 int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>16);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
99 dest[0]=clip_table[((Y + yuvtab_3343[U]) >>13)];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
100 dest[1]=clip_table[((Y + yuvtab_0c92[V] + yuvtab_1a1e[U]) >>13)];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
101 dest[2]=clip_table[((Y + yuvtab_40cf[V]) >>13)];
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
102 dest+=dstbpp;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
103 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
104
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
105 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
106
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
107 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
108
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
109
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
110 void SwScale_Init(){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
111 // generating tables:
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
112 int i;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
113 for(i=0;i<256;i++){
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
114 clip_table[i]=0;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
115 clip_table[i+256]=i;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
116 clip_table[i+512]=255;
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
117 yuvtab_2568[i]=(0x2568*(i-16))+(256<<13);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
118 yuvtab_3343[i]=0x3343*(i-128);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
119 yuvtab_0c92[i]=-0x0c92*(i-128);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
120 yuvtab_1a1e[i]=-0x1a1e*(i-128);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
121 yuvtab_40cf[i]=0x40cf*(i-128);
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
122 }
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
123
9da2a0515184 software yv12->rgb scaler - separated from fsdga
arpi
parents:
diff changeset
124 }