1 #include "gfx_conv_c.h"
2
3 #include <strings.h>
4 #include <stdio.h>
5
6
7 void
gfx_conv_null(AVFrame * in,AVFrame * out,int width,int height)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
gfx_conv_yuv410p_ycbcr422_c(AVFrame * in,AVFrame * out,int width,int height)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
gfx_conv_yuv411p_ycbcr422_c(AVFrame * in,AVFrame * out,int width,int height)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
gfx_conv_yuv420p_ycbcr422_c(AVFrame * in,AVFrame * out,int width,int height)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
YUV10TORGBA8888(uint16 y,uint16 u,uint16 v)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
gfx_conv_yuv420p10le_rgb32_c(AVFrame * in,AVFrame * out,int width,int height)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
YUV444TORGBA8888(uint8 y,uint8 u,uint8 v)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
gfx_conv_yuv410p_rgb32_c(AVFrame * in,AVFrame * out,int width,int height)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
gfx_conv_yuv411p_rgb32_c(AVFrame * in,AVFrame * out,int width,int height)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
gfx_conv_YCbCr422_RGB32_c(AVFrame * in,AVFrame * out,int width,int height)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
gfx_conv_GBRP_RGB32_c(AVFrame * in,AVFrame * out,int width,int height)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