2 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
3 * Copyright (C) 2006 Mindfruit Bv.
4 * Author: Sjoerd Simons <sjoerd@luon.net>
5 * Author: Alex Ugarte <alexugarte@gmail.com>
6 * Copyright (C) 2009 Alex Ugarte <augarte@vicomtech.org>
7 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
30 #include "compositororc.h"
34 #include <gst/video/video.h>
36 GST_DEBUG_CATEGORY_STATIC (gst_compositor_blend_debug);
37 #define GST_CAT_DEFAULT gst_compositor_blend_debug
39 /* Below are the implementations of everything */
41 /* A32 is for AYUV, ARGB and BGRA */
42 #define BLEND_A32(name, method, LOOP) \
44 method##_ ##name (GstVideoFrame * srcframe, gint xpos, gint ypos, \
45 gdouble src_alpha, GstVideoFrame * destframe, GstCompositorBlendMode mode) \
48 gint src_stride, dest_stride; \
49 gint dest_width, dest_height; \
51 gint src_width, src_height; \
53 src_width = GST_VIDEO_FRAME_WIDTH (srcframe); \
54 src_height = GST_VIDEO_FRAME_HEIGHT (srcframe); \
55 src = GST_VIDEO_FRAME_PLANE_DATA (srcframe, 0); \
56 src_stride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 0); \
57 dest = GST_VIDEO_FRAME_PLANE_DATA (destframe, 0); \
58 dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 0); \
59 dest_width = GST_VIDEO_FRAME_COMP_WIDTH (destframe, 0); \
60 dest_height = GST_VIDEO_FRAME_COMP_HEIGHT (destframe, 0); \
62 s_alpha = CLAMP ((gint) (src_alpha * 255), 0, 255); \
64 /* If it's completely transparent... we just return */ \
65 if (G_UNLIKELY (s_alpha == 0)) \
68 /* adjust src pointers for negative sizes */ \
75 src += -ypos * src_stride; \
76 src_height -= -ypos; \
79 /* adjust width/height if the src is bigger than dest */ \
80 if (xpos + src_width > dest_width) { \
81 src_width = dest_width - xpos; \
83 if (ypos + src_height > dest_height) { \
84 src_height = dest_height - ypos; \
87 if (src_height > 0 && src_width > 0) { \
88 dest = dest + 4 * xpos + (ypos * dest_stride); \
90 LOOP (dest, src, src_height, src_width, src_stride, dest_stride, s_alpha, \
95 #define OVERLAY_A32_LOOP(name) \
97 _overlay_loop_##name (guint8 * dest, const guint8 * src, gint src_height, \
98 gint src_width, gint src_stride, gint dest_stride, guint s_alpha, \
99 GstCompositorBlendMode mode) \
101 s_alpha = MIN (255, s_alpha); \
103 case COMPOSITOR_BLEND_MODE_SOURCE:\
104 compositor_orc_source_##name (dest, dest_stride, src, src_stride, \
105 s_alpha, src_width, src_height); \
107 case COMPOSITOR_BLEND_MODE_OVER:\
108 compositor_orc_overlay_##name (dest, dest_stride, src, src_stride, \
109 s_alpha, src_width, src_height); \
111 case COMPOSITOR_BLEND_MODE_ADD:\
112 compositor_orc_overlay_##name##_addition (dest, dest_stride, src, src_stride, \
113 s_alpha, src_width, src_height); \
118 #define BLEND_A32_LOOP(name) \
120 _blend_loop_##name (guint8 * dest, const guint8 * src, gint src_height, \
121 gint src_width, gint src_stride, gint dest_stride, guint s_alpha, \
122 GstCompositorBlendMode mode) \
124 s_alpha = MIN (255, s_alpha); \
126 case COMPOSITOR_BLEND_MODE_SOURCE:\
127 compositor_orc_source_##name (dest, dest_stride, src, src_stride, \
128 s_alpha, src_width, src_height); \
130 case COMPOSITOR_BLEND_MODE_OVER:\
131 case COMPOSITOR_BLEND_MODE_ADD:\
132 /* both modes are the same for opaque background */ \
133 compositor_orc_blend_##name (dest, dest_stride, src, src_stride, \
134 s_alpha, src_width, src_height); \
139 OVERLAY_A32_LOOP (argb);
140 OVERLAY_A32_LOOP (bgra);
141 BLEND_A32_LOOP (argb);
142 BLEND_A32_LOOP (bgra);
144 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
145 BLEND_A32 (argb, blend, _blend_loop_argb);
146 BLEND_A32 (bgra, blend, _blend_loop_bgra);
147 BLEND_A32 (argb, overlay, _overlay_loop_argb);
148 BLEND_A32 (bgra, overlay, _overlay_loop_bgra);
150 BLEND_A32 (argb, blend, _blend_loop_bgra);
151 BLEND_A32 (bgra, blend, _blend_loop_argb);
152 BLEND_A32 (argb, overlay, _overlay_loop_bgra);
153 BLEND_A32 (bgra, overlay, _overlay_loop_argb);
156 #define A32_CHECKER_C(name, RGB, A, C1, C2, C3) \
158 fill_checker_##name##_c (GstVideoFrame * frame) \
162 static const gint tab[] = { 80, 160, 80, 160 }; \
163 gint width, height; \
166 dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
167 width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0); \
168 height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0); \
171 for (i = 0; i < height; i++) { \
172 for (j = 0; j < width; j++) { \
174 dest[C1] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \
181 for (i = 0; i < height; i++) { \
182 for (j = 0; j < width; j++) { \
183 val = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \
194 A32_CHECKER_C (argb, TRUE, 0, 1, 2, 3);
195 A32_CHECKER_C (bgra, TRUE, 3, 2, 1, 0);
196 A32_CHECKER_C (ayuv, FALSE, 0, 1, 2, 3);
198 #define YUV_TO_R(Y,U,V) (CLAMP (1.164 * (Y - 16) + 1.596 * (V - 128), 0, 255))
199 #define YUV_TO_G(Y,U,V) (CLAMP (1.164 * (Y - 16) - 0.813 * (V - 128) - 0.391 * (U - 128), 0, 255))
200 #define YUV_TO_B(Y,U,V) (CLAMP (1.164 * (Y - 16) + 2.018 * (U - 128), 0, 255))
202 #define A32_COLOR(name, RGB, A, C1, C2, C3) \
204 fill_color_##name (GstVideoFrame * frame, gint Y, gint U, gint V) \
208 gint width, height; \
211 dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
212 width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0); \
213 height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0); \
216 c1 = YUV_TO_R (Y, U, V); \
217 c2 = YUV_TO_G (Y, U, V); \
218 c3 = YUV_TO_B (Y, U, V); \
224 val = GUINT32_FROM_BE ((0xff << A) | (c1 << C1) | (c2 << C2) | (c3 << C3)); \
226 compositor_orc_splat_u32 ((guint32 *) dest, val, height * width); \
229 A32_COLOR (argb, TRUE, 24, 16, 8, 0);
230 A32_COLOR (bgra, TRUE, 0, 8, 16, 24);
231 A32_COLOR (abgr, TRUE, 24, 0, 8, 16);
232 A32_COLOR (rgba, TRUE, 0, 24, 16, 8);
233 A32_COLOR (ayuv, FALSE, 24, 16, 8, 0);
235 /* Y444, Y42B, I420, YV12, Y41B */
236 #define PLANAR_YUV_BLEND(format_name,format_enum,x_round,y_round,MEMCPY,BLENDLOOP) \
238 _blend_##format_name (const guint8 * src, guint8 * dest, \
239 gint src_stride, gint dest_stride, gint src_width, gint src_height, \
240 gdouble src_alpha, GstCompositorBlendMode mode) \
245 /* in source mode we just have to copy over things */ \
246 if (mode == COMPOSITOR_BLEND_MODE_SOURCE) { \
250 /* If it's completely transparent... we just return */ \
251 if (G_UNLIKELY (src_alpha == 0.0)) { \
252 GST_INFO ("Fast copy (alpha == 0.0)"); \
256 /* If it's completely opaque, we do a fast copy */ \
257 if (G_UNLIKELY (src_alpha == 1.0)) { \
258 GST_INFO ("Fast copy (alpha == 1.0)"); \
259 for (i = 0; i < src_height; i++) { \
260 MEMCPY (dest, src, src_width); \
262 dest += dest_stride; \
267 b_alpha = CLAMP ((gint) (src_alpha * 255), 0, 255); \
269 BLENDLOOP(dest, dest_stride, src, src_stride, b_alpha, src_width, src_height);\
273 blend_##format_name (GstVideoFrame * srcframe, gint xpos, gint ypos, \
274 gdouble src_alpha, GstVideoFrame * destframe, GstCompositorBlendMode mode) \
276 const guint8 *b_src; \
282 gint src_comp_rowstride, dest_comp_rowstride; \
283 gint src_comp_height; \
284 gint src_comp_width; \
285 gint comp_ypos, comp_xpos; \
286 gint comp_yoffset, comp_xoffset; \
287 gint dest_width, dest_height; \
288 const GstVideoFormatInfo *info; \
289 gint src_width, src_height; \
291 src_width = GST_VIDEO_FRAME_WIDTH (srcframe); \
292 src_height = GST_VIDEO_FRAME_HEIGHT (srcframe); \
294 info = srcframe->info.finfo; \
295 dest_width = GST_VIDEO_FRAME_WIDTH (destframe); \
296 dest_height = GST_VIDEO_FRAME_HEIGHT (destframe); \
298 xpos = x_round (xpos); \
299 ypos = y_round (ypos); \
301 b_src_width = src_width; \
302 b_src_height = src_height; \
304 /* adjust src pointers for negative sizes */ \
307 b_src_width -= -xpos; \
312 b_src_height -= -ypos; \
315 /* If x or y offset are larger then the source it's outside of the picture */ \
316 if (xoffset >= src_width || yoffset >= src_height) { \
320 /* adjust width/height if the src is bigger than dest */ \
321 if (xpos + b_src_width > dest_width) { \
322 b_src_width = dest_width - xpos; \
324 if (ypos + b_src_height > dest_height) { \
325 b_src_height = dest_height - ypos; \
327 if (b_src_width <= 0 || b_src_height <= 0) { \
331 /* First mix Y, then U, then V */ \
332 b_src = GST_VIDEO_FRAME_COMP_DATA (srcframe, 0); \
333 b_dest = GST_VIDEO_FRAME_COMP_DATA (destframe, 0); \
334 src_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 0); \
335 dest_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 0); \
336 src_comp_width = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(info, 0, b_src_width); \
337 src_comp_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(info, 0, b_src_height); \
338 comp_xpos = (xpos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 0, xpos); \
339 comp_ypos = (ypos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 0, ypos); \
340 comp_xoffset = (xoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 0, xoffset); \
341 comp_yoffset = (yoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 0, yoffset); \
342 _blend_##format_name (b_src + comp_xoffset + comp_yoffset * src_comp_rowstride, \
343 b_dest + comp_xpos + comp_ypos * dest_comp_rowstride, \
344 src_comp_rowstride, \
345 dest_comp_rowstride, src_comp_width, src_comp_height, \
348 b_src = GST_VIDEO_FRAME_COMP_DATA (srcframe, 1); \
349 b_dest = GST_VIDEO_FRAME_COMP_DATA (destframe, 1); \
350 src_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 1); \
351 dest_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 1); \
352 src_comp_width = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(info, 1, b_src_width); \
353 src_comp_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(info, 1, b_src_height); \
354 comp_xpos = (xpos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 1, xpos); \
355 comp_ypos = (ypos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 1, ypos); \
356 comp_xoffset = (xoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 1, xoffset); \
357 comp_yoffset = (yoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 1, yoffset); \
358 _blend_##format_name (b_src + comp_xoffset + comp_yoffset * src_comp_rowstride, \
359 b_dest + comp_xpos + comp_ypos * dest_comp_rowstride, \
360 src_comp_rowstride, \
361 dest_comp_rowstride, src_comp_width, src_comp_height, \
364 b_src = GST_VIDEO_FRAME_COMP_DATA (srcframe, 2); \
365 b_dest = GST_VIDEO_FRAME_COMP_DATA (destframe, 2); \
366 src_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 2); \
367 dest_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 2); \
368 src_comp_width = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(info, 2, b_src_width); \
369 src_comp_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(info, 2, b_src_height); \
370 comp_xpos = (xpos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 2, xpos); \
371 comp_ypos = (ypos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 2, ypos); \
372 comp_xoffset = (xoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 2, xoffset); \
373 comp_yoffset = (yoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 2, yoffset); \
374 _blend_##format_name (b_src + comp_xoffset + comp_yoffset * src_comp_rowstride, \
375 b_dest + comp_xpos + comp_ypos * dest_comp_rowstride, \
376 src_comp_rowstride, \
377 dest_comp_rowstride, src_comp_width, src_comp_height, \
381 #define PLANAR_YUV_FILL_CHECKER(format_name, format_enum, MEMSET) \
383 fill_checker_##format_name (GstVideoFrame * frame) \
386 static const int tab[] = { 80, 160, 80, 160 }; \
388 gint comp_width, comp_height; \
391 p = GST_VIDEO_FRAME_COMP_DATA (frame, 0); \
392 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0); \
393 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0); \
394 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
396 for (i = 0; i < comp_height; i++) { \
397 for (j = 0; j < comp_width; j++) { \
398 *p++ = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \
400 p += rowstride - comp_width; \
403 p = GST_VIDEO_FRAME_COMP_DATA (frame, 1); \
404 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 1); \
405 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1); \
406 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1); \
408 for (i = 0; i < comp_height; i++) { \
409 MEMSET (p, 0x80, comp_width); \
413 p = GST_VIDEO_FRAME_COMP_DATA (frame, 2); \
414 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 2); \
415 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 2); \
416 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2); \
418 for (i = 0; i < comp_height; i++) { \
419 MEMSET (p, 0x80, comp_width); \
424 #define PLANAR_YUV_FILL_COLOR(format_name,format_enum,MEMSET) \
426 fill_color_##format_name (GstVideoFrame * frame, \
427 gint colY, gint colU, gint colV) \
430 gint comp_width, comp_height; \
434 p = GST_VIDEO_FRAME_COMP_DATA (frame, 0); \
435 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0); \
436 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0); \
437 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
439 for (i = 0; i < comp_height; i++) { \
440 MEMSET (p, colY, comp_width); \
444 p = GST_VIDEO_FRAME_COMP_DATA (frame, 1); \
445 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 1); \
446 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1); \
447 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1); \
449 for (i = 0; i < comp_height; i++) { \
450 MEMSET (p, colU, comp_width); \
454 p = GST_VIDEO_FRAME_COMP_DATA (frame, 2); \
455 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 2); \
456 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 2); \
457 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2); \
459 for (i = 0; i < comp_height; i++) { \
460 MEMSET (p, colV, comp_width); \
465 #define GST_ROUND_UP_1(x) (x)
467 PLANAR_YUV_BLEND (i420, GST_VIDEO_FORMAT_I420, GST_ROUND_UP_2,
468 GST_ROUND_UP_2, memcpy, compositor_orc_blend_u8);
469 PLANAR_YUV_FILL_CHECKER (i420, GST_VIDEO_FORMAT_I420, memset);
470 PLANAR_YUV_FILL_COLOR (i420, GST_VIDEO_FORMAT_I420, memset);
471 PLANAR_YUV_FILL_COLOR (yv12, GST_VIDEO_FORMAT_YV12, memset);
472 PLANAR_YUV_BLEND (y444, GST_VIDEO_FORMAT_Y444, GST_ROUND_UP_1,
473 GST_ROUND_UP_1, memcpy, compositor_orc_blend_u8);
474 PLANAR_YUV_FILL_CHECKER (y444, GST_VIDEO_FORMAT_Y444, memset);
475 PLANAR_YUV_FILL_COLOR (y444, GST_VIDEO_FORMAT_Y444, memset);
476 PLANAR_YUV_BLEND (y42b, GST_VIDEO_FORMAT_Y42B, GST_ROUND_UP_2,
477 GST_ROUND_UP_1, memcpy, compositor_orc_blend_u8);
478 PLANAR_YUV_FILL_CHECKER (y42b, GST_VIDEO_FORMAT_Y42B, memset);
479 PLANAR_YUV_FILL_COLOR (y42b, GST_VIDEO_FORMAT_Y42B, memset);
480 PLANAR_YUV_BLEND (y41b, GST_VIDEO_FORMAT_Y41B, GST_ROUND_UP_4,
481 GST_ROUND_UP_1, memcpy, compositor_orc_blend_u8);
482 PLANAR_YUV_FILL_CHECKER (y41b, GST_VIDEO_FORMAT_Y41B, memset);
483 PLANAR_YUV_FILL_COLOR (y41b, GST_VIDEO_FORMAT_Y41B, memset);
486 #define NV_YUV_BLEND(format_name,MEMCPY,BLENDLOOP) \
488 _blend_##format_name (const guint8 * src, guint8 * dest, \
489 gint src_stride, gint dest_stride, gint src_width, gint src_height, \
490 gdouble src_alpha, GstCompositorBlendMode mode) \
495 /* in source mode we just have to copy over things */ \
496 if (mode == COMPOSITOR_BLEND_MODE_SOURCE) { \
500 /* If it's completely transparent... we just return */ \
501 if (G_UNLIKELY (src_alpha == 0.0)) { \
502 GST_INFO ("Fast copy (alpha == 0.0)"); \
506 /* If it's completely opaque, we do a fast copy */ \
507 if (G_UNLIKELY (src_alpha == 1.0)) { \
508 GST_INFO ("Fast copy (alpha == 1.0)"); \
509 for (i = 0; i < src_height; i++) { \
510 MEMCPY (dest, src, src_width); \
512 dest += dest_stride; \
517 b_alpha = CLAMP ((gint) (src_alpha * 255), 0, 255); \
519 BLENDLOOP(dest, dest_stride, src, src_stride, b_alpha, src_width, src_height); \
523 blend_##format_name (GstVideoFrame * srcframe, gint xpos, gint ypos, \
524 gdouble src_alpha, GstVideoFrame * destframe, GstCompositorBlendMode mode) \
526 const guint8 *b_src; \
532 gint src_comp_rowstride, dest_comp_rowstride; \
533 gint src_comp_height; \
534 gint src_comp_width; \
535 gint comp_ypos, comp_xpos; \
536 gint comp_yoffset, comp_xoffset; \
537 gint dest_width, dest_height; \
538 const GstVideoFormatInfo *info; \
539 gint src_width, src_height; \
541 src_width = GST_VIDEO_FRAME_WIDTH (srcframe); \
542 src_height = GST_VIDEO_FRAME_HEIGHT (srcframe); \
544 info = srcframe->info.finfo; \
545 dest_width = GST_VIDEO_FRAME_WIDTH (destframe); \
546 dest_height = GST_VIDEO_FRAME_HEIGHT (destframe); \
548 xpos = GST_ROUND_UP_2 (xpos); \
549 ypos = GST_ROUND_UP_2 (ypos); \
551 b_src_width = src_width; \
552 b_src_height = src_height; \
554 /* adjust src pointers for negative sizes */ \
557 b_src_width -= -xpos; \
562 b_src_height -= -ypos; \
565 /* If x or y offset are larger then the source it's outside of the picture */ \
566 if (xoffset > src_width || yoffset > src_height) { \
570 /* adjust width/height if the src is bigger than dest */ \
571 if (xpos + src_width > dest_width) { \
572 b_src_width = dest_width - xpos; \
574 if (ypos + src_height > dest_height) { \
575 b_src_height = dest_height - ypos; \
577 if (b_src_width < 0 || b_src_height < 0) { \
581 /* First mix Y, then UV */ \
582 b_src = GST_VIDEO_FRAME_COMP_DATA (srcframe, 0); \
583 b_dest = GST_VIDEO_FRAME_COMP_DATA (destframe, 0); \
584 src_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 0); \
585 dest_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 0); \
586 src_comp_width = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(info, 0, b_src_width); \
587 src_comp_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(info, 0, b_src_height); \
588 comp_xpos = (xpos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 0, xpos); \
589 comp_ypos = (ypos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 0, ypos); \
590 comp_xoffset = (xoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 0, xoffset); \
591 comp_yoffset = (yoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 0, yoffset); \
592 _blend_##format_name (b_src + comp_xoffset + comp_yoffset * src_comp_rowstride, \
593 b_dest + comp_xpos + comp_ypos * dest_comp_rowstride, \
594 src_comp_rowstride, \
595 dest_comp_rowstride, src_comp_width, src_comp_height, \
598 b_src = GST_VIDEO_FRAME_PLANE_DATA (srcframe, 1); \
599 b_dest = GST_VIDEO_FRAME_PLANE_DATA (destframe, 1); \
600 src_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 1); \
601 dest_comp_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 1); \
602 src_comp_width = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(info, 1, b_src_width); \
603 src_comp_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(info, 1, b_src_height); \
604 comp_xpos = (xpos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 1, xpos); \
605 comp_ypos = (ypos == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 1, ypos); \
606 comp_xoffset = (xoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (info, 1, xoffset); \
607 comp_yoffset = (yoffset == 0) ? 0 : GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, 1, yoffset); \
608 _blend_##format_name (b_src + comp_xoffset * 2 + comp_yoffset * src_comp_rowstride, \
609 b_dest + comp_xpos * 2 + comp_ypos * dest_comp_rowstride, \
610 src_comp_rowstride, \
611 dest_comp_rowstride, 2 * src_comp_width, src_comp_height, \
615 #define NV_YUV_FILL_CHECKER(format_name, MEMSET) \
617 fill_checker_##format_name (GstVideoFrame * frame) \
620 static const int tab[] = { 80, 160, 80, 160 }; \
622 gint comp_width, comp_height; \
625 p = GST_VIDEO_FRAME_COMP_DATA (frame, 0); \
626 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0); \
627 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0); \
628 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
630 for (i = 0; i < comp_height; i++) { \
631 for (j = 0; j < comp_width; j++) { \
632 *p++ = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \
634 p += rowstride - comp_width; \
637 p = GST_VIDEO_FRAME_PLANE_DATA (frame, 1); \
638 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 1); \
639 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1); \
640 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1); \
642 for (i = 0; i < comp_height; i++) { \
643 MEMSET (p, 0x80, comp_width * 2); \
648 #define NV_YUV_FILL_COLOR(format_name,MEMSET) \
650 fill_color_##format_name (GstVideoFrame * frame, \
651 gint colY, gint colU, gint colV) \
654 gint comp_width, comp_height; \
658 y = GST_VIDEO_FRAME_COMP_DATA (frame, 0); \
659 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0); \
660 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0); \
661 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
663 for (i = 0; i < comp_height; i++) { \
664 MEMSET (y, colY, comp_width); \
668 u = GST_VIDEO_FRAME_COMP_DATA (frame, 1); \
669 v = GST_VIDEO_FRAME_COMP_DATA (frame, 2); \
670 comp_width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 1); \
671 comp_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1); \
672 rowstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1); \
674 for (i = 0; i < comp_height; i++) { \
675 for (j = 0; j < comp_width; j++) { \
684 NV_YUV_BLEND (nv12, memcpy, compositor_orc_blend_u8);
685 NV_YUV_FILL_CHECKER (nv12, memset);
686 NV_YUV_FILL_COLOR (nv12, memset);
687 NV_YUV_BLEND (nv21, memcpy, compositor_orc_blend_u8);
688 NV_YUV_FILL_CHECKER (nv21, memset);
690 /* RGB, BGR, xRGB, xBGR, RGBx, BGRx */
692 #define RGB_BLEND(name, bpp, MEMCPY, BLENDLOOP) \
694 blend_##name (GstVideoFrame * srcframe, gint xpos, gint ypos, \
695 gdouble src_alpha, GstVideoFrame * destframe, GstCompositorBlendMode mode) \
699 gint src_stride, dest_stride; \
700 gint dest_width, dest_height; \
701 guint8 *dest, *src; \
702 gint src_width, src_height; \
704 src_width = GST_VIDEO_FRAME_WIDTH (srcframe); \
705 src_height = GST_VIDEO_FRAME_HEIGHT (srcframe); \
707 src = GST_VIDEO_FRAME_PLANE_DATA (srcframe, 0); \
708 dest = GST_VIDEO_FRAME_PLANE_DATA (destframe, 0); \
710 dest_width = GST_VIDEO_FRAME_WIDTH (destframe); \
711 dest_height = GST_VIDEO_FRAME_HEIGHT (destframe); \
713 src_stride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 0); \
714 dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 0); \
716 b_alpha = CLAMP ((gint) (src_alpha * 255), 0, 255); \
718 /* adjust src pointers for negative sizes */ \
720 src += -xpos * bpp; \
721 src_width -= -xpos; \
725 src += -ypos * src_stride; \
726 src_height -= -ypos; \
729 /* adjust width/height if the src is bigger than dest */ \
730 if (xpos + src_width > dest_width) { \
731 src_width = dest_width - xpos; \
733 if (ypos + src_height > dest_height) { \
734 src_height = dest_height - ypos; \
737 dest = dest + bpp * xpos + (ypos * dest_stride); \
739 /* in source mode we just have to copy over things */ \
740 if (mode == COMPOSITOR_BLEND_MODE_SOURCE) { \
744 /* If it's completely transparent... we just return */ \
745 if (G_UNLIKELY (src_alpha == 0.0)) { \
746 GST_INFO ("Fast copy (alpha == 0.0)"); \
750 /* If it's completely opaque, we do a fast copy */ \
751 if (G_UNLIKELY (src_alpha == 1.0)) { \
752 GST_INFO ("Fast copy (alpha == 1.0)"); \
753 for (i = 0; i < src_height; i++) { \
754 MEMCPY (dest, src, bpp * src_width); \
756 dest += dest_stride; \
761 BLENDLOOP(dest, dest_stride, src, src_stride, b_alpha, src_width * bpp, src_height); \
764 #define RGB_FILL_CHECKER_C(name, bpp, r, g, b) \
766 fill_checker_##name##_c (GstVideoFrame * frame) \
769 static const int tab[] = { 80, 160, 80, 160 }; \
770 gint stride, dest_add, width, height; \
773 width = GST_VIDEO_FRAME_WIDTH (frame); \
774 height = GST_VIDEO_FRAME_HEIGHT (frame); \
775 dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
776 stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
777 dest_add = stride - width * bpp; \
779 for (i = 0; i < height; i++) { \
780 for (j = 0; j < width; j++) { \
781 dest[r] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; /* red */ \
782 dest[g] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; /* green */ \
783 dest[b] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; /* blue */ \
790 #define RGB_FILL_COLOR(name, bpp, MEMSET_RGB) \
792 fill_color_##name (GstVideoFrame * frame, \
793 gint colY, gint colU, gint colV) \
795 gint red, green, blue; \
798 gint width, height; \
801 width = GST_VIDEO_FRAME_WIDTH (frame); \
802 height = GST_VIDEO_FRAME_HEIGHT (frame); \
803 dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
804 dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
806 red = YUV_TO_R (colY, colU, colV); \
807 green = YUV_TO_G (colY, colU, colV); \
808 blue = YUV_TO_B (colY, colU, colV); \
810 for (i = 0; i < height; i++) { \
811 MEMSET_RGB (dest, red, green, blue, width); \
812 dest += dest_stride; \
816 #define MEMSET_RGB_C(name, r, g, b) \
818 _memset_##name##_c (guint8* dest, gint red, gint green, gint blue, gint width) { \
821 for (j = 0; j < width; j++) { \
829 #define MEMSET_XRGB(name, r, g, b) \
831 _memset_##name (guint8* dest, gint red, gint green, gint blue, gint width) { \
834 val = GUINT32_FROM_BE ((red << r) | (green << g) | (blue << b)); \
835 compositor_orc_splat_u32 ((guint32 *) dest, val, width); \
838 #define _orc_memcpy_u32(dest,src,len) compositor_orc_memcpy_u32((guint32 *) dest, (const guint32 *) src, len/4)
840 RGB_BLEND (rgb, 3, memcpy, compositor_orc_blend_u8);
841 RGB_FILL_CHECKER_C (rgb, 3, 0, 1, 2);
842 MEMSET_RGB_C (rgb, 0, 1, 2);
843 RGB_FILL_COLOR (rgb_c, 3, _memset_rgb_c);
845 MEMSET_RGB_C (bgr, 2, 1, 0);
846 RGB_FILL_COLOR (bgr_c, 3, _memset_bgr_c);
848 RGB_BLEND (xrgb, 4, _orc_memcpy_u32, compositor_orc_blend_u8);
849 RGB_FILL_CHECKER_C (xrgb, 4, 1, 2, 3);
850 MEMSET_XRGB (xrgb, 24, 16, 0);
851 RGB_FILL_COLOR (xrgb, 4, _memset_xrgb);
853 MEMSET_XRGB (xbgr, 0, 16, 24);
854 RGB_FILL_COLOR (xbgr, 4, _memset_xbgr);
856 MEMSET_XRGB (rgbx, 24, 16, 8);
857 RGB_FILL_COLOR (rgbx, 4, _memset_rgbx);
859 MEMSET_XRGB (bgrx, 8, 16, 24);
860 RGB_FILL_COLOR (bgrx, 4, _memset_bgrx);
862 /* YUY2, YVYU, UYVY */
864 #define PACKED_422_BLEND(name, MEMCPY, BLENDLOOP) \
866 blend_##name (GstVideoFrame * srcframe, gint xpos, gint ypos, \
867 gdouble src_alpha, GstVideoFrame * destframe, GstCompositorBlendMode mode) \
871 gint src_stride, dest_stride; \
872 gint dest_width, dest_height; \
873 guint8 *src, *dest; \
874 gint src_width, src_height; \
876 src_width = GST_VIDEO_FRAME_WIDTH (srcframe); \
877 src_height = GST_VIDEO_FRAME_HEIGHT (srcframe); \
879 dest_width = GST_VIDEO_FRAME_WIDTH (destframe); \
880 dest_height = GST_VIDEO_FRAME_HEIGHT (destframe); \
882 src = GST_VIDEO_FRAME_PLANE_DATA (srcframe, 0); \
883 dest = GST_VIDEO_FRAME_PLANE_DATA (destframe, 0); \
885 src_stride = GST_VIDEO_FRAME_COMP_STRIDE (srcframe, 0); \
886 dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (destframe, 0); \
888 b_alpha = CLAMP ((gint) (src_alpha * 255), 0, 255); \
890 xpos = GST_ROUND_UP_2 (xpos); \
892 /* adjust src pointers for negative sizes */ \
895 src_width -= -xpos; \
899 src += -ypos * src_stride; \
900 src_height -= -ypos; \
904 /* adjust width/height if the src is bigger than dest */ \
905 if (xpos + src_width > dest_width) { \
906 src_width = dest_width - xpos; \
908 if (ypos + src_height > dest_height) { \
909 src_height = dest_height - ypos; \
912 dest = dest + 2 * xpos + (ypos * dest_stride); \
914 /* in source mode we just have to copy over things */ \
915 if (mode == COMPOSITOR_BLEND_MODE_SOURCE) { \
919 /* If it's completely transparent... we just return */ \
920 if (G_UNLIKELY (src_alpha == 0.0)) { \
921 GST_INFO ("Fast copy (alpha == 0.0)"); \
925 /* If it's completely opaque, we do a fast copy */ \
926 if (G_UNLIKELY (src_alpha == 1.0)) { \
927 GST_INFO ("Fast copy (alpha == 1.0)"); \
928 for (i = 0; i < src_height; i++) { \
929 MEMCPY (dest, src, 2 * src_width); \
931 dest += dest_stride; \
936 BLENDLOOP(dest, dest_stride, src, src_stride, b_alpha, 2 * src_width, src_height); \
939 #define PACKED_422_FILL_CHECKER_C(name, Y1, U, Y2, V) \
941 fill_checker_##name##_c (GstVideoFrame * frame) \
944 static const int tab[] = { 80, 160, 80, 160 }; \
946 gint width, height; \
949 width = GST_VIDEO_FRAME_WIDTH (frame); \
950 width = GST_ROUND_UP_2 (width); \
951 height = GST_VIDEO_FRAME_HEIGHT (frame); \
952 dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
953 dest_add = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0) - width * 2; \
956 for (i = 0; i < height; i++) { \
957 for (j = 0; j < width; j++) { \
958 dest[Y1] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \
959 dest[Y2] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \
968 #define PACKED_422_FILL_COLOR(name, Y1, U, Y2, V) \
970 fill_color_##name (GstVideoFrame * frame, \
971 gint colY, gint colU, gint colV) \
976 gint width, height; \
979 width = GST_VIDEO_FRAME_WIDTH (frame); \
980 width = GST_ROUND_UP_2 (width); \
981 height = GST_VIDEO_FRAME_HEIGHT (frame); \
982 dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
983 dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
986 val = GUINT32_FROM_BE ((colY << Y1) | (colY << Y2) | (colU << U) | (colV << V)); \
988 for (i = 0; i < height; i++) { \
989 compositor_orc_splat_u32 ((guint32 *) dest, val, width); \
990 dest += dest_stride; \
994 PACKED_422_BLEND (yuy2, memcpy, compositor_orc_blend_u8);
995 PACKED_422_FILL_CHECKER_C (yuy2, 0, 1, 2, 3);
996 PACKED_422_FILL_CHECKER_C (uyvy, 1, 0, 3, 2);
997 PACKED_422_FILL_COLOR (yuy2, 24, 16, 8, 0);
998 PACKED_422_FILL_COLOR (yvyu, 24, 0, 8, 16);
999 PACKED_422_FILL_COLOR (uyvy, 16, 24, 0, 8);
1002 BlendFunction gst_compositor_blend_argb;
1003 BlendFunction gst_compositor_blend_bgra;
1004 BlendFunction gst_compositor_overlay_argb;
1005 BlendFunction gst_compositor_overlay_bgra;
1006 /* AYUV/ABGR is equal to ARGB, RGBA is equal to BGRA */
1007 BlendFunction gst_compositor_blend_y444;
1008 BlendFunction gst_compositor_blend_y42b;
1009 BlendFunction gst_compositor_blend_i420;
1010 /* I420 is equal to YV12 */
1011 BlendFunction gst_compositor_blend_nv12;
1012 BlendFunction gst_compositor_blend_nv21;
1013 BlendFunction gst_compositor_blend_y41b;
1014 BlendFunction gst_compositor_blend_rgb;
1015 /* BGR is equal to RGB */
1016 BlendFunction gst_compositor_blend_rgbx;
1017 /* BGRx, xRGB, xBGR are equal to RGBx */
1018 BlendFunction gst_compositor_blend_yuy2;
1019 /* YVYU and UYVY are equal to YUY2 */
1021 FillCheckerFunction gst_compositor_fill_checker_argb;
1022 FillCheckerFunction gst_compositor_fill_checker_bgra;
1023 /* ABGR is equal to ARGB, RGBA is equal to BGRA */
1024 FillCheckerFunction gst_compositor_fill_checker_ayuv;
1025 FillCheckerFunction gst_compositor_fill_checker_y444;
1026 FillCheckerFunction gst_compositor_fill_checker_y42b;
1027 FillCheckerFunction gst_compositor_fill_checker_i420;
1028 /* I420 is equal to YV12 */
1029 FillCheckerFunction gst_compositor_fill_checker_nv12;
1030 FillCheckerFunction gst_compositor_fill_checker_nv21;
1031 FillCheckerFunction gst_compositor_fill_checker_y41b;
1032 FillCheckerFunction gst_compositor_fill_checker_rgb;
1033 /* BGR is equal to RGB */
1034 FillCheckerFunction gst_compositor_fill_checker_xrgb;
1035 /* BGRx, xRGB, xBGR are equal to RGBx */
1036 FillCheckerFunction gst_compositor_fill_checker_yuy2;
1037 /* YVYU is equal to YUY2 */
1038 FillCheckerFunction gst_compositor_fill_checker_uyvy;
1040 FillColorFunction gst_compositor_fill_color_argb;
1041 FillColorFunction gst_compositor_fill_color_bgra;
1042 FillColorFunction gst_compositor_fill_color_abgr;
1043 FillColorFunction gst_compositor_fill_color_rgba;
1044 FillColorFunction gst_compositor_fill_color_ayuv;
1045 FillColorFunction gst_compositor_fill_color_y444;
1046 FillColorFunction gst_compositor_fill_color_y42b;
1047 FillColorFunction gst_compositor_fill_color_i420;
1048 FillColorFunction gst_compositor_fill_color_yv12;
1049 FillColorFunction gst_compositor_fill_color_nv12;
1050 /* NV21 is equal to NV12 */
1051 FillColorFunction gst_compositor_fill_color_y41b;
1052 FillColorFunction gst_compositor_fill_color_rgb;
1053 FillColorFunction gst_compositor_fill_color_bgr;
1054 FillColorFunction gst_compositor_fill_color_xrgb;
1055 FillColorFunction gst_compositor_fill_color_xbgr;
1056 FillColorFunction gst_compositor_fill_color_rgbx;
1057 FillColorFunction gst_compositor_fill_color_bgrx;
1058 FillColorFunction gst_compositor_fill_color_yuy2;
1059 FillColorFunction gst_compositor_fill_color_yvyu;
1060 FillColorFunction gst_compositor_fill_color_uyvy;
1063 gst_compositor_init_blend (void)
1065 GST_DEBUG_CATEGORY_INIT (gst_compositor_blend_debug, "compositor_blend", 0,
1066 "video compositor blending functions");
1068 gst_compositor_blend_argb = GST_DEBUG_FUNCPTR (blend_argb);
1069 gst_compositor_blend_bgra = GST_DEBUG_FUNCPTR (blend_bgra);
1070 gst_compositor_overlay_argb = GST_DEBUG_FUNCPTR (overlay_argb);
1071 gst_compositor_overlay_bgra = GST_DEBUG_FUNCPTR (overlay_bgra);
1072 gst_compositor_blend_i420 = GST_DEBUG_FUNCPTR (blend_i420);
1073 gst_compositor_blend_nv12 = GST_DEBUG_FUNCPTR (blend_nv12);
1074 gst_compositor_blend_nv21 = GST_DEBUG_FUNCPTR (blend_nv21);
1075 gst_compositor_blend_y444 = GST_DEBUG_FUNCPTR (blend_y444);
1076 gst_compositor_blend_y42b = GST_DEBUG_FUNCPTR (blend_y42b);
1077 gst_compositor_blend_y41b = GST_DEBUG_FUNCPTR (blend_y41b);
1078 gst_compositor_blend_rgb = GST_DEBUG_FUNCPTR (blend_rgb);
1079 gst_compositor_blend_xrgb = GST_DEBUG_FUNCPTR (blend_xrgb);
1080 gst_compositor_blend_yuy2 = GST_DEBUG_FUNCPTR (blend_yuy2);
1082 gst_compositor_fill_checker_argb = GST_DEBUG_FUNCPTR (fill_checker_argb_c);
1083 gst_compositor_fill_checker_bgra = GST_DEBUG_FUNCPTR (fill_checker_bgra_c);
1084 gst_compositor_fill_checker_ayuv = GST_DEBUG_FUNCPTR (fill_checker_ayuv_c);
1085 gst_compositor_fill_checker_i420 = GST_DEBUG_FUNCPTR (fill_checker_i420);
1086 gst_compositor_fill_checker_nv12 = GST_DEBUG_FUNCPTR (fill_checker_nv12);
1087 gst_compositor_fill_checker_nv21 = GST_DEBUG_FUNCPTR (fill_checker_nv21);
1088 gst_compositor_fill_checker_y444 = GST_DEBUG_FUNCPTR (fill_checker_y444);
1089 gst_compositor_fill_checker_y42b = GST_DEBUG_FUNCPTR (fill_checker_y42b);
1090 gst_compositor_fill_checker_y41b = GST_DEBUG_FUNCPTR (fill_checker_y41b);
1091 gst_compositor_fill_checker_rgb = GST_DEBUG_FUNCPTR (fill_checker_rgb_c);
1092 gst_compositor_fill_checker_xrgb = GST_DEBUG_FUNCPTR (fill_checker_xrgb_c);
1093 gst_compositor_fill_checker_yuy2 = GST_DEBUG_FUNCPTR (fill_checker_yuy2_c);
1094 gst_compositor_fill_checker_uyvy = GST_DEBUG_FUNCPTR (fill_checker_uyvy_c);
1096 gst_compositor_fill_color_argb = GST_DEBUG_FUNCPTR (fill_color_argb);
1097 gst_compositor_fill_color_bgra = GST_DEBUG_FUNCPTR (fill_color_bgra);
1098 gst_compositor_fill_color_abgr = GST_DEBUG_FUNCPTR (fill_color_abgr);
1099 gst_compositor_fill_color_rgba = GST_DEBUG_FUNCPTR (fill_color_rgba);
1100 gst_compositor_fill_color_ayuv = GST_DEBUG_FUNCPTR (fill_color_ayuv);
1101 gst_compositor_fill_color_i420 = GST_DEBUG_FUNCPTR (fill_color_i420);
1102 gst_compositor_fill_color_yv12 = GST_DEBUG_FUNCPTR (fill_color_yv12);
1103 gst_compositor_fill_color_nv12 = GST_DEBUG_FUNCPTR (fill_color_nv12);
1104 gst_compositor_fill_color_y444 = GST_DEBUG_FUNCPTR (fill_color_y444);
1105 gst_compositor_fill_color_y42b = GST_DEBUG_FUNCPTR (fill_color_y42b);
1106 gst_compositor_fill_color_y41b = GST_DEBUG_FUNCPTR (fill_color_y41b);
1107 gst_compositor_fill_color_rgb = GST_DEBUG_FUNCPTR (fill_color_rgb_c);
1108 gst_compositor_fill_color_bgr = GST_DEBUG_FUNCPTR (fill_color_bgr_c);
1109 gst_compositor_fill_color_xrgb = GST_DEBUG_FUNCPTR (fill_color_xrgb);
1110 gst_compositor_fill_color_xbgr = GST_DEBUG_FUNCPTR (fill_color_xbgr);
1111 gst_compositor_fill_color_rgbx = GST_DEBUG_FUNCPTR (fill_color_rgbx);
1112 gst_compositor_fill_color_bgrx = GST_DEBUG_FUNCPTR (fill_color_bgrx);
1113 gst_compositor_fill_color_yuy2 = GST_DEBUG_FUNCPTR (fill_color_yuy2);
1114 gst_compositor_fill_color_yvyu = GST_DEBUG_FUNCPTR (fill_color_yvyu);
1115 gst_compositor_fill_color_uyvy = GST_DEBUG_FUNCPTR (fill_color_uyvy);