1 #include <strings.h> 2 #include <stdio.h> 3 #include "gfx_conv_c.h" 4 5 #define OPTIMIZED 1 6 7 void gfx_conv_null_c(AVFrame *in, AVFrame *out, int width, int height) 8 { 9 printf("[%d, %d, %d] -> [%d, %d, %d]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]); 10 memcpy(out->data[0], in->data[0], height * in->linesize[0]); 11 } 12 13 14 #if !OPTIMIZED 15 // this one is for SVQ1 :^) 16 // july 2002, mmu_man 17 void gfx_conv_yuv410p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height) 18 { 19 int i, j; 20 unsigned char *po, *pi, *pi2, *pi3; 21 // printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]); 22 // memcpy(out->data[0], in->data[0], height * in->linesize[0]); 23 po = out->data[0]; 24 pi = in->data[0]; 25 pi2 = in->data[1]; 26 pi3 = in->data[2]; 27 for(i=0; i<height; i++) { 28 for(j=0;j<out->linesize[0];j++) 29 // *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24)); 30 *(((long *)po)+j) = (long)(*(pi+2*j) + (*(pi2+(j >> 1)) << 8) + (*(pi+2*j+1) << 16) + (*(pi3+j) << 24)); 31 po += out->linesize[0]; 32 pi += in->linesize[0]; 33 if(i%4 == 1) 34 pi2 += in->linesize[1]; 35 else if (i%4 == 3) 36 pi3 += in->linesize[2]; 37 } 38 } 39 40 #else 41 42 void gfx_conv_yuv410p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height) 43 { 44 int i; 45 // bool toggle=false; 46 unsigned long *po, *po_eol; 47 register unsigned long *p; 48 unsigned long *pi; 49 unsigned short *pi2, *pi3; 50 register unsigned long y1, y2; 51 register unsigned short u, v; 52 register unsigned long a, b, c, d; 53 // printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]); 54 // memcpy(out->data[0], in->data[0], height * in->linesize[0]); 55 po = (unsigned long *)out->data[0]; 56 pi = (unsigned long *)in->data[0]; 57 pi2 = (unsigned short *)in->data[1]; 58 pi3 = (unsigned short *)in->data[2]; 59 for(i=0; i<height; i++) { 60 for(p=po, po_eol = (unsigned long *)(((char *)po)+out->linesize[0]); p<po_eol;) { 61 // *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24)); 62 y1 = *pi++; 63 y2 = *pi++; 64 u = *pi2; 65 v = *pi3; 66 a = (long)(y1 & 0x0FF | ((u& 0x0FF) << 8) | ((y1 & 0x0FF00) << 8) | ((v & 0x0FF) << 24)); 67 b = (long)(((y1 & 0x0FF0000) >> 16) | ((u& 0x0FF) << 8) | ((y1 & 0x0FF000000) >> 8) | ((v & 0x0FF) << 24)); 68 c = (long)(y2 & 0x0FF | ((u& 0x0FF00)) | ((y2 & 0x0FF00) << 8) | ((v & 0x0FF00) << 16)); 69 d = (long)(((y2 & 0x0FF0000) >> 16) | ((u& 0x0FF00)) | ((y2 & 0x0FF000000) >> 8) | ((v & 0x0FF00) << 16)); 70 // if (toggle) { 71 pi2++; 72 // } else { 73 pi3++; 74 // } 75 // toggle = !toggle; 76 77 *(p++) = a; 78 *(p++) = b; 79 *(p++) = c; 80 *(p++) = d; 81 } 82 po = (unsigned long *)((char *)po + out->linesize[0]); 83 pi = (unsigned long *)(in->data[0] + i * in->linesize[0]); 84 pi2 = (unsigned short *)(in->data[1] + ((i+2)/4) * in->linesize[1]); 85 pi3 = (unsigned short *)(in->data[2] + ((i+3)/4) * in->linesize[2]); 86 } 87 } 88 #endif // OPTIMIZED 89 90 // this one is for cyuv 91 // may 2003, mmu_man 92 // XXX: FIXME (== yuv410p atm) 93 void gfx_conv_yuv411p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height) 94 { 95 gfx_conv_yuv410p_ycbcr422_c(in, out, width, height); 96 } 97 98 99 /* 100 * DOES CRASH 101 void gfx_conv_yuv420p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height) 102 { 103 int i, j; 104 unsigned char *po, *pi, *pi2, *pi3; 105 // printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]); 106 // memcpy(out->data[0], in->data[0], height * in->linesize[0]); 107 po = out->data[0]; 108 pi = in->data[0]; 109 pi2 = in->data[1]; 110 pi3 = in->data[2]; 111 for(i=0; i<height; i++) { 112 for(j=0;j<out->linesize[0];j++) 113 // *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24)); 114 *(((long *)po)+j) = (long)(*(pi+2*j) + (*(pi2+j) << 8) + (*(pi+2*j+1) << 16) + (*(pi3+j) << 24)); 115 po += out->linesize[0]; 116 pi += in->linesize[0]; 117 if(i%2) 118 pi2 += in->linesize[1]; 119 else 120 pi3 += in->linesize[2]; 121 } 122 } 123 */ 124 125 126 void gfx_conv_yuv420p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height) 127 { 128 int i; 129 unsigned long *po, *po_eol; 130 register unsigned long *p; 131 unsigned long *pi, *pi2, *pi3; 132 register unsigned long y1, y2, u, v; 133 register unsigned long a, b, c, d; 134 // printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]); 135 // memcpy(out->data[0], in->data[0], height * in->linesize[0]); 136 po = (unsigned long *)out->data[0]; 137 pi = (unsigned long *)in->data[0]; 138 pi2 = (unsigned long *)in->data[1]; 139 pi3 = (unsigned long *)in->data[2]; 140 for(i=0; i<height; i++) { 141 for(p=po, po_eol = (unsigned long *)(((char *)po)+out->linesize[0]); p<po_eol;) { 142 // *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24)); 143 y1 = *pi++; 144 y2 = *pi++; 145 u = *pi2++; 146 v = *pi3++; 147 a = (long)(y1 & 0x0FF | ((u& 0x0FF) << 8) | ((y1 & 0x0FF00) << 8) | ((v & 0x0FF) << 24)); 148 b = (long)(((y1 & 0x0FF0000) >> 16) | ((u& 0x0FF00)) | ((y1 & 0x0FF000000) >> 8) | ((v & 0x0FF00) << 16)); 149 c = (long)(y2 & 0x0FF | ((u& 0x0FF0000) >> 8) | ((y2 & 0x0FF00) << 8) | ((v & 0x0FF0000) << 8)); 150 d = (long)(((y2 & 0x0FF0000) >> 16) | ((u& 0x0FF000000) >> 16) | ((y2 & 0x0FF000000) >> 8) | ((v & 0x0FF000000))); 151 152 153 *(p++) = a; 154 *(p++) = b; 155 *(p++) = c; 156 *(p++) = d; 157 } 158 po = (unsigned long *)((char *)po + out->linesize[0]); 159 pi = (unsigned long *)(in->data[0] + i * in->linesize[0]); 160 pi2 = (unsigned long *)(in->data[1] + ((i+1)/2) * in->linesize[1]); 161 pi3 = (unsigned long *)(in->data[2] + ((i)/2) * in->linesize[2]); 162 } 163 } 164 165 void gfx_conv_yuv410p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height) 166 { 167 gfx_conv_null_c(in, out, width, height); 168 } 169 170 171 void gfx_conv_yuv411p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height) 172 { 173 gfx_conv_null_c(in, out, width, height); 174 } 175 176 // the lookup table based versio in gfx_conv_c_lookup.cpp is faster! 177 #if 0 178 179 // Macro to limit the signed a into range 0-255, first one seems to be fastest 180 #define SATURATE(a) if (0xffffff00 & (uint32)a) { if (a < 0) a = 0; else a = 255; } 181 // #define SATURATE(a) if (0xffffff00 & (uint32)a) { if (0x80000000 & (uint32)a) a = 0; else a = 0xff; } 182 // #define SATURATE(a) if (a < 0) a = 0; else if (a > 255) a = 255; 183 // #define SATURATE(a) if (a < 0) a = 0; else if (a & 0xffffff00) a = 255; 184 // #define SATURATE(a) if (a < 0) a = 0; if (a & 0xffffff00) a = 255; 185 186 void gfx_conv_YCbCr420p_RGB32_c(AVFrame *in, AVFrame *out, int width, int height) 187 { 188 uint32 poutInc = 2 * out->linesize[0]; 189 uint32 *poutEven = (uint32 *)out->data[0]; 190 uint32 *poutOdd = (uint32 *)(out->linesize[0] + (uint8 *)poutEven); 191 192 uint32 pi1Inc = in->linesize[0]; 193 uint32 pi1Inc2 = 2 * pi1Inc; 194 uint32 pi2Inc = in->linesize[1]; 195 uint32 pi3Inc = in->linesize[2]; 196 197 uint8 *pi1Base = (uint8 *)in->data[0]; 198 uint8 *pi2Base = (uint8 *)in->data[1]; 199 uint8 *pi3Base = (uint8 *)in->data[2]; 200 201 uint32 runs = height / 2; 202 for (uint32 i = 0; i < runs; i++) { 203 204 uint16 *pi1Even = (uint16 *) (i * pi1Inc2 + pi1Base); 205 uint16 *pi1Odd = (uint16 *) (pi1Inc + (uint8 *)pi1Even); 206 uint8 *pi2 = i * pi2Inc + pi2Base; 207 uint8 *pi3 = i *pi3Inc + pi3Base; 208 209 for (uint32 j = 0; j < (uint32)width; j+= 2) { 210 211 int32 Cr_R, Cr_G, Cb_G, Cb_B; 212 register int32 Y0, Y1, R, G, B; 213 214 B = - 128 + *(pi2++); 215 R = - 128 + *(pi3++); 216 Cb_G = B * -12845; 217 Cb_B = B * 66493; 218 Cr_R = R * 52298; 219 Cr_G = R * -26640; 220 221 G = *(pi1Even++); 222 Y0 = ((G & 0x000000ff) - 16) * 38142; 223 Y1 = (((G & 0x0000ff00) >> 8) - 16) * 38142; 224 225 R = (Y0 + Cr_R) >> 15; 226 G = (Y0 + Cr_G + Cb_G) >> 15; 227 B = (Y0 + Cb_B) >> 15; 228 SATURATE(R); 229 SATURATE(B); 230 SATURATE(G); 231 poutEven[j] = (R << 16) | (G << 8) | B; 232 233 R = (Y1 + Cr_R) >> 15; 234 G = (Y1 + Cr_G + Cb_G) >> 15; 235 B = (Y1 + Cb_B) >> 15; 236 SATURATE(R); 237 SATURATE(B); 238 SATURATE(G); 239 poutEven[j + 1] = (R << 16) | (G << 8) | B; 240 241 G = *(pi1Odd++); 242 Y0 = ((G & 0x000000ff) - 16) * 38142; 243 Y1 = (((G & 0x0000ff00) >> 8) - 16) * 38142; 244 245 R = (Y0 + Cr_R) >> 15; 246 G = (Y0 + Cr_G + Cb_G) >> 15; 247 B = (Y0 + Cb_B) >> 15; 248 SATURATE(R); 249 SATURATE(B); 250 SATURATE(G); 251 poutOdd[j] = (R << 16) | (G << 8) | B; 252 253 R = (Y1 + Cr_R) >> 15; 254 G = (Y1 + Cr_G + Cb_G) >> 15; 255 B = (Y1 + Cb_B) >> 15; 256 SATURATE(R); 257 SATURATE(B); 258 SATURATE(G); 259 poutOdd[j + 1] = (R << 16) | (G << 8) | B; 260 } 261 poutEven = (uint32 *)(poutInc + (uint8 *)poutEven); 262 poutOdd = (uint32 *)(poutInc + (uint8 *)poutOdd); 263 } 264 if (height & 1) { 265 // XXX special case for last line if height not multiple of 2 goes here 266 memset((height - 1) * out->linesize[0] + (uint8 *)out->data[0], 0, width * 4); 267 } 268 } 269 270 #endif 271 272 #define CLIP(a) if (0xffffff00 & (uint32)a) { if (a < 0) a = 0; else a = 255; } 273 274 // http://en.wikipedia.org/wiki/YUV 275 uint32 YUV444TORGBA8888(uint8 y, uint8 u, uint8 v) 276 { 277 uint32 pixel = 0; 278 int32 c, d, e; 279 int32 r,g,b; 280 281 c = y - 16; 282 d = u - 128; 283 e = v - 128; 284 285 r = (298 * c + 409 * e + 128) >> 8; 286 g = (298 * c - 100 * d - 208 * e + 128) >> 8; 287 b = (298 * c + 516 * d + 128) >> 8; 288 289 CLIP(r); 290 CLIP(g); 291 CLIP(b); 292 293 pixel = (r << 16) | (g << 8) | b; 294 295 return pixel; 296 } 297 298 void gfx_conv_YCbCr422_RGB32_c(AVFrame *in, AVFrame *out, int width, int height) 299 { 300 uint8 *ybase = (uint8 *)in->data[0]; 301 uint8 *ubase = (uint8 *)in->data[1]; 302 uint8 *vbase = (uint8 *)in->data[2]; 303 304 uint32 *rgbbase = (uint32 *)out->data[0]; 305 306 int uv_index; 307 308 for (uint32 i = 0; i < height; i++) { 309 310 uv_index = 0; 311 312 for (uint32 j=0; j < width; j+=2) { 313 rgbbase[j] = YUV444TORGBA8888(ybase[j] ,ubase[uv_index],vbase[uv_index]); 314 rgbbase[j+1] = YUV444TORGBA8888(ybase[j+1],ubase[uv_index],vbase[uv_index]); 315 316 uv_index++; 317 } 318 319 ybase += in->linesize[0]; 320 ubase += in->linesize[1]; 321 vbase += in->linesize[2]; 322 323 rgbbase += out->linesize[0] / 4; 324 } 325 326 if (height & 1) { 327 // XXX special case for last line if height not multiple of 2 goes here 328 memset((height - 1) * out->linesize[0] + (uint8 *)out->data[0], 0, width * 4); 329 } 330 331 } 332