1 /* Gstreamer video blending utility functions
3 * Copied/pasted from gst/videoconvert/videoconvert.c
4 * Copyright (C) 2010 David Schleef <ds@schleef.org>
5 * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
7 * Copyright (C) <2011> Intel Corporation
8 * Copyright (C) <2011> Collabora Ltd.
9 * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
16 * This library 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 GNU
19 * Library General Public License for more details.
21 * You should have received a copy of the GNU Library General Public
22 * License along with this library; if not, write to the
23 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
30 #include "video-blend.h"
31 #include "videoblendorc.h"
35 #ifndef GST_DISABLE_GST_DEBUG
37 #define GST_CAT_DEFAULT ensure_debug_category()
39 static GstDebugCategory *
40 ensure_debug_category (void)
42 static gsize cat_gonce = 0;
44 if (g_once_init_enter (&cat_gonce)) {
47 cat_done = (gsize) _gst_debug_category_new ("video-blending", 0,
50 g_once_init_leave (&cat_gonce, cat_done);
53 return (GstDebugCategory *) cat_gonce;
58 #define ensure_debug_category() /* NOOP */
60 #endif /* GST_DISABLE_GST_DEBUG */
62 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
74 /* Copy/pasted from 0.11 video.c */
76 fill_planes (GstBlendVideoFormatInfo * info)
81 height = info->height;
84 case GST_VIDEO_FORMAT_YUY2:
85 case GST_VIDEO_FORMAT_YVYU:
86 case GST_VIDEO_FORMAT_UYVY:
87 info->stride[0] = GST_ROUND_UP_4 (width * 2);
90 case GST_VIDEO_FORMAT_AYUV:
91 case GST_VIDEO_FORMAT_RGBx:
92 case GST_VIDEO_FORMAT_RGBA:
93 case GST_VIDEO_FORMAT_BGRx:
94 case GST_VIDEO_FORMAT_BGRA:
95 case GST_VIDEO_FORMAT_xRGB:
96 case GST_VIDEO_FORMAT_ARGB:
97 case GST_VIDEO_FORMAT_xBGR:
98 case GST_VIDEO_FORMAT_ABGR:
99 case GST_VIDEO_FORMAT_r210:
100 info->stride[0] = width * 4;
103 case GST_VIDEO_FORMAT_RGB16:
104 case GST_VIDEO_FORMAT_BGR16:
105 case GST_VIDEO_FORMAT_RGB15:
106 case GST_VIDEO_FORMAT_BGR15:
107 info->stride[0] = GST_ROUND_UP_4 (width * 2);
110 case GST_VIDEO_FORMAT_RGB:
111 case GST_VIDEO_FORMAT_BGR:
112 case GST_VIDEO_FORMAT_v308:
113 info->stride[0] = GST_ROUND_UP_4 (width * 3);
116 case GST_VIDEO_FORMAT_v210:
117 info->stride[0] = ((width + 47) / 48) * 128;
120 case GST_VIDEO_FORMAT_v216:
121 info->stride[0] = GST_ROUND_UP_8 (width * 4);
124 case GST_VIDEO_FORMAT_GRAY8:
125 case GST_VIDEO_FORMAT_Y800:
126 info->stride[0] = GST_ROUND_UP_4 (width);
129 case GST_VIDEO_FORMAT_GRAY16_BE:
130 case GST_VIDEO_FORMAT_GRAY16_LE:
131 case GST_VIDEO_FORMAT_Y16:
132 info->stride[0] = GST_ROUND_UP_4 (width * 2);
135 case GST_VIDEO_FORMAT_UYVP:
136 info->stride[0] = GST_ROUND_UP_4 ((width * 2 * 5 + 3) / 4);
139 case GST_VIDEO_FORMAT_RGB8_PALETTED:
140 info->stride[0] = GST_ROUND_UP_4 (width);
143 case GST_VIDEO_FORMAT_IYU1:
144 info->stride[0] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) +
145 GST_ROUND_UP_4 (width) / 2);
148 case GST_VIDEO_FORMAT_ARGB64:
149 case GST_VIDEO_FORMAT_AYUV64:
150 info->stride[0] = width * 8;
153 case GST_VIDEO_FORMAT_I420:
154 info->stride[0] = GST_ROUND_UP_4 (width);
155 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
156 info->stride[2] = info->stride[1];
158 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
159 info->offset[2] = info->offset[1] +
160 info->stride[1] * (GST_ROUND_UP_2 (height) / 2);
162 case GST_VIDEO_FORMAT_YV12: /* same as I420, but plane 1+2 swapped */
163 info->stride[0] = GST_ROUND_UP_4 (width);
164 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
165 info->stride[2] = info->stride[1];
167 info->offset[2] = info->stride[0] * GST_ROUND_UP_2 (height);
168 info->offset[1] = info->offset[2] +
169 info->stride[1] * (GST_ROUND_UP_2 (height) / 2);
171 case GST_VIDEO_FORMAT_Y41B:
172 info->stride[0] = GST_ROUND_UP_4 (width);
173 info->stride[1] = GST_ROUND_UP_16 (width) / 4;
174 info->stride[2] = info->stride[1];
176 info->offset[1] = info->stride[0] * height;
177 info->offset[2] = info->offset[1] + info->stride[1] * height;
178 /* simplification of ROUNDUP4(w)*h + 2*((ROUNDUP16(w)/4)*h */
180 case GST_VIDEO_FORMAT_Y42B:
181 info->stride[0] = GST_ROUND_UP_4 (width);
182 info->stride[1] = GST_ROUND_UP_8 (width) / 2;
183 info->stride[2] = info->stride[1];
185 info->offset[1] = info->stride[0] * height;
186 info->offset[2] = info->offset[1] + info->stride[1] * height;
187 /* simplification of ROUNDUP4(w)*h + 2*(ROUNDUP8(w)/2)*h */
189 case GST_VIDEO_FORMAT_Y444:
190 info->stride[0] = GST_ROUND_UP_4 (width);
191 info->stride[1] = info->stride[0];
192 info->stride[2] = info->stride[0];
194 info->offset[1] = info->stride[0] * height;
195 info->offset[2] = info->offset[1] * 2;
197 case GST_VIDEO_FORMAT_NV12:
198 case GST_VIDEO_FORMAT_NV21:
199 info->stride[0] = GST_ROUND_UP_4 (width);
200 info->stride[1] = info->stride[0];
202 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
204 case GST_VIDEO_FORMAT_A420:
205 info->stride[0] = GST_ROUND_UP_4 (width);
206 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
207 info->stride[2] = info->stride[1];
208 info->stride[3] = info->stride[0];
210 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
211 info->offset[2] = info->offset[1] +
212 info->stride[1] * (GST_ROUND_UP_2 (height) / 2);
213 info->offset[3] = info->offset[2] +
214 info->stride[2] * (GST_ROUND_UP_2 (height) / 2);
216 case GST_VIDEO_FORMAT_YUV9:
217 info->stride[0] = GST_ROUND_UP_4 (width);
218 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4);
219 info->stride[2] = info->stride[1];
221 info->offset[1] = info->stride[0] * height;
222 info->offset[2] = info->offset[1] +
223 info->stride[1] * (GST_ROUND_UP_4 (height) / 4);
225 case GST_VIDEO_FORMAT_YVU9:
226 info->stride[0] = GST_ROUND_UP_4 (width);
227 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4);
228 info->stride[2] = info->stride[1];
230 info->offset[2] = info->stride[0] * height;
231 info->offset[1] = info->offset[2] +
232 info->stride[1] * (GST_ROUND_UP_4 (height) / 4);
234 case GST_VIDEO_FORMAT_UNKNOWN:
235 GST_ERROR ("invalid format");
236 g_warning ("invalid format");
244 GstVideoFormat format;
245 void (*getline) (guint8 * dest, const GstBlendVideoFormatInfo * src,
247 void (*putline) (GstBlendVideoFormatInfo * dest,
248 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff,
250 void (*matrix) (guint8 * tmpline, guint width);
254 #define GET_LINE(info, comp, line) \
255 (info)->pixels + info->offset[(comp)] + ((info)->stride[(comp)] * (line))
257 /* Line conversion to AYUV */
259 /* Supports YV12 as well */
261 getline_I420 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
264 cogorc_getline_I420 (dest,
265 GET_LINE (src, 0, j) + xoff,
266 GET_LINE (src, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2),
267 GET_LINE (src, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2), src->width);
270 /* Supports YV12 as well */
272 putline_I420 (GstBlendVideoFormatInfo * dest,
273 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
275 cogorc_putline_I420 (GET_LINE (dest, 0, j) + xoff,
276 GET_LINE (dest, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2),
277 GET_LINE (dest, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2),
278 line, srcinfo->width / 2);
282 getline_YUY2 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
285 cogorc_getline_YUY2 (dest, GET_LINE (src, 0, j) +
286 (GST_ROUND_UP_2 (xoff * 4) / 2), src->width / 2);
290 putline_YUY2 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
291 const guint8 * line, guint xoff, int j)
293 cogorc_putline_YUY2 (GET_LINE (dest, 0,
294 j) + (GST_ROUND_UP_2 (xoff * 4) / 2), line, srcinfo->width / 2);
299 getline_AYUV (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
302 memcpy (dest, GET_LINE (src, 0, j) + (xoff * 4), (src->width - xoff) * 4);
306 putline_AYUV (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
307 const guint8 * line, guint xoff, int j)
309 memcpy (GET_LINE (dest, 0, j) + (xoff * 4), line, srcinfo->width * 4);
313 getline_UYVY (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
316 cogorc_getline_UYVY (dest, GET_LINE (src, 0, j) + xoff * 2, src->width / 2);
320 putline_UYVY (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
321 const guint8 * line, guint xoff, int j)
323 cogorc_putline_UYVY (GET_LINE (dest, 0, j) +
324 (GST_ROUND_UP_2 (xoff * 4) / 2), line, srcinfo->width / 2);
328 getline_v308 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
332 const guint8 *srcline = GET_LINE (src, 0, j) + GST_ROUND_UP_2 (xoff * 3);
334 for (i = 0; i < src->width; i++) {
335 dest[i * 4 + 0] = 0xff;
336 dest[i * 4 + 1] = srcline[i * 3 + 0];
337 dest[i * 4 + 2] = srcline[i * 3 + 1];
338 dest[i * 4 + 3] = srcline[i * 3 + 2];
343 putline_v308 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
344 const guint8 * line, guint xoff, int j)
347 guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 (xoff * 3);
349 for (i = 0; i < srcinfo->width; i++) {
350 destline[i * 3 + 0] = line[i * 4 + 1];
351 destline[i * 3 + 1] = line[i * 4 + 2];
352 destline[i * 3 + 2] = line[i * 4 + 3];
357 getline_v210 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
361 const guint8 *srcline = GET_LINE (src, 0, j) + GST_ROUND_UP_2 (xoff * 4) / 5;
363 for (i = 0; i < src->width; i += 6) {
364 guint32 a0, a1, a2, a3;
365 guint16 y0, y1, y2, y3, y4, y5;
369 a0 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 0);
370 a1 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 4);
371 a2 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 8);
372 a3 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 12);
374 u0 = ((a0 >> 0) & 0x3ff) >> 2;
375 y0 = ((a0 >> 10) & 0x3ff) >> 2;
376 v0 = ((a0 >> 20) & 0x3ff) >> 2;
377 y1 = ((a1 >> 0) & 0x3ff) >> 2;
379 u2 = ((a1 >> 10) & 0x3ff) >> 2;
380 y2 = ((a1 >> 20) & 0x3ff) >> 2;
381 v2 = ((a2 >> 0) & 0x3ff) >> 2;
382 y3 = ((a2 >> 10) & 0x3ff) >> 2;
384 u4 = ((a2 >> 20) & 0x3ff) >> 2;
385 y4 = ((a3 >> 0) & 0x3ff) >> 2;
386 v4 = ((a3 >> 10) & 0x3ff) >> 2;
387 y5 = ((a3 >> 20) & 0x3ff) >> 2;
389 dest[4 * (i + 0) + 0] = 0xff;
390 dest[4 * (i + 0) + 1] = y0;
391 dest[4 * (i + 0) + 2] = u0;
392 dest[4 * (i + 0) + 3] = v0;
394 dest[4 * (i + 1) + 0] = 0xff;
395 dest[4 * (i + 1) + 1] = y1;
396 dest[4 * (i + 1) + 2] = u0;
397 dest[4 * (i + 1) + 3] = v0;
399 dest[4 * (i + 2) + 0] = 0xff;
400 dest[4 * (i + 2) + 1] = y2;
401 dest[4 * (i + 2) + 2] = u2;
402 dest[4 * (i + 2) + 3] = v2;
404 dest[4 * (i + 3) + 0] = 0xff;
405 dest[4 * (i + 3) + 1] = y3;
406 dest[4 * (i + 3) + 2] = u2;
407 dest[4 * (i + 3) + 3] = v2;
409 dest[4 * (i + 4) + 0] = 0xff;
410 dest[4 * (i + 4) + 1] = y4;
411 dest[4 * (i + 4) + 2] = u4;
412 dest[4 * (i + 4) + 3] = v4;
414 dest[4 * (i + 5) + 0] = 0xff;
415 dest[4 * (i + 5) + 1] = y5;
416 dest[4 * (i + 5) + 2] = u4;
417 dest[4 * (i + 5) + 3] = v4;
424 putline_v210 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
425 const guint8 * line, guint xoff, int j)
428 guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 (xoff * 4) / 5;
431 for (i = 0; i < srcinfo->width + 5; i += 6) {
432 guint32 a0, a1, a2, a3;
433 guint16 y0, y1, y2, y3, y4, y5;
437 y0 = line[4 * (i + 0) + 1] << 2;
438 y1 = line[4 * (i + 1) + 1] << 2;
439 y2 = line[4 * (i + 2) + 1] << 2;
440 y3 = line[4 * (i + 3) + 1] << 2;
441 y4 = line[4 * (i + 4) + 1] << 2;
442 y5 = line[4 * (i + 5) + 1] << 2;
444 u0 = (line[4 * (i + 0) + 2] + line[4 * (i + 1) + 2]) << 1;
445 u1 = (line[4 * (i + 2) + 2] + line[4 * (i + 3) + 2]) << 1;
446 u2 = (line[4 * (i + 4) + 2] + line[4 * (i + 5) + 2]) << 1;
448 v0 = (line[4 * (i + 0) + 3] + line[4 * (i + 1) + 3]) << 1;
449 v1 = (line[4 * (i + 2) + 3] + line[4 * (i + 3) + 3]) << 1;
450 v2 = (line[4 * (i + 4) + 3] + line[4 * (i + 5) + 3]) << 1;
452 a0 = u0 | (y0 << 10) | (v0 << 20);
453 a1 = y1 | (u1 << 10) | (y2 << 20);
454 a2 = v1 | (y3 << 10) | (u2 << 20);
455 a3 = y4 | (v2 << 10) | (y5 << 20);
457 GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 0, a0);
458 GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 4, a1);
459 GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 8, a2);
460 GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 12, a3);
465 getline_v216 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
469 const guint8 *srcline = GET_LINE (src, 0, j) + GST_ROUND_UP_2 (xoff + 3);
471 for (i = 0; i < src->width; i++) {
472 dest[i * 4 + 0] = 0xff;
473 dest[i * 4 + 1] = GST_READ_UINT16_LE (srcline + i * 4 + 2) >> 8;
474 dest[i * 4 + 2] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 0) >> 8;
475 dest[i * 4 + 3] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 4) >> 8;
480 putline_v216 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
481 const guint8 * line, guint xoff, int j)
484 guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 (xoff + 3);
486 for (i = 0; i < srcinfo->width / 2; i++) {
487 GST_WRITE_UINT16_LE (destline + i * 8 + 0, line[(i * 2 + 0) * 4 + 2] << 8);
488 GST_WRITE_UINT16_LE (destline + i * 8 + 2, line[(i * 2 + 0) * 4 + 1] << 8);
489 GST_WRITE_UINT16_LE (destline + i * 8 + 4, line[(i * 2 + 1) * 4 + 3] << 8);
490 GST_WRITE_UINT16_LE (destline + i * 8 + 8, line[(i * 2 + 0) * 4 + 1] << 8);
495 getline_Y41B (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
498 cogorc_getline_YUV9 (dest,
499 GET_LINE (src, 0, j) + xoff,
500 GET_LINE (src, 1, j) + (xoff / 4), GET_LINE (src, 2, j) + (xoff / 4),
505 putline_Y41B (GstBlendVideoFormatInfo * dest,
506 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
509 guint8 *destlineY = GET_LINE (dest, 0, j) + xoff;
510 guint8 *destlineU = GET_LINE (dest, 1, j) + (xoff / 4);
511 guint8 *destlineV = GET_LINE (dest, 2, j) + (xoff / 4);
513 for (i = 0; i < srcinfo->width - 3; i += 4) {
514 destlineY[i] = line[i * 4 + 1];
515 destlineY[i + 1] = line[i * 4 + 5];
516 destlineY[i + 2] = line[i * 4 + 9];
517 destlineY[i + 3] = line[i * 4 + 13];
520 (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + line[i * 4 +
523 (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + line[i * 4 +
527 if (i == srcinfo->width - 3) {
528 destlineY[i] = line[i * 4 + 1];
529 destlineY[i + 1] = line[i * 4 + 5];
530 destlineY[i + 2] = line[i * 4 + 9];
533 (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + 1) / 3;
535 (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + 1) / 3;
536 } else if (i == srcinfo->width - 2) {
537 destlineY[i] = line[i * 4 + 1];
538 destlineY[i + 1] = line[i * 4 + 5];
540 destlineU[i >> 2] = (line[i * 4 + 2] + line[i * 4 + 6] + 1) >> 1;
541 destlineV[i >> 2] = (line[i * 4 + 3] + line[i * 4 + 7] + 1) >> 1;
542 } else if (i == srcinfo->width - 1) {
543 destlineY[i + 1] = line[i * 4 + 5];
545 destlineU[i >> 2] = line[i * 4 + 2];
546 destlineV[i >> 2] = line[i * 4 + 3];
551 getline_Y42B (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
554 cogorc_getline_Y42B (dest,
555 GET_LINE (src, 0, j) + xoff,
556 GET_LINE (src, 1, j) + GST_ROUND_UP_2 (xoff / 2),
557 GET_LINE (src, 2, j) + GST_ROUND_UP_2 (xoff / 2), src->width / 2);
561 putline_Y42B (GstBlendVideoFormatInfo * dest,
562 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
564 cogorc_putline_Y42B (GET_LINE (dest, 0, j) + xoff,
565 GET_LINE (dest, 1, j) + GST_ROUND_UP_2 (xoff / 2),
566 GET_LINE (dest, 2, j) + GST_ROUND_UP_2 (xoff / 2), line,
571 getline_Y444 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
574 cogorc_getline_Y444 (dest,
575 GET_LINE (src, 0, j) + xoff,
576 GET_LINE (src, 1, j) + xoff, GET_LINE (src, 2, j) + xoff, src->width);
580 putline_Y444 (GstBlendVideoFormatInfo * dest,
581 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
583 cogorc_putline_Y444 (GET_LINE (dest, 0, j) + xoff,
584 GET_LINE (dest, 1, j) + xoff,
585 GET_LINE (dest, 2, j) + xoff, line, srcinfo->width);
589 getline_Y800 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
592 cogorc_getline_Y800 (dest, GET_LINE (src, 0, j) + xoff, src->width);
596 putline_Y800 (GstBlendVideoFormatInfo * dest,
597 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
599 cogorc_putline_Y800 (GET_LINE (dest, 0, j) + xoff, line, srcinfo->width);
603 getline_Y16 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
606 cogorc_getline_Y16 (dest, GET_LINE (src, 0, j) + xoff * 2, src->width);
610 putline_Y16 (GstBlendVideoFormatInfo * dest,
611 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
613 cogorc_putline_Y16 (GET_LINE (dest, 0, j) + xoff * 2, line, srcinfo->width);
617 getline_NV12 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
620 cogorc_getline_NV12 (dest,
621 GET_LINE (src, 0, j) + xoff,
622 GET_LINE (src, 1, j >> 1) + xoff, src->width / 2);
626 putline_NV12 (GstBlendVideoFormatInfo * dest,
627 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
629 cogorc_putline_NV12 (GET_LINE (dest, 0, j) + xoff,
630 GET_LINE (dest, 1, j >> 1) + xoff, line, srcinfo->width / 2);
634 getline_NV21 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
637 cogorc_getline_NV21 (dest,
638 GET_LINE (src, 0, j) + xoff,
639 GET_LINE (src, 1, j >> 1) + xoff, src->width / 2);
643 putline_NV21 (GstBlendVideoFormatInfo * dest,
644 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
646 cogorc_putline_NV21 (GET_LINE (dest, 0, j) + xoff,
647 GET_LINE (dest, 1, j >> 1) + xoff, line, srcinfo->width / 2);
651 getline_UYVP (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
655 const guint8 *srcline = GET_LINE (src, 0, j)
658 for (i = 0; i < src->width; i += 2) {
663 u0 = (srcline[(i / 2) * 5 + 0] << 2) | (srcline[(i / 2) * 5 + 1] >> 6);
665 y0 = ((srcline[(i / 2) * 5 + 1] & 0x3f) << 4) |
666 (srcline[(i / 2) * 5 + 2] >> 4);
668 v0 = ((srcline[(i / 2) * 5 + 2] & 0x0f) << 6) |
669 (srcline[(i / 2) * 5 + 3] >> 2);
671 y1 = ((srcline[(i / 2) * 5 + 3] & 0x03) << 8) | srcline[(i / 2) * 5 + 4];
673 dest[i * 4 + 0] = 0xff;
674 dest[i * 4 + 1] = y0 >> 2;
675 dest[i * 4 + 2] = u0 >> 2;
676 dest[i * 4 + 3] = v0 >> 2;
677 dest[i * 4 + 4] = 0xff;
678 dest[i * 4 + 5] = y1 >> 2;
679 dest[i * 4 + 6] = u0 >> 2;
680 dest[i * 4 + 7] = v0 >> 2;
685 putline_UYVP (GstBlendVideoFormatInfo * dest,
686 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
689 guint8 *destline = GET_LINE (dest, 0, j) + xoff * 3;
691 for (i = 0; i < srcinfo->width; i += 2) {
696 y0 = line[4 * (i + 0) + 1];
697 y1 = line[4 * (i + 1) + 1];
698 u0 = (line[4 * (i + 0) + 2] + line[4 * (i + 1) + 2] + 1) >> 1;
699 v0 = (line[4 * (i + 0) + 3] + line[4 * (i + 1) + 3] + 1) >> 1;
701 destline[(i / 2) * 5 + 0] = u0;
702 destline[(i / 2) * 5 + 1] = y0 >> 2;
703 destline[(i / 2) * 5 + 2] = (y0 << 6) | (v0 >> 4);
704 destline[(i / 2) * 5 + 3] = (v0 << 4) | (y1 >> 2);
705 destline[(i / 2) * 5 + 4] = (y1 << 2);
710 getline_A420 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
713 cogorc_getline_A420 (dest,
714 GET_LINE (src, 0, j) + xoff,
715 GET_LINE (src, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2),
716 GET_LINE (src, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2),
717 GET_LINE (src, 3, j) + GST_ROUND_UP_2 (xoff / 2), src->width);
721 putline_A420 (GstBlendVideoFormatInfo * dest,
722 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
724 cogorc_putline_A420 (GET_LINE (dest, 0, j) + xoff,
725 GET_LINE (dest, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2),
726 GET_LINE (dest, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2),
727 GET_LINE (dest, 3, j) + GST_ROUND_UP_2 (xoff / 2), line,
732 getline_YUV9 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
735 cogorc_getline_YUV9 (dest,
736 GET_LINE (src, 0, j) + xoff,
737 GET_LINE (src, 1, j >> 2) + GST_ROUND_UP_4 (xoff / 4),
738 GET_LINE (src, 2, j >> 2) + GST_ROUND_UP_4 (xoff / 4), src->width / 2);
742 putline_YUV9 (GstBlendVideoFormatInfo * dest,
743 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
746 guint8 *destY = GET_LINE (dest, 0, j) + xoff;
747 guint8 *destU = GET_LINE (dest, 1, j >> 2) + GST_ROUND_UP_4 (xoff / 4);
748 guint8 *destV = GET_LINE (dest, 2, j >> 2) + GST_ROUND_UP_4 (xoff / 4);
749 guint width = srcinfo->width;
751 for (i = 0; i < width - 3; i += 4) {
752 destY[i] = line[i * 4 + 1];
753 destY[i + 1] = line[i * 4 + 5];
754 destY[i + 2] = line[i * 4 + 9];
755 destY[i + 3] = line[i * 4 + 13];
758 (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + line[i * 4 +
761 (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + line[i * 4 +
766 if (i == width - 3) {
767 destY[i] = line[i * 4 + 1];
768 destY[i + 1] = line[i * 4 + 5];
769 destY[i + 2] = line[i * 4 + 9];
772 (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10]) / 3;
774 (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11]) / 3;
776 } else if (i == width - 2) {
777 destY[i] = line[i * 4 + 1];
778 destY[i + 1] = line[i * 4 + 5];
780 destU[i >> 2] = (line[i * 4 + 2] + line[i * 4 + 6]) >> 1;
781 destV[i >> 2] = (line[i * 4 + 3] + line[i * 4 + 7]) >> 1;
783 } else if (i == width - 1) {
784 destY[i] = line[i * 4 + 1];
785 destU[i >> 2] = line[i * 4 + 2];
786 destV[i >> 2] = line[i * 4 + 3];
791 getline_IYU1 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
795 const guint8 *srcline =
796 GET_LINE (src, 0, j) + GST_ROUND_UP_2 ((xoff * 3) / 2);
797 guint width = src->width;
799 for (i = 0; i < width - 3; i += 4) {
800 dest[i * 4 + 0] = 0xff;
801 dest[i * 4 + 4] = 0xff;
802 dest[i * 4 + 8] = 0xff;
803 dest[i * 4 + 12] = 0xff;
804 dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1];
805 dest[i * 4 + 5] = srcline[(i >> 2) * 6 + 2];
806 dest[i * 4 + 9] = srcline[(i >> 2) * 6 + 4];
807 dest[i * 4 + 13] = srcline[(i >> 2) * 6 + 5];
808 dest[i * 4 + 2] = dest[i * 4 + 6] = dest[i * 4 + 10] = dest[i * 4 + 14] =
809 srcline[(i >> 2) * 6 + 0];
810 dest[i * 4 + 3] = dest[i * 4 + 7] = dest[i * 4 + 11] = dest[i * 4 + 15] =
811 srcline[(i >> 2) * 6 + 3];
814 if (i == width - 3) {
815 dest[i * 4 + 0] = 0xff;
816 dest[i * 4 + 4] = 0xff;
817 dest[i * 4 + 8] = 0xff;
818 dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1];
819 dest[i * 4 + 5] = srcline[(i >> 2) * 6 + 2];
820 dest[i * 4 + 9] = srcline[(i >> 2) * 6 + 4];
821 dest[i * 4 + 2] = dest[i * 4 + 6] = dest[i * 4 + 10] =
822 srcline[(i >> 2) * 6 + 0];
823 dest[i * 4 + 3] = dest[i * 4 + 7] = dest[i * 4 + 11] =
824 srcline[(i >> 2) * 6 + 3];
825 } else if (i == width - 2) {
826 dest[i * 4 + 0] = 0xff;
827 dest[i * 4 + 4] = 0xff;
828 dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1];
829 dest[i * 4 + 5] = srcline[(i >> 2) * 6 + 2];
830 dest[i * 4 + 2] = dest[i * 4 + 6] = srcline[(i >> 2) * 6 + 0];
831 dest[i * 4 + 3] = dest[i * 4 + 7] = srcline[(i >> 2) * 6 + 3];
832 } else if (i == width - 1) {
833 dest[i * 4 + 0] = 0xff;
834 dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1];
835 dest[i * 4 + 2] = srcline[(i >> 2) * 6 + 0];
836 dest[i * 4 + 3] = srcline[(i >> 2) * 6 + 3];
841 putline_IYU1 (GstBlendVideoFormatInfo * dest,
842 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
845 guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 ((xoff * 3) / 2);
846 guint width = srcinfo->width;
848 for (i = 0; i < width - 3; i += 4) {
849 destline[(i >> 2) * 6 + 1] = line[i * 4 + 1];
850 destline[(i >> 2) * 6 + 2] = line[i * 4 + 5];
851 destline[(i >> 2) * 6 + 4] = line[i * 4 + 9];
852 destline[(i >> 2) * 6 + 5] = line[i * 4 + 13];
853 destline[(i >> 2) * 6 + 0] =
854 (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + line[i * 4 +
856 destline[(i >> 2) * 6 + 3] =
857 (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + line[i * 4 +
861 if (i == width - 3) {
862 destline[(i >> 2) * 6 + 1] = line[i * 4 + 1];
863 destline[(i >> 2) * 6 + 2] = line[i * 4 + 5];
864 destline[(i >> 2) * 6 + 4] = line[i * 4 + 9];
865 destline[(i >> 2) * 6 + 0] =
866 (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10]) / 3;
867 destline[(i >> 2) * 6 + 3] =
868 (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11]) / 3;
869 } else if (i == width - 2) {
870 destline[(i >> 2) * 6 + 1] = line[i * 4 + 1];
871 destline[(i >> 2) * 6 + 2] = line[i * 4 + 5];
872 destline[(i >> 2) * 6 + 0] = (line[i * 4 + 2] + line[i * 4 + 6]) >> 1;
873 destline[(i >> 2) * 6 + 3] = (line[i * 4 + 3] + line[i * 4 + 7]) >> 1;
874 } else if (i == width - 1) {
875 destline[(i >> 2) * 6 + 1] = line[i * 4 + 1];
876 destline[(i >> 2) * 6 + 0] = line[i * 4 + 2];
877 destline[(i >> 2) * 6 + 3] = line[i * 4 + 3];
882 /* Line conversion to ARGB */
884 getline_RGB (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
888 const guint8 *srcline = GET_LINE (src, 0, j) + xoff * 3;
890 for (i = 0; i < src->width; i++) {
891 dest[i * 4 + 0] = 0xff;
892 dest[i * 4 + 1] = srcline[i * 3 + 0];
893 dest[i * 4 + 2] = srcline[i * 3 + 1];
894 dest[i * 4 + 3] = srcline[i * 3 + 2];
899 putline_RGB (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
900 const guint8 * line, guint xoff, int j)
903 guint8 *destline = GET_LINE (dest, 0, j) + xoff * 3;
905 for (i = 0; i < srcinfo->width; i++) {
906 destline[i * 3 + 0] = line[i * 4 + 1];
907 destline[i * 3 + 1] = line[i * 4 + 2];
908 destline[i * 3 + 2] = line[i * 4 + 3];
913 getline_BGR (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
917 const guint8 *srcline = GET_LINE (src, 0, j) + xoff * 3;
919 for (i = 0; i < src->width; i++) {
920 dest[i * 4 + 0] = 0xff;
921 dest[i * 4 + 1] = srcline[i * 3 + 2];
922 dest[i * 4 + 2] = srcline[i * 3 + 1];
923 dest[i * 4 + 3] = srcline[i * 3 + 0];
928 putline_BGR (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
929 const guint8 * line, guint xoff, int j)
932 guint8 *destline = GET_LINE (dest, 0, j) + xoff * 3;
934 for (i = 0; i < srcinfo->width; i++) {
935 destline[i * 3 + 0] = line[i * 4 + 3];
936 destline[i * 3 + 1] = line[i * 4 + 2];
937 destline[i * 3 + 2] = line[i * 4 + 1];
942 getline_RGBA (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
945 cogorc_getline_RGBA (dest, GET_LINE (src, 0, j) + (4 * xoff), src->width);
949 putline_RGBA (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
950 const guint8 * line, guint xoff, int j)
952 cogorc_putline_RGBA (GET_LINE (dest, 0, j) + (4 * xoff),
953 line, srcinfo->width);
957 getline_ARGB (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
961 memcpy (dest, GET_LINE (src, 0, j), (src->width - xoff) * 4);
965 putline_ARGB (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo,
966 const guint8 * line, guint xoff, int j)
968 memcpy (GET_LINE (dest, 0, j) + (xoff * 4), line, srcinfo->width * 4);
972 getline_RGB16 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
976 const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j)
979 for (i = 0; i < src->width; i++) {
980 dest[i * 4 + 0] = 0xff;
981 dest[i * 4 + 1] = ((srcline[i] >> 11) & 0x1f) << 3;
982 dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x3f) << 2;
983 dest[i * 4 + 3] = ((srcline[i]) & 0x1f) << 3;
988 putline_RGB16 (GstBlendVideoFormatInfo * dest,
989 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
992 guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3);
994 for (i = 0; i < srcinfo->width; i++) {
995 destline[i] = ((line[i * 4 + 1] >> 3) << 11) | ((line[i * 4 +
996 2] >> 2) << 5) | (line[i * 4 + 3] >> 3);
1001 getline_RGB15 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
1005 const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j)
1008 for (i = 0; i < src->width; i++) {
1009 dest[i * 4 + 0] = 0xff;
1010 dest[i * 4 + 1] = ((srcline[i] >> 10) & 0x1f) << 3;
1011 dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x1f) << 3;
1012 dest[i * 4 + 3] = ((srcline[i]) & 0x1f) << 3;
1017 putline_RGB15 (GstBlendVideoFormatInfo * dest,
1018 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
1021 guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3);
1023 for (i = 0; i < srcinfo->width; i++) {
1024 destline[i] = ((line[i * 4 + 1] >> 3) << 10) | ((line[i * 4 +
1025 2] >> 3) << 5) | (line[i * 4 + 3] >> 3);
1030 getline_BGR15 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
1034 const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j)
1037 for (i = 0; i < src->width; i++) {
1038 dest[i * 4 + 0] = 0xff;
1039 dest[i * 4 + 3] = ((srcline[i] >> 10) & 0x1f) << 3;
1040 dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x1f) << 3;
1041 dest[i * 4 + 1] = ((srcline[i]) & 0x1f) << 3;
1046 putline_BGR15 (GstBlendVideoFormatInfo * dest,
1047 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
1050 guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3);
1052 for (i = 0; i < srcinfo->width; i++) {
1053 destline[i] = ((line[i * 4 + 3] >> 3) << 10) | ((line[i * 4 +
1054 2] >> 3) << 5) | (line[i * 4 + 1] >> 3);
1059 getline_BGR16 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
1063 const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j)
1066 for (i = 0; i < src->width; i++) {
1067 dest[i * 4 + 0] = 0xff;
1068 dest[i * 4 + 3] = ((srcline[i] >> 11) & 0x1f) << 3;
1069 dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x3f) << 2;
1070 dest[i * 4 + 1] = ((srcline[i]) & 0x1f) << 3;
1075 putline_BGR16 (GstBlendVideoFormatInfo * dest,
1076 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
1079 guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3);
1081 for (i = 0; i < srcinfo->width; i++) {
1082 destline[i] = ((line[i * 4 + 3] >> 3) << 11) | ((line[i * 4 +
1083 2] >> 2) << 5) | (line[i * 4 + 1] >> 3);
1088 getline_BGRA (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
1091 cogorc_getline_BGRA (dest, GET_LINE (src, 0, j) + xoff * 4, src->width);
1095 putline_BGRA (GstBlendVideoFormatInfo * dest,
1096 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
1098 cogorc_putline_BGRA (GET_LINE (dest, 0, j) + xoff * 4, line, srcinfo->width);
1102 getline_ABGR (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff,
1105 cogorc_getline_ABGR (dest, GET_LINE (src, 0, j) + (xoff * 4), src->width);
1109 putline_ABGR (GstBlendVideoFormatInfo * dest,
1110 GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j)
1112 cogorc_putline_ABGR (GET_LINE (dest, 0, j) + (xoff * 4),
1113 line, srcinfo->width);
1116 static const GetPutLine lines[] = {
1117 /* YUV lines conversion */
1118 {GST_VIDEO_FORMAT_I420, getline_I420, putline_I420},
1119 {GST_VIDEO_FORMAT_YV12, getline_I420, putline_I420},
1120 {GST_VIDEO_FORMAT_AYUV, getline_AYUV, putline_AYUV},
1121 {GST_VIDEO_FORMAT_YUY2, getline_YUY2, putline_YUY2},
1122 {GST_VIDEO_FORMAT_UYVY, getline_UYVY, putline_UYVY},
1123 {GST_VIDEO_FORMAT_v308, getline_v308, putline_v308},
1124 {GST_VIDEO_FORMAT_v210, getline_v210, putline_v210},
1125 {GST_VIDEO_FORMAT_v216, getline_v216, putline_v216},
1126 {GST_VIDEO_FORMAT_Y41B, getline_Y41B, putline_Y41B},
1127 {GST_VIDEO_FORMAT_Y42B, getline_Y42B, putline_Y42B},
1128 {GST_VIDEO_FORMAT_Y444, getline_Y444, putline_Y444},
1129 {GST_VIDEO_FORMAT_Y800, getline_Y800, putline_Y800},
1130 {GST_VIDEO_FORMAT_Y16, getline_Y16, putline_Y16},
1131 {GST_VIDEO_FORMAT_NV12, getline_NV12, putline_NV12},
1132 {GST_VIDEO_FORMAT_NV21, getline_NV21, putline_NV21},
1133 {GST_VIDEO_FORMAT_UYVP, getline_UYVP, putline_UYVP},
1134 {GST_VIDEO_FORMAT_A420, getline_A420, putline_A420},
1135 {GST_VIDEO_FORMAT_YUV9, getline_YUV9, putline_YUV9},
1136 {GST_VIDEO_FORMAT_IYU1, getline_IYU1, putline_IYU1},
1138 /* ARGB lines conversion */
1139 {GST_VIDEO_FORMAT_RGB, getline_RGB, putline_RGB},
1140 {GST_VIDEO_FORMAT_BGR, getline_BGR, putline_BGR},
1141 {GST_VIDEO_FORMAT_RGBx, getline_RGBA, putline_RGBA},
1142 {GST_VIDEO_FORMAT_RGBA, getline_RGBA, putline_RGBA},
1143 {GST_VIDEO_FORMAT_ARGB, getline_ARGB, putline_ARGB},
1144 {GST_VIDEO_FORMAT_RGB16, getline_RGB16, putline_RGB16},
1145 {GST_VIDEO_FORMAT_BGR16, getline_BGR16, putline_BGR16},
1146 {GST_VIDEO_FORMAT_BGR15, getline_BGR15, putline_BGR15},
1147 {GST_VIDEO_FORMAT_RGB15, getline_RGB15, putline_RGB15},
1148 {GST_VIDEO_FORMAT_BGRA, getline_BGRA, putline_BGRA},
1149 {GST_VIDEO_FORMAT_ABGR, getline_ABGR, putline_ABGR},
1150 {GST_VIDEO_FORMAT_BGRx, getline_BGRA, putline_BGRA}
1154 matrix_identity (guint8 * tmpline, guint width)
1159 matrix_rgb_to_yuv (guint8 * tmpline, guint width)
1165 for (i = 0; i < width; i++) {
1166 r = tmpline[i * 4 + 1];
1167 g = tmpline[i * 4 + 2];
1168 b = tmpline[i * 4 + 3];
1170 y = (47 * r + 157 * g + 16 * b + 4096) >> 8;
1171 u = (-26 * r - 87 * g + 112 * b + 32768) >> 8;
1172 v = (112 * r - 102 * g - 10 * b + 32768) >> 8;
1174 tmpline[i * 4 + 1] = CLAMP (y, 0, 255);
1175 tmpline[i * 4 + 2] = CLAMP (u, 0, 255);
1176 tmpline[i * 4 + 3] = CLAMP (v, 0, 255);
1181 matrix_yuv_to_rgb (guint8 * tmpline, guint width)
1187 for (i = 0; i < width; i++) {
1188 y = tmpline[i * 4 + 1];
1189 u = tmpline[i * 4 + 2];
1190 v = tmpline[i * 4 + 3];
1192 r = (298 * y + 459 * v - 63514) >> 8;
1193 g = (298 * y - 55 * u - 136 * v + 19681) >> 8;
1194 b = (298 * y + 541 * u - 73988) >> 8;
1196 tmpline[i * 4 + ARGB_R] = CLAMP (r, 0, 255);
1197 tmpline[i * 4 + ARGB_G] = CLAMP (g, 0, 255);
1198 tmpline[i * 4 + ARGB_B] = CLAMP (b, 0, 255);
1203 lookup_getput (GetPutLine * getput, GstVideoFormat fmt)
1207 getput->getline = NULL;
1208 getput->putline = NULL;
1209 getput->matrix = matrix_identity;
1211 for (i = 0; i < sizeof (lines) / sizeof (lines[0]); i++) {
1212 if (lines[i].format == fmt) {
1213 getput->getline = lines[i].getline;
1214 getput->putline = lines[i].putline;
1219 GST_WARNING ("Conversion from %i not supported", fmt);
1224 #define BLEND(ret, alpha, v0, v1) \
1226 ret = (v0 * alpha + v1 * (255 - alpha)) / 255; \
1230 video_blend_scale_linear_RGBA (GstBlendVideoFormatInfo * src,
1231 gint dest_height, gint dest_width)
1241 guint dest_stride = dest_width * 4;
1242 guint src_stride = src->width * 4;
1244 guint8 *tmpbuf = g_malloc (dest_width * 8 * 4);
1245 guint8 *dest_pixels =
1246 g_malloc (gst_video_format_get_size (src->fmt, dest_height,
1249 if (dest_height == 1)
1252 y_increment = ((src->height - 1) << 16) / (dest_height - 1) - 1;
1254 if (dest_width == 1)
1257 x_increment = ((src->width - 1) << 16) / (dest_width - 1) - 1;
1259 dest_size = dest_width * 4;
1261 #define LINE(x) ((tmpbuf) + (dest_size)*((x)&1))
1264 orc_resample_bilinear_u32 (LINE (0), src->pixels, 0, x_increment, dest_width);
1266 for (i = 0; i < dest_height; i++) {
1271 memcpy (dest_pixels + i * dest_stride, LINE (j), dest_size);
1274 orc_resample_bilinear_u32 (LINE (j),
1275 src->pixels + j * src_stride, 0, x_increment, dest_width);
1279 orc_resample_bilinear_u32 (LINE (j + 1),
1280 src->pixels + (j + 1) * src_stride, 0, x_increment, dest_width);
1283 orc_merge_linear_u8 (dest_pixels + i * dest_stride,
1284 LINE (j), LINE (j + 1), (x >> 8), dest_width * 4);
1290 /* Update src, our reference to the old src->pixels is lost */
1291 video_blend_format_info_init (src, dest_pixels, dest_height, dest_width,
1298 * @dest: The #GstBlendVideoFormatInfo where to blend @src in
1299 * @src: the #GstBlendVideoFormatInfo that we want to blend into
1301 * @x: The x offset in pixel where the @src image should be blended
1302 * @y: the y offset in pixel where the @src image should be blended
1304 * Lets you blend the @src image into the @dest image
1307 video_blend (GstBlendVideoFormatInfo * dest,
1308 GstBlendVideoFormatInfo * src, guint x, guint y)
1312 GetPutLine getputdest, getputsrc;
1314 gint src_stride = src->width * 4;
1315 guint8 *tmpdestline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4);
1316 guint8 *tmpsrcline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4);
1318 ensure_debug_category ();
1321 if (!lookup_getput (&getputdest, dest->fmt))
1324 if (!lookup_getput (&getputsrc, src->fmt))
1327 if (gst_video_format_is_rgb (src->fmt) != gst_video_format_is_rgb (dest->fmt))
1328 getputsrc.matrix = gst_video_format_is_rgb (src->fmt) ?
1329 matrix_rgb_to_yuv : matrix_yuv_to_rgb;
1331 /* adjust src pointers for negative sizes */
1339 src += -y * src_stride;
1344 /* adjust width/height if the src is bigger than dest */
1345 if (x + src->width > dest->width)
1346 src->width = dest->width - x;
1348 if (y + src->height > dest->height)
1349 src->height = dest->height - y;
1351 /* Mainloop doing the needed conversions, and blending */
1352 for (i = y; i < y + src->height; i++) {
1354 getputdest.getline (tmpdestline, dest, x, i);
1355 getputsrc.getline (tmpsrcline, src, 0, (i - y));
1357 getputsrc.matrix (tmpsrcline, src->width);
1359 /* Here dest and src are both either in AYUV or ARGB
1360 * TODO: Make the orc version working properly*/
1361 for (j = 0; j < src->width * 4; j += 4) {
1362 alpha = tmpsrcline[j];
1364 BLEND (tmpdestline[j + 1], alpha, tmpsrcline[j + 1], tmpdestline[j + 1]);
1365 BLEND (tmpdestline[j + 2], alpha, tmpsrcline[j + 2], tmpdestline[j + 2]);
1366 BLEND (tmpdestline[j + 3], alpha, tmpsrcline[j + 3], tmpdestline[j + 3]);
1370 * #if G_BYTE_ORDER == LITTLE_ENDIAN
1371 * orc_blend_little (tmpdestline, tmpsrcline, dest->width);
1373 * orc_blend_big (tmpdestline, tmpsrcline, src->width);
1377 getputdest.putline (dest, src, tmpdestline, x, i);
1381 g_free (tmpdestline);
1382 g_free (tmpsrcline);
1387 GST_WARNING ("Could not do the blending");
1388 g_free (tmpdestline);
1389 g_free (tmpsrcline);
1394 /* video_blend_format_info_init:
1395 * @info: The #GstBlendVideoFormatInfo to initialize
1396 * @pixels: The pixels data in @fmt format
1397 * @height: The height of the image
1398 * @width: the width of the image
1399 * @fmt: The #GstVideoFormat of the image
1401 * Initializes a GstBlendVideoFormatInfo.
1402 * This function can be called on already initialized instances.
1405 video_blend_format_info_init (GstBlendVideoFormatInfo * info,
1406 guint8 * pixels, guint height, guint width, GstVideoFormat fmt)
1408 guint nb_component = gst_video_format_has_alpha (fmt) ? 4 : 3;
1410 ensure_debug_category ();
1413 ("Initializing video bleding info, height %i, width %i, fmt %i nb_component %i",
1414 height, width, fmt, nb_component);
1416 info->width = width;
1417 info->height = height;
1418 info->pixels = pixels;
1420 info->size = gst_video_format_get_size (fmt, height, width);