2 * Implementation of color conversion for MARU Virtual Camera device on MacOS.
4 * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
7 * Jun Tian <jun.j.tian@intel.com>
8 * JinHyung Jo <jinhyung.jo@samsung.com>
9 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
31 #include "qemu-common.h"
32 #include "maru_camera_darwin.h"
33 #include "tizen/src/debug_ch.h"
35 MULTI_DEBUG_CHANNEL(tizen, camera_darwin);
37 static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
38 int width, int height);
39 static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
40 int width, int height);
41 static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
42 int width, int height);
44 /* Convert pixel format to YUV420 */
45 void convert_frame(uint32_t pixel_format, int frame_width, int frame_height,
46 size_t frame_size, void *frame_pixels, void *video_buf)
48 switch (pixel_format) {
49 case V4L2_PIX_FMT_YUV420:
50 memcpy(video_buf, (void *)frame_pixels, (size_t)frame_size);
52 case V4L2_PIX_FMT_YVU420:
53 YVU420ToYUV420(frame_pixels, video_buf, frame_width, frame_height);
55 case V4L2_PIX_FMT_YUYV:
56 YUYVToYUV420(frame_pixels, video_buf, frame_width, frame_height);
58 case V4L2_PIX_FMT_UYVY: /* Mac default format */
59 UYVYToYUV420(frame_pixels, video_buf, frame_width, frame_height);
62 ERR("Cannot convert the pixel format (%.4s)...\n",
63 (const char *)&pixel_format);
68 static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
69 int width, int height)
74 unsigned char *ptrsrcy1, *ptrsrcy2;
75 unsigned char *ptrsrcy3, *ptrsrcy4;
76 unsigned char *ptrsrccb1;
77 unsigned char *ptrsrccb3;
78 unsigned char *ptrsrccr1;
79 unsigned char *ptrsrccr3;
80 int srcystride, srcccstride;
82 ptrsrcy1 = bufsrc + 1;
83 ptrsrcy2 = bufsrc + (width << 1) + 1;
84 ptrsrcy3 = bufsrc + (width << 1) * 2 + 1;
85 ptrsrcy4 = bufsrc + (width << 1) * 3 + 1;
88 ptrsrccb3 = bufsrc + (width << 1) * 2;
90 ptrsrccr1 = bufsrc + 2;
91 ptrsrccr3 = bufsrc + (width << 1) * 2 + 2;
93 srcystride = (width << 1) * 3;
94 srcccstride = (width << 1) * 3;
97 unsigned char *ptrdesty1, *ptrdesty2;
98 unsigned char *ptrdesty3, *ptrdesty4;
99 unsigned char *ptrdestcb1, *ptrdestcb2;
100 unsigned char *ptrdestcr1, *ptrdestcr2;
101 int destystride, destccstride;
104 ptrdesty2 = bufdest + width;
105 ptrdesty3 = bufdest + width * 2;
106 ptrdesty4 = bufdest + width * 3;
108 ptrdestcb1 = bufdest + width * height;
109 ptrdestcb2 = bufdest + width * height + (width >> 1);
111 ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
112 ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
115 destystride = (width)*3;
116 destccstride = (width>>1);
118 for (j = 0; j < (height / 4); j++) {
119 for (i = 0; i < (width / 2); i++) {
120 (*ptrdesty1++) = (*ptrsrcy1);
121 (*ptrdesty2++) = (*ptrsrcy2);
122 (*ptrdesty3++) = (*ptrsrcy3);
123 (*ptrdesty4++) = (*ptrsrcy4);
130 (*ptrdesty1++) = (*ptrsrcy1);
131 (*ptrdesty2++) = (*ptrsrcy2);
132 (*ptrdesty3++) = (*ptrsrcy3);
133 (*ptrdesty4++) = (*ptrsrcy4);
140 (*ptrdestcb1++) = (*ptrsrccb1);
141 (*ptrdestcb2++) = (*ptrsrccb3);
146 (*ptrdestcr1++) = (*ptrsrccr1);
147 (*ptrdestcr2++) = (*ptrsrccr3);
154 /* Update src pointers */
155 ptrsrcy1 += srcystride;
156 ptrsrcy2 += srcystride;
157 ptrsrcy3 += srcystride;
158 ptrsrcy4 += srcystride;
160 ptrsrccb1 += srcccstride;
161 ptrsrccb3 += srcccstride;
163 ptrsrccr1 += srcccstride;
164 ptrsrccr3 += srcccstride;
166 /* Update dest pointers */
167 ptrdesty1 += destystride;
168 ptrdesty2 += destystride;
169 ptrdesty3 += destystride;
170 ptrdesty4 += destystride;
172 ptrdestcb1 += destccstride;
173 ptrdestcb2 += destccstride;
175 ptrdestcr1 += destccstride;
176 ptrdestcr2 += destccstride;
180 static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
181 int width, int height)
186 unsigned char *ptrsrcy1, *ptrsrcy2;
187 unsigned char *ptrsrcy3, *ptrsrcy4;
188 unsigned char *ptrsrccb1, *ptrsrccb2;
189 unsigned char *ptrsrccr1, *ptrsrccr2;
190 int srcystride, srcccstride;
193 ptrsrcy2 = bufsrc + width;
194 ptrsrcy3 = bufsrc + width*2;
195 ptrsrcy4 = bufsrc + width*3;
197 ptrsrccr1 = bufsrc + width*height;
198 ptrsrccr2 = bufsrc + width*height + (width>>1);
200 ptrsrccb1 = bufsrc + width*height + ((width*height) >> 2);
201 ptrsrccb2 = bufsrc + width*height + ((width*height) >> 2) + (width>>1);
203 srcystride = (width)*3;
204 srcccstride = (width>>1);
207 unsigned char *ptrdesty1, *ptrdesty2;
208 unsigned char *ptrdesty3, *ptrdesty4;
209 unsigned char *ptrdestcb1, *ptrdestcb2;
210 unsigned char *ptrdestcr1, *ptrdestcr2;
211 int destystride, destccstride;
214 ptrdesty2 = bufdest + width;
215 ptrdesty3 = bufdest + width * 2;
216 ptrdesty4 = bufdest + width * 3;
218 ptrdestcb1 = bufdest + width * height;
219 ptrdestcb2 = bufdest + width * height + (width >> 1);
221 ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
222 ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
225 destystride = (width)*3;
226 destccstride = (width>>1);
228 for (j = 0; j < (height / 4); j++) {
229 for (i = 0; i < (width / 2); i++) {
231 (*ptrdesty1++) = (*ptrsrcy1++);
232 (*ptrdesty2++) = (*ptrsrcy2++);
233 (*ptrdesty3++) = (*ptrsrcy3++);
234 (*ptrdesty4++) = (*ptrsrcy4++);
235 (*ptrdesty1++) = (*ptrsrcy1++);
236 (*ptrdesty2++) = (*ptrsrcy2++);
237 (*ptrdesty3++) = (*ptrsrcy3++);
238 (*ptrdesty4++) = (*ptrsrcy4++);
240 (*ptrdestcb1++) = (*ptrsrccb1++);
241 (*ptrdestcr1++) = (*ptrsrccr1++);
242 (*ptrdestcb2++) = (*ptrsrccb2++);
243 (*ptrdestcr2++) = (*ptrsrccr2++);
247 /* Update src pointers */
248 ptrsrcy1 += srcystride;
249 ptrsrcy2 += srcystride;
250 ptrsrcy3 += srcystride;
251 ptrsrcy4 += srcystride;
253 ptrsrccb1 += srcccstride;
254 ptrsrccb2 += srcccstride;
256 ptrsrccr1 += srcccstride;
257 ptrsrccr2 += srcccstride;
259 /* Update dest pointers */
260 ptrdesty1 += destystride;
261 ptrdesty2 += destystride;
262 ptrdesty3 += destystride;
263 ptrdesty4 += destystride;
265 ptrdestcb1 += destccstride;
266 ptrdestcb2 += destccstride;
268 ptrdestcr1 += destccstride;
269 ptrdestcr2 += destccstride;
275 static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
276 int width, int height)
281 unsigned char *ptrsrcy1, *ptrsrcy2;
282 unsigned char *ptrsrcy3, *ptrsrcy4;
283 unsigned char *ptrsrccb1;
284 unsigned char *ptrsrccb3;
285 unsigned char *ptrsrccr1;
286 unsigned char *ptrsrccr3;
287 int srcystride, srcccstride;
290 ptrsrcy2 = bufsrc + (width << 1);
291 ptrsrcy3 = bufsrc + (width << 1) * 2;
292 ptrsrcy4 = bufsrc + (width << 1) * 3;
294 ptrsrccb1 = bufsrc + 1;
295 ptrsrccb3 = bufsrc + (width << 1) * 2 + 1;
297 ptrsrccr1 = bufsrc + 3;
298 ptrsrccr3 = bufsrc + (width << 1) * 2 + 3;
300 srcystride = (width << 1) * 3;
301 srcccstride = (width << 1) * 3;
304 unsigned char *ptrdesty1, *ptrdesty2;
305 unsigned char *ptrdesty3, *ptrdesty4;
306 unsigned char *ptrdestcb1, *ptrdestcb2;
307 unsigned char *ptrdestcr1, *ptrdestcr2;
308 int destystride, destccstride;
311 ptrdesty2 = bufdest + width;
312 ptrdesty3 = bufdest + width * 2;
313 ptrdesty4 = bufdest + width * 3;
315 ptrdestcb1 = bufdest + width * height;
316 ptrdestcb2 = bufdest + width * height + (width >> 1);
318 ptrdestcr1 = bufdest + width * height + ((width * height) >> 2);
319 ptrdestcr2 = bufdest + width * height + ((width * height) >> 2)
322 destystride = width * 3;
323 destccstride = (width >> 1);
325 for (j = 0; j < (height / 4); j++) {
326 for (i = 0; i < (width / 2); i++) {
327 (*ptrdesty1++) = (*ptrsrcy1);
328 (*ptrdesty2++) = (*ptrsrcy2);
329 (*ptrdesty3++) = (*ptrsrcy3);
330 (*ptrdesty4++) = (*ptrsrcy4);
337 (*ptrdesty1++) = (*ptrsrcy1);
338 (*ptrdesty2++) = (*ptrsrcy2);
339 (*ptrdesty3++) = (*ptrsrcy3);
340 (*ptrdesty4++) = (*ptrsrcy4);
347 (*ptrdestcb1++) = (*ptrsrccb1);
348 (*ptrdestcb2++) = (*ptrsrccb3);
353 (*ptrdestcr1++) = (*ptrsrccr1);
354 (*ptrdestcr2++) = (*ptrsrccr3);
361 /* Update src pointers */
362 ptrsrcy1 += srcystride;
363 ptrsrcy2 += srcystride;
364 ptrsrcy3 += srcystride;
365 ptrsrcy4 += srcystride;
367 ptrsrccb1 += srcccstride;
368 ptrsrccb3 += srcccstride;
370 ptrsrccr1 += srcccstride;
371 ptrsrccr3 += srcccstride;
373 /* Update dest pointers */
374 ptrdesty1 += destystride;
375 ptrdesty2 += destystride;
376 ptrdesty3 += destystride;
377 ptrdesty4 += destystride;
379 ptrdestcb1 += destccstride;
380 ptrdestcb2 += destccstride;
382 ptrdestcr1 += destccstride;
383 ptrdestcr2 += destccstride;