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