1 /*
2 * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "libyuv/format_conversion.h"
12
13 #include "libyuv/basic_types.h"
14 #include "libyuv/cpu_id.h"
15 #include "libyuv/video_common.h"
16 #include "libyuv/row.h"
17
18 #ifdef __cplusplus
19 namespace libyuv {
20 extern "C" {
21 #endif
22
23 // Note: to do this with Neon vld4.8 would load ARGB values into 4 registers
24 // and vst would select which 2 components to write. The low level would need
25 // to be ARGBToBG, ARGBToGB, ARGBToRG, ARGBToGR
26
27 #if !defined(YUV_DISABLE_ASM) && defined(_M_IX86)
28 #define HAS_ARGBTOBAYERROW_SSSE3
29 __declspec(naked) __declspec(align(16))
ARGBToBayerRow_SSSE3(const uint8 * src_argb,uint8 * dst_bayer,uint32 selector,int pix)30 static void ARGBToBayerRow_SSSE3(const uint8* src_argb,
31 uint8* dst_bayer, uint32 selector, int pix) {
32 __asm {
33 mov eax, [esp + 4] // src_argb
34 mov edx, [esp + 8] // dst_bayer
35 movd xmm5, [esp + 12] // selector
36 mov ecx, [esp + 16] // pix
37 pshufd xmm5, xmm5, 0
38
39 align 16
40 wloop:
41 movdqa xmm0, [eax]
42 lea eax, [eax + 16]
43 pshufb xmm0, xmm5
44 sub ecx, 4
45 movd [edx], xmm0
46 lea edx, [edx + 4]
47 jg wloop
48 ret
49 }
50 }
51
52 #elif !defined(YUV_DISABLE_ASM) && (defined(__x86_64__) || defined(__i386__))
53
54 #define HAS_ARGBTOBAYERROW_SSSE3
55 static void ARGBToBayerRow_SSSE3(const uint8* src_argb, uint8* dst_bayer,
56 uint32 selector, int pix) {
57 asm volatile (
58 "movd %3,%%xmm5 \n"
59 "pshufd $0x0,%%xmm5,%%xmm5 \n"
60 ".p2align 4 \n"
61 "1: \n"
62 "movdqa (%0),%%xmm0 \n"
63 "lea 0x10(%0),%0 \n"
64 "pshufb %%xmm5,%%xmm0 \n"
65 "sub $0x4,%2 \n"
66 "movd %%xmm0,(%1) \n"
67 "lea 0x4(%1),%1 \n"
68 "jg 1b \n"
69 : "+r"(src_argb), // %0
70 "+r"(dst_bayer), // %1
71 "+r"(pix) // %2
72 : "g"(selector) // %3
73 : "memory", "cc"
74 #if defined(__SSE2__)
75 , "xmm0", "xmm5"
76 #endif
77
78 );
79 }
80 #endif
81
ARGBToBayerRow_C(const uint8 * src_argb,uint8 * dst_bayer,uint32 selector,int pix)82 static void ARGBToBayerRow_C(const uint8* src_argb,
83 uint8* dst_bayer, uint32 selector, int pix) {
84 int index0 = selector & 0xff;
85 int index1 = (selector >> 8) & 0xff;
86 // Copy a row of Bayer.
87 for (int x = 0; x < pix - 1; x += 2) {
88 dst_bayer[0] = src_argb[index0];
89 dst_bayer[1] = src_argb[index1];
90 src_argb += 8;
91 dst_bayer += 2;
92 }
93 if (pix & 1) {
94 dst_bayer[0] = src_argb[index0];
95 }
96 }
97
98 // generate a selector mask useful for pshufb
GenerateSelector(int select0,int select1)99 static uint32 GenerateSelector(int select0, int select1) {
100 return static_cast<uint32>(select0) |
101 static_cast<uint32>((select1 + 4) << 8) |
102 static_cast<uint32>((select0 + 8) << 16) |
103 static_cast<uint32>((select1 + 12) << 24);
104 }
105
MakeSelectors(const int blue_index,const int green_index,const int red_index,uint32 dst_fourcc_bayer,uint32 * index_map)106 static int MakeSelectors(const int blue_index,
107 const int green_index,
108 const int red_index,
109 uint32 dst_fourcc_bayer,
110 uint32 *index_map) {
111 // Now build a lookup table containing the indices for the four pixels in each
112 // 2x2 Bayer grid.
113 switch (dst_fourcc_bayer) {
114 case FOURCC_BGGR:
115 index_map[0] = GenerateSelector(blue_index, green_index);
116 index_map[1] = GenerateSelector(green_index, red_index);
117 break;
118 case FOURCC_GBRG:
119 index_map[0] = GenerateSelector(green_index, blue_index);
120 index_map[1] = GenerateSelector(red_index, green_index);
121 break;
122 case FOURCC_RGGB:
123 index_map[0] = GenerateSelector(red_index, green_index);
124 index_map[1] = GenerateSelector(green_index, blue_index);
125 break;
126 case FOURCC_GRBG:
127 index_map[0] = GenerateSelector(green_index, red_index);
128 index_map[1] = GenerateSelector(blue_index, green_index);
129 break;
130 default:
131 return -1; // Bad FourCC
132 }
133 return 0;
134 }
135
136 // Converts 32 bit ARGB to Bayer RGB formats.
137 LIBYUV_API
ARGBToBayer(const uint8 * src_argb,int src_stride_argb,uint8 * dst_bayer,int dst_stride_bayer,int width,int height,uint32 dst_fourcc_bayer)138 int ARGBToBayer(const uint8* src_argb, int src_stride_argb,
139 uint8* dst_bayer, int dst_stride_bayer,
140 int width, int height,
141 uint32 dst_fourcc_bayer) {
142 if (height < 0) {
143 height = -height;
144 src_argb = src_argb + (height - 1) * src_stride_argb;
145 src_stride_argb = -src_stride_argb;
146 }
147 void (*ARGBToBayerRow)(const uint8* src_argb, uint8* dst_bayer,
148 uint32 selector, int pix) = ARGBToBayerRow_C;
149 #if defined(HAS_ARGBTOBAYERROW_SSSE3)
150 if (TestCpuFlag(kCpuHasSSSE3) &&
151 IS_ALIGNED(width, 4) &&
152 IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
153 ARGBToBayerRow = ARGBToBayerRow_SSSE3;
154 }
155 #endif
156 const int blue_index = 0; // Offsets for ARGB format
157 const int green_index = 1;
158 const int red_index = 2;
159 uint32 index_map[2];
160 if (MakeSelectors(blue_index, green_index, red_index,
161 dst_fourcc_bayer, index_map)) {
162 return -1; // Bad FourCC
163 }
164
165 for (int y = 0; y < height; ++y) {
166 ARGBToBayerRow(src_argb, dst_bayer, index_map[y & 1], width);
167 src_argb += src_stride_argb;
168 dst_bayer += dst_stride_bayer;
169 }
170 return 0;
171 }
172
173 #define AVG(a, b) (((a) + (b)) >> 1)
174
BayerRowBG(const uint8 * src_bayer0,int src_stride_bayer,uint8 * dst_argb,int pix)175 static void BayerRowBG(const uint8* src_bayer0, int src_stride_bayer,
176 uint8* dst_argb, int pix) {
177 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
178 uint8 g = src_bayer0[1];
179 uint8 r = src_bayer1[1];
180 for (int x = 0; x < pix - 2; x += 2) {
181 dst_argb[0] = src_bayer0[0];
182 dst_argb[1] = AVG(g, src_bayer0[1]);
183 dst_argb[2] = AVG(r, src_bayer1[1]);
184 dst_argb[3] = 255U;
185 dst_argb[4] = AVG(src_bayer0[0], src_bayer0[2]);
186 dst_argb[5] = src_bayer0[1];
187 dst_argb[6] = src_bayer1[1];
188 dst_argb[7] = 255U;
189 g = src_bayer0[1];
190 r = src_bayer1[1];
191 src_bayer0 += 2;
192 src_bayer1 += 2;
193 dst_argb += 8;
194 }
195 dst_argb[0] = src_bayer0[0];
196 dst_argb[1] = AVG(g, src_bayer0[1]);
197 dst_argb[2] = AVG(r, src_bayer1[1]);
198 dst_argb[3] = 255U;
199 if (!(pix & 1)) {
200 dst_argb[4] = src_bayer0[0];
201 dst_argb[5] = src_bayer0[1];
202 dst_argb[6] = src_bayer1[1];
203 dst_argb[7] = 255U;
204 }
205 }
206
BayerRowRG(const uint8 * src_bayer0,int src_stride_bayer,uint8 * dst_argb,int pix)207 static void BayerRowRG(const uint8* src_bayer0, int src_stride_bayer,
208 uint8* dst_argb, int pix) {
209 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
210 uint8 g = src_bayer0[1];
211 uint8 b = src_bayer1[1];
212 for (int x = 0; x < pix - 2; x += 2) {
213 dst_argb[0] = AVG(b, src_bayer1[1]);
214 dst_argb[1] = AVG(g, src_bayer0[1]);
215 dst_argb[2] = src_bayer0[0];
216 dst_argb[3] = 255U;
217 dst_argb[4] = src_bayer1[1];
218 dst_argb[5] = src_bayer0[1];
219 dst_argb[6] = AVG(src_bayer0[0], src_bayer0[2]);
220 dst_argb[7] = 255U;
221 g = src_bayer0[1];
222 b = src_bayer1[1];
223 src_bayer0 += 2;
224 src_bayer1 += 2;
225 dst_argb += 8;
226 }
227 dst_argb[0] = AVG(b, src_bayer1[1]);
228 dst_argb[1] = AVG(g, src_bayer0[1]);
229 dst_argb[2] = src_bayer0[0];
230 dst_argb[3] = 255U;
231 if (!(pix & 1)) {
232 dst_argb[4] = src_bayer1[1];
233 dst_argb[5] = src_bayer0[1];
234 dst_argb[6] = src_bayer0[0];
235 dst_argb[7] = 255U;
236 }
237 }
238
BayerRowGB(const uint8 * src_bayer0,int src_stride_bayer,uint8 * dst_argb,int pix)239 static void BayerRowGB(const uint8* src_bayer0, int src_stride_bayer,
240 uint8* dst_argb, int pix) {
241 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
242 uint8 b = src_bayer0[1];
243 for (int x = 0; x < pix - 2; x += 2) {
244 dst_argb[0] = AVG(b, src_bayer0[1]);
245 dst_argb[1] = src_bayer0[0];
246 dst_argb[2] = src_bayer1[0];
247 dst_argb[3] = 255U;
248 dst_argb[4] = src_bayer0[1];
249 dst_argb[5] = AVG(src_bayer0[0], src_bayer0[2]);
250 dst_argb[6] = AVG(src_bayer1[0], src_bayer1[2]);
251 dst_argb[7] = 255U;
252 b = src_bayer0[1];
253 src_bayer0 += 2;
254 src_bayer1 += 2;
255 dst_argb += 8;
256 }
257 dst_argb[0] = AVG(b, src_bayer0[1]);
258 dst_argb[1] = src_bayer0[0];
259 dst_argb[2] = src_bayer1[0];
260 dst_argb[3] = 255U;
261 if (!(pix & 1)) {
262 dst_argb[4] = src_bayer0[1];
263 dst_argb[5] = src_bayer0[0];
264 dst_argb[6] = src_bayer1[0];
265 dst_argb[7] = 255U;
266 }
267 }
268
BayerRowGR(const uint8 * src_bayer0,int src_stride_bayer,uint8 * dst_argb,int pix)269 static void BayerRowGR(const uint8* src_bayer0, int src_stride_bayer,
270 uint8* dst_argb, int pix) {
271 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
272 uint8 r = src_bayer0[1];
273 for (int x = 0; x < pix - 2; x += 2) {
274 dst_argb[0] = src_bayer1[0];
275 dst_argb[1] = src_bayer0[0];
276 dst_argb[2] = AVG(r, src_bayer0[1]);
277 dst_argb[3] = 255U;
278 dst_argb[4] = AVG(src_bayer1[0], src_bayer1[2]);
279 dst_argb[5] = AVG(src_bayer0[0], src_bayer0[2]);
280 dst_argb[6] = src_bayer0[1];
281 dst_argb[7] = 255U;
282 r = src_bayer0[1];
283 src_bayer0 += 2;
284 src_bayer1 += 2;
285 dst_argb += 8;
286 }
287 dst_argb[0] = src_bayer1[0];
288 dst_argb[1] = src_bayer0[0];
289 dst_argb[2] = AVG(r, src_bayer0[1]);
290 dst_argb[3] = 255U;
291 if (!(pix & 1)) {
292 dst_argb[4] = src_bayer1[0];
293 dst_argb[5] = src_bayer0[0];
294 dst_argb[6] = src_bayer0[1];
295 dst_argb[7] = 255U;
296 }
297 }
298
299 // Converts any Bayer RGB format to ARGB.
300 LIBYUV_API
BayerToARGB(const uint8 * src_bayer,int src_stride_bayer,uint8 * dst_argb,int dst_stride_argb,int width,int height,uint32 src_fourcc_bayer)301 int BayerToARGB(const uint8* src_bayer, int src_stride_bayer,
302 uint8* dst_argb, int dst_stride_argb,
303 int width, int height,
304 uint32 src_fourcc_bayer) {
305 if (height < 0) {
306 height = -height;
307 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
308 dst_stride_argb = -dst_stride_argb;
309 }
310 void (*BayerRow0)(const uint8* src_bayer, int src_stride_bayer,
311 uint8* dst_argb, int pix);
312 void (*BayerRow1)(const uint8* src_bayer, int src_stride_bayer,
313 uint8* dst_argb, int pix);
314 switch (src_fourcc_bayer) {
315 case FOURCC_BGGR:
316 BayerRow0 = BayerRowBG;
317 BayerRow1 = BayerRowGR;
318 break;
319 case FOURCC_GBRG:
320 BayerRow0 = BayerRowGB;
321 BayerRow1 = BayerRowRG;
322 break;
323 case FOURCC_GRBG:
324 BayerRow0 = BayerRowGR;
325 BayerRow1 = BayerRowBG;
326 break;
327 case FOURCC_RGGB:
328 BayerRow0 = BayerRowRG;
329 BayerRow1 = BayerRowGB;
330 break;
331 default:
332 return -1; // Bad FourCC
333 }
334
335 for (int y = 0; y < height - 1; y += 2) {
336 BayerRow0(src_bayer, src_stride_bayer, dst_argb, width);
337 BayerRow1(src_bayer + src_stride_bayer, -src_stride_bayer,
338 dst_argb + dst_stride_argb, width);
339 src_bayer += src_stride_bayer * 2;
340 dst_argb += dst_stride_argb * 2;
341 }
342 if (height & 1) {
343 BayerRow0(src_bayer, -src_stride_bayer, dst_argb, width);
344 }
345 return 0;
346 }
347
348 // Converts any Bayer RGB format to ARGB.
349 LIBYUV_API
BayerToI420(const uint8 * src_bayer,int src_stride_bayer,uint8 * dst_y,int dst_stride_y,uint8 * dst_u,int dst_stride_u,uint8 * dst_v,int dst_stride_v,int width,int height,uint32 src_fourcc_bayer)350 int BayerToI420(const uint8* src_bayer, int src_stride_bayer,
351 uint8* dst_y, int dst_stride_y,
352 uint8* dst_u, int dst_stride_u,
353 uint8* dst_v, int dst_stride_v,
354 int width, int height,
355 uint32 src_fourcc_bayer) {
356 if (width * 4 > kMaxStride) {
357 return -1; // Size too large for row buffer
358 }
359 // Negative height means invert the image.
360 if (height < 0) {
361 height = -height;
362 int halfheight = (height + 1) >> 1;
363 dst_y = dst_y + (height - 1) * dst_stride_y;
364 dst_u = dst_u + (halfheight - 1) * dst_stride_u;
365 dst_v = dst_v + (halfheight - 1) * dst_stride_v;
366 dst_stride_y = -dst_stride_y;
367 dst_stride_u = -dst_stride_u;
368 dst_stride_v = -dst_stride_v;
369 }
370 void (*BayerRow0)(const uint8* src_bayer, int src_stride_bayer,
371 uint8* dst_argb, int pix);
372 void (*BayerRow1)(const uint8* src_bayer, int src_stride_bayer,
373 uint8* dst_argb, int pix);
374 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) =
375 ARGBToYRow_C;
376 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
377 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
378 SIMD_ALIGNED(uint8 row[kMaxStride * 2]);
379
380 #if defined(HAS_ARGBTOYROW_SSSE3)
381 if (TestCpuFlag(kCpuHasSSSE3) &&
382 IS_ALIGNED(width, 16) &&
383 IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
384 ARGBToYRow = ARGBToYRow_SSSE3;
385 }
386 #endif
387 #if defined(HAS_ARGBTOUVROW_SSSE3)
388 if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) {
389 ARGBToUVRow = ARGBToUVRow_SSSE3;
390 }
391 #endif
392
393 switch (src_fourcc_bayer) {
394 case FOURCC_BGGR:
395 BayerRow0 = BayerRowBG;
396 BayerRow1 = BayerRowGR;
397 break;
398 case FOURCC_GBRG:
399 BayerRow0 = BayerRowGB;
400 BayerRow1 = BayerRowRG;
401 break;
402 case FOURCC_GRBG:
403 BayerRow0 = BayerRowGR;
404 BayerRow1 = BayerRowBG;
405 break;
406 case FOURCC_RGGB:
407 BayerRow0 = BayerRowRG;
408 BayerRow1 = BayerRowGB;
409 break;
410 default:
411 return -1; // Bad FourCC
412 }
413
414 for (int y = 0; y < height - 1; y += 2) {
415 BayerRow0(src_bayer, src_stride_bayer, row, width);
416 BayerRow1(src_bayer + src_stride_bayer, -src_stride_bayer,
417 row + kMaxStride, width);
418 ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width);
419 ARGBToYRow(row, dst_y, width);
420 ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width);
421 src_bayer += src_stride_bayer * 2;
422 dst_y += dst_stride_y * 2;
423 dst_u += dst_stride_u;
424 dst_v += dst_stride_v;
425 }
426 if (height & 1) {
427 BayerRow0(src_bayer, src_stride_bayer, row, width);
428 ARGBToUVRow(row, 0, dst_u, dst_v, width);
429 ARGBToYRow(row, dst_y, width);
430 }
431 return 0;
432 }
433
434 // Convert I420 to Bayer.
435 LIBYUV_API
I420ToBayer(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_bayer,int dst_stride_bayer,int width,int height,uint32 dst_fourcc_bayer)436 int I420ToBayer(const uint8* src_y, int src_stride_y,
437 const uint8* src_u, int src_stride_u,
438 const uint8* src_v, int src_stride_v,
439 uint8* dst_bayer, int dst_stride_bayer,
440 int width, int height,
441 uint32 dst_fourcc_bayer) {
442 // Negative height means invert the image.
443 if (height < 0) {
444 height = -height;
445 int halfheight = (height + 1) >> 1;
446 src_y = src_y + (height - 1) * src_stride_y;
447 src_u = src_u + (halfheight - 1) * src_stride_u;
448 src_v = src_v + (halfheight - 1) * src_stride_v;
449 src_stride_y = -src_stride_y;
450 src_stride_u = -src_stride_u;
451 src_stride_v = -src_stride_v;
452 }
453 void (*I422ToARGBRow)(const uint8* y_buf,
454 const uint8* u_buf,
455 const uint8* v_buf,
456 uint8* rgb_buf,
457 int width) = I422ToARGBRow_C;
458 #if defined(HAS_I422TOARGBROW_NEON)
459 if (TestCpuFlag(kCpuHasNEON)) {
460 I422ToARGBRow = I422ToARGBRow_NEON;
461 }
462 #elif defined(HAS_I422TOARGBROW_SSSE3)
463 if (TestCpuFlag(kCpuHasSSSE3)) {
464 I422ToARGBRow = I422ToARGBRow_SSSE3;
465 }
466 #endif
467 SIMD_ALIGNED(uint8 row[kMaxStride]);
468 void (*ARGBToBayerRow)(const uint8* src_argb, uint8* dst_bayer,
469 uint32 selector, int pix) = ARGBToBayerRow_C;
470 #if defined(HAS_ARGBTOBAYERROW_SSSE3)
471 if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4)) {
472 ARGBToBayerRow = ARGBToBayerRow_SSSE3;
473 }
474 #endif
475 const int blue_index = 0; // Offsets for ARGB format
476 const int green_index = 1;
477 const int red_index = 2;
478 uint32 index_map[2];
479 if (MakeSelectors(blue_index, green_index, red_index,
480 dst_fourcc_bayer, index_map)) {
481 return -1; // Bad FourCC
482 }
483
484 for (int y = 0; y < height; ++y) {
485 I422ToARGBRow(src_y, src_u, src_v, row, width);
486 ARGBToBayerRow(row, dst_bayer, index_map[y & 1], width);
487 dst_bayer += dst_stride_bayer;
488 src_y += src_stride_y;
489 if (y & 1) {
490 src_u += src_stride_u;
491 src_v += src_stride_v;
492 }
493 }
494 return 0;
495 }
496
497 #define MAKEBAYERFOURCC(BAYER) \
498 LIBYUV_API \
499 int Bayer##BAYER##ToI420(const uint8* src_bayer, int src_stride_bayer, \
500 uint8* dst_y, int dst_stride_y, \
501 uint8* dst_u, int dst_stride_u, \
502 uint8* dst_v, int dst_stride_v, \
503 int width, int height) { \
504 return BayerToI420(src_bayer, src_stride_bayer, \
505 dst_y, dst_stride_y, \
506 dst_u, dst_stride_u, \
507 dst_v, dst_stride_v, \
508 width, height, \
509 FOURCC_##BAYER); \
510 } \
511 \
512 LIBYUV_API \
513 int I420ToBayer##BAYER(const uint8* src_y, int src_stride_y, \
514 const uint8* src_u, int src_stride_u, \
515 const uint8* src_v, int src_stride_v, \
516 uint8* dst_bayer, int dst_stride_bayer, \
517 int width, int height) { \
518 return I420ToBayer(src_y, src_stride_y, \
519 src_u, src_stride_u, \
520 src_v, src_stride_v, \
521 dst_bayer, dst_stride_bayer, \
522 width, height, \
523 FOURCC_##BAYER); \
524 } \
525 \
526 LIBYUV_API \
527 int ARGBToBayer##BAYER(const uint8* src_argb, int src_stride_argb, \
528 uint8* dst_bayer, int dst_stride_bayer, \
529 int width, int height) { \
530 return ARGBToBayer(src_argb, src_stride_argb, \
531 dst_bayer, dst_stride_bayer, \
532 width, height, \
533 FOURCC_##BAYER); \
534 } \
535 \
536 LIBYUV_API \
537 int Bayer##BAYER##ToARGB(const uint8* src_bayer, int src_stride_bayer, \
538 uint8* dst_argb, int dst_stride_argb, \
539 int width, int height) { \
540 return BayerToARGB(src_bayer, src_stride_bayer, \
541 dst_argb, dst_stride_argb, \
542 width, height, \
543 FOURCC_##BAYER); \
544 }
545
546 MAKEBAYERFOURCC(BGGR)
547 MAKEBAYERFOURCC(GBRG)
548 MAKEBAYERFOURCC(GRBG)
549 MAKEBAYERFOURCC(RGGB)
550
551 #ifdef __cplusplus
552 } // extern "C"
553 } // namespace libyuv
554 #endif
555