2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
24 /* non-GST-specific stuff */
26 #include "gstvideotestsrc.h"
27 #include "videotestsrc.h"
28 #include "gstvideotestsrcorc.h"
30 #include <gst/math-compat.h>
35 #define TO_16(x) (((x)<<8) | (x))
38 random_char (guint * state)
42 return (*state >> 16) & 0xff;
61 static const struct vts_color_struct vts_colors_bt709_ycbcr_100[] = {
62 {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
63 {219, 16, 138, 255, 255, 255, 0, (219 << 8)},
64 {188, 154, 16, 255, 0, 255, 255, (188 << 8)},
65 {173, 42, 26, 255, 0, 255, 0, (173 << 8)},
66 {78, 214, 230, 255, 255, 0, 255, (78 << 8)},
67 {63, 102, 240, 255, 255, 0, 0, (64 << 8)},
68 {32, 240, 118, 255, 0, 0, 255, (32 << 8)},
69 {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
70 {16, 198, 21, 255, 0, 0, 128, (16 << 8)}, /* -I ? */
71 {16, 235, 198, 255, 0, 128, 255, (16 << 8)}, /* +Q ? */
72 {0, 128, 128, 255, 0, 0, 0, 0},
73 {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
76 static const struct vts_color_struct vts_colors_bt709_ycbcr_75[] = {
77 {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
78 {168, 44, 136, 255, 191, 191, 0, (168 << 8)},
79 {145, 147, 44, 255, 0, 191, 191, (145 << 8)},
80 {133, 63, 52, 255, 0, 191, 0, (133 << 8)},
81 {63, 193, 204, 255, 191, 0, 191, (63 << 8)},
82 {51, 109, 212, 255, 191, 0, 0, (51 << 8)},
83 {28, 212, 120, 255, 0, 0, 191, (28 << 8)},
84 {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
85 {16, 198, 21, 255, 0, 0, 128, (16 << 8)}, /* -I ? */
86 {16, 235, 198, 255, 0, 128, 255, (16 << 8)}, /* +Q ? */
87 {0, 128, 128, 255, 0, 0, 0, 0},
88 {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
91 static const struct vts_color_struct vts_colors_bt601_ycbcr_100[] = {
92 {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
93 {210, 16, 146, 255, 255, 255, 0, (219 << 8)},
94 {170, 166, 16, 255, 0, 255, 255, (188 << 8)},
95 {145, 54, 34, 255, 0, 255, 0, (173 << 8)},
96 {106, 202, 222, 255, 255, 0, 255, (78 << 8)},
97 {81, 90, 240, 255, 255, 0, 0, (64 << 8)},
98 {41, 240, 110, 255, 0, 0, 255, (32 << 8)},
99 {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
100 {16, 198, 21, 255, 0, 0, 128, (16 << 8)}, /* -I ? */
101 {16, 235, 198, 255, 0, 128, 255, (16 << 8)}, /* +Q ? */
102 {-0, 128, 128, 255, 0, 0, 0, 0},
103 {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
106 static const struct vts_color_struct vts_colors_bt601_ycbcr_75[] = {
107 {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
108 {162, 44, 142, 255, 191, 191, 0, (168 << 8)},
109 {131, 156, 44, 255, 0, 191, 191, (145 << 8)},
110 {112, 72, 58, 255, 0, 191, 0, (133 << 8)},
111 {84, 184, 198, 255, 191, 0, 191, (63 << 8)},
112 {65, 100, 212, 255, 191, 0, 0, (51 << 8)},
113 {35, 212, 114, 255, 0, 0, 191, (28 << 8)},
114 {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
115 {16, 198, 21, 255, 0, 0, 128, (16 << 8)}, /* -I ? */
116 {16, 235, 198, 255, 0, 128, 255, (16 << 8)}, /* +Q ? */
117 {-0, 128, 128, 255, 0, 0, 0, 0},
118 {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
122 static void paint_tmpline_ARGB (paintinfo * p, int x, int w);
123 static void paint_tmpline_AYUV (paintinfo * p, int x, int w);
125 static void convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y);
126 static void convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y);
129 #define ONE_HALF (1 << (SCALEBITS - 1))
130 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
132 #define RGB_TO_Y(r, g, b) \
133 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
134 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
136 #define RGB_TO_U(r1, g1, b1, shift)\
137 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
138 FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
140 #define RGB_TO_V(r1, g1, b1, shift)\
141 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
142 FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
144 #define RGB_TO_Y_CCIR(r, g, b) \
145 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
146 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
148 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
149 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
150 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
152 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
153 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
154 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
156 #define RGB_TO_Y_CCIR_709(r, g, b) \
157 ((FIX(0.212600*219.0/255.0) * (r) + FIX(0.715200*219.0/255.0) * (g) + \
158 FIX(0.072200*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
160 #define RGB_TO_U_CCIR_709(r1, g1, b1, shift)\
161 (((- FIX(0.114572*224.0/255.0) * r1 - FIX(0.385427*224.0/255.0) * g1 + \
162 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
164 #define RGB_TO_V_CCIR_709(r1, g1, b1, shift)\
165 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.454153*224.0/255.0) * g1 - \
166 FIX(0.045847*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
169 videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
173 GstVideoInfo *info = &v->info;
175 width = GST_VIDEO_INFO_WIDTH (info);
177 if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
178 p->colors = vts_colors_bt601_ycbcr_100;
180 p->colors = vts_colors_bt709_ycbcr_100;
184 p->paint_tmpline = paint_tmpline_ARGB;
185 p->convert_tmpline = convert_hline_bayer;
187 p->convert_tmpline = convert_hline_generic;
188 if (GST_VIDEO_INFO_IS_RGB (info)) {
189 p->paint_tmpline = paint_tmpline_ARGB;
191 p->paint_tmpline = paint_tmpline_AYUV;
194 p->tmpline = v->tmpline;
195 p->tmpline2 = v->tmpline2;
196 p->tmpline_u8 = v->tmpline_u8;
197 p->tmpline_u16 = v->tmpline_u16;
198 p->n_lines = v->n_lines;
199 p->offset = v->offset;
201 p->x_offset = (v->horizontal_speed * v->n_frames) % width;
203 p->x_offset += width;
204 p->x_invert = v->x_invert;
205 p->y_invert = v->y_invert;
207 a = (v->foreground_color >> 24) & 0xff;
208 r = (v->foreground_color >> 16) & 0xff;
209 g = (v->foreground_color >> 8) & 0xff;
210 b = (v->foreground_color >> 0) & 0xff;
211 p->foreground_color.A = a;
212 p->foreground_color.R = r;
213 p->foreground_color.G = g;
214 p->foreground_color.B = b;
216 if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
217 p->foreground_color.Y = RGB_TO_Y_CCIR (r, g, b);
218 p->foreground_color.U = RGB_TO_U_CCIR (r, g, b, 0);
219 p->foreground_color.V = RGB_TO_V_CCIR (r, g, b, 0);
221 p->foreground_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
222 p->foreground_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
223 p->foreground_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
225 p->foreground_color.gray = RGB_TO_Y (r, g, b);
227 a = (v->background_color >> 24) & 0xff;
228 r = (v->background_color >> 16) & 0xff;
229 g = (v->background_color >> 8) & 0xff;
230 b = (v->background_color >> 0) & 0xff;
231 p->background_color.A = a;
232 p->background_color.R = r;
233 p->background_color.G = g;
234 p->background_color.B = b;
236 if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
237 p->background_color.Y = RGB_TO_Y_CCIR (r, g, b);
238 p->background_color.U = RGB_TO_U_CCIR (r, g, b, 0);
239 p->background_color.V = RGB_TO_V_CCIR (r, g, b, 0);
241 p->background_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
242 p->background_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
243 p->background_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
245 p->background_color.gray = RGB_TO_Y (r, g, b);
247 p->subsample = v->subsample;
251 videotestsrc_convert_tmpline (paintinfo * p, GstVideoFrame * frame, int j)
255 int width = frame->info.width;
256 int height = frame->info.height;
257 int n_lines = p->n_lines;
258 int offset = p->offset;
259 guint8 *tmpline = p->tmpline, *tmpline2 = p->tmpline2;
261 /* `tmpline2` is only used here and when the shift amount `x` is
262 * non-zero, which only applies when `horizontal-speed` is set.
264 * Instead of copying the rotated line back to `tmpline` for
265 * `p->convert_tmpline` to use, swap the pointers briefly. Besides
266 * being cheaper, this also lets us reuse the painted `tmpline` for
270 memcpy (tmpline2, tmpline + x * 4, (width - x) * 4);
271 memcpy (tmpline2 + (width - x) * 4, tmpline, x * 4);
272 p->tmpline = tmpline2;
273 p->tmpline2 = tmpline;
276 for (i = width; i < width + 5; i++) {
277 p->tmpline[4 * i + 0] = p->tmpline[4 * (width - 1) + 0];
278 p->tmpline[4 * i + 1] = p->tmpline[4 * (width - 1) + 1];
279 p->tmpline[4 * i + 2] = p->tmpline[4 * (width - 1) + 2];
280 p->tmpline[4 * i + 3] = p->tmpline[4 * (width - 1) + 3];
283 p->convert_tmpline (p, frame, j);
285 if (j == height - 1) {
286 while (j % n_lines - offset != n_lines - 1) {
288 p->convert_tmpline (p, frame, j);
293 p->tmpline = tmpline;
294 p->tmpline2 = tmpline2;
298 #define BLEND1(a,b,x) ((a)*(x) + (b)*(255-(x)))
299 #define DIV255(x) (((x) + (((x)+128)>>8) + 128)>>8)
300 #define BLEND(a,b,x) DIV255(BLEND1(a,b,x))
304 videotestsrc_blend_color (struct vts_color_struct *dest,
305 struct vts_color_struct *a, struct vts_color_struct *b, int x)
307 dest->Y = BLEND (a->Y, b->Y, x);
308 dest->U = BLEND (a->U, b->U, x);
309 dest->V = BLEND (a->V, b->V, x);
310 dest->R = BLEND (a->R, b->R, x);
311 dest->G = BLEND (a->G, b->G, x);
312 dest->B = BLEND (a->B, b->B, x);
313 dest->gray = BLEND (a->gray, b->gray, x);
319 videotestsrc_blend_line (GstVideoTestSrc * v, guint8 * dest,
320 const guint8 * src, const struct vts_color_struct *a,
321 const struct vts_color_struct *b, int x1, int x2)
324 if (v->bayer || GST_VIDEO_INFO_IS_RGB (&v->info)) {
325 for (i = x1; i < x2; i++) {
326 dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
327 dest[i * 4 + 1] = BLEND (a->R, b->R, src[i]);
328 dest[i * 4 + 2] = BLEND (a->G, b->G, src[i]);
329 dest[i * 4 + 3] = BLEND (a->B, b->B, src[i]);
332 for (i = x1; i < x2; i++) {
333 dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
334 dest[i * 4 + 1] = BLEND (a->Y, b->Y, src[i]);
335 dest[i * 4 + 2] = BLEND (a->U, b->U, src[i]);
336 dest[i * 4 + 3] = BLEND (a->V, b->V, src[i]);
343 gst_video_test_src_smpte (GstVideoTestSrc * v, GstClockTime pts,
344 GstVideoFrame * frame)
349 paintinfo pi = PAINT_INFO_INIT;
351 int w = frame->info.width, h = frame->info.height;
353 videotestsrc_setup_paintinfo (v, p, w, h);
359 for (j = 0; j < y1; j++) {
360 for (i = 0; i < 7; i++) {
362 int x2 = (i + 1) * w / 7;
364 p->color = p->colors + i;
365 p->paint_tmpline (p, x1, (x2 - x1));
367 videotestsrc_convert_tmpline (p, frame, j);
370 /* inverse blue bars */
371 for (j = y1; j < y2; j++) {
372 for (i = 0; i < 7; i++) {
374 int x2 = (i + 1) * w / 7;
382 p->color = p->colors + k;
383 p->paint_tmpline (p, x1, (x2 - x1));
385 videotestsrc_convert_tmpline (p, frame, j);
388 for (j = y2; j < h; j++) {
389 /* -I, white, Q regions */
390 for (i = 0; i < 3; i++) {
392 int x2 = (i + 1) * w / 6;
402 p->color = p->colors + k;
403 p->paint_tmpline (p, x1, (x2 - x1));
406 /* superblack, black, dark grey */
407 for (i = 0; i < 3; i++) {
408 int x1 = w / 2 + i * w / 12;
409 int x2 = w / 2 + (i + 1) * w / 12;
413 k = COLOR_SUPER_BLACK;
419 p->color = p->colors + k;
420 p->paint_tmpline (p, x1, (x2 - x1));
425 struct vts_color_struct color;
427 color = p->colors[COLOR_BLACK];
430 for (i = x1; i < w; i++) {
431 int y = random_char (&v->random_state);
432 p->tmpline_u8[i] = y;
434 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
435 &p->foreground_color, &p->background_color, x1, w);
438 videotestsrc_convert_tmpline (p, frame, j);
444 gst_video_test_src_smpte75 (GstVideoTestSrc * v, GstClockTime pts,
445 GstVideoFrame * frame)
449 paintinfo pi = PAINT_INFO_INIT;
451 int w = frame->info.width, h = frame->info.height;
453 videotestsrc_setup_paintinfo (v, p, w, h);
454 if (v->info.colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
455 p->colors = vts_colors_bt601_ycbcr_75;
457 p->colors = vts_colors_bt709_ycbcr_75;
461 for (j = 0; j < h; j++) {
462 for (i = 0; i < 7; i++) {
464 int x2 = (i + 1) * w / 7;
466 p->color = p->colors + i;
467 p->paint_tmpline (p, x1, (x2 - x1));
469 videotestsrc_convert_tmpline (p, frame, j);
474 gst_video_test_src_smpte100 (GstVideoTestSrc * v, GstClockTime pts,
475 GstVideoFrame * frame)
479 paintinfo pi = PAINT_INFO_INIT;
481 int w = frame->info.width, h = frame->info.height;
483 videotestsrc_setup_paintinfo (v, p, w, h);
486 for (j = 0; j < h; j++) {
487 for (i = 0; i < 7; i++) {
489 int x2 = (i + 1) * w / 7;
491 p->color = p->colors + i;
492 p->paint_tmpline (p, x1, (x2 - x1));
494 videotestsrc_convert_tmpline (p, frame, j);
499 gst_video_test_src_bar (GstVideoTestSrc * v, GstClockTime pts,
500 GstVideoFrame * frame)
503 paintinfo pi = PAINT_INFO_INIT;
505 int w = frame->info.width, h = frame->info.height;
507 videotestsrc_setup_paintinfo (v, p, w, h);
509 for (j = 0; j < h; j++) {
510 /* use fixed size for now */
513 p->color = &p->foreground_color;
514 p->paint_tmpline (p, 0, x2);
515 p->color = &p->background_color;
516 p->paint_tmpline (p, x2, (w - x2));
517 videotestsrc_convert_tmpline (p, frame, j);
522 gst_video_test_src_snow (GstVideoTestSrc * v, GstClockTime pts,
523 GstVideoFrame * frame)
527 paintinfo pi = PAINT_INFO_INIT;
529 struct vts_color_struct color;
530 int w = frame->info.width, h = frame->info.height;
532 videotestsrc_setup_paintinfo (v, p, w, h);
534 color = p->colors[COLOR_BLACK];
537 for (j = 0; j < h; j++) {
538 for (i = 0; i < w; i++) {
539 int y = random_char (&v->random_state);
540 p->tmpline_u8[i] = y;
542 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
543 &p->foreground_color, &p->background_color, 0, w);
544 videotestsrc_convert_tmpline (p, frame, j);
549 gst_video_test_src_unicolor (GstVideoTestSrc * v, GstVideoFrame * frame,
553 paintinfo pi = PAINT_INFO_INIT;
555 int w = frame->info.width, h = frame->info.height;
557 videotestsrc_setup_paintinfo (v, p, w, h);
559 p->color = p->colors + color_index;
560 if (color_index == COLOR_BLACK) {
561 p->color = &p->background_color;
563 if (color_index == COLOR_WHITE) {
564 p->color = &p->foreground_color;
567 for (i = 0; i < h; i++) {
568 p->paint_tmpline (p, 0, w);
569 videotestsrc_convert_tmpline (p, frame, i);
574 gst_video_test_src_black (GstVideoTestSrc * v, GstClockTime pts,
575 GstVideoFrame * frame)
577 gst_video_test_src_unicolor (v, frame, COLOR_BLACK);
581 gst_video_test_src_white (GstVideoTestSrc * v, GstClockTime pts,
582 GstVideoFrame * frame)
584 gst_video_test_src_unicolor (v, frame, COLOR_WHITE);
588 gst_video_test_src_red (GstVideoTestSrc * v, GstClockTime pts,
589 GstVideoFrame * frame)
591 gst_video_test_src_unicolor (v, frame, COLOR_RED);
595 gst_video_test_src_green (GstVideoTestSrc * v, GstClockTime pts,
596 GstVideoFrame * frame)
598 gst_video_test_src_unicolor (v, frame, COLOR_GREEN);
602 gst_video_test_src_blue (GstVideoTestSrc * v, GstClockTime pts,
603 GstVideoFrame * frame)
605 gst_video_test_src_unicolor (v, frame, COLOR_BLUE);
609 gst_video_test_src_blink (GstVideoTestSrc * v, GstClockTime pts,
610 GstVideoFrame * frame)
613 paintinfo pi = PAINT_INFO_INIT;
615 int w = frame->info.width, h = frame->info.height;
617 videotestsrc_setup_paintinfo (v, p, w, h);
619 if (v->n_frames & 1) {
620 p->color = &p->foreground_color;
622 p->color = &p->background_color;
625 for (i = 0; i < h; i++) {
626 p->paint_tmpline (p, 0, w);
627 videotestsrc_convert_tmpline (p, frame, i);
632 gst_video_test_src_solid (GstVideoTestSrc * v, GstClockTime pts,
633 GstVideoFrame * frame)
636 paintinfo pi = PAINT_INFO_INIT;
638 int w = frame->info.width, h = frame->info.height;
640 videotestsrc_setup_paintinfo (v, p, w, h);
642 p->color = &p->foreground_color;
644 for (i = 0; i < h; i++) {
645 p->paint_tmpline (p, 0, w);
646 videotestsrc_convert_tmpline (p, frame, i);
651 gst_video_test_src_checkers1 (GstVideoTestSrc * v, GstClockTime pts,
652 GstVideoFrame * frame)
655 paintinfo pi = PAINT_INFO_INIT;
657 int w = frame->info.width, h = frame->info.height;
659 videotestsrc_setup_paintinfo (v, p, w, h);
661 for (y = 0; y < h; y++) {
662 for (x = 0; x < w; x++) {
664 p->color = p->colors + COLOR_GREEN;
666 p->color = p->colors + COLOR_RED;
668 p->paint_tmpline (p, x, 1);
670 videotestsrc_convert_tmpline (p, frame, y);
675 gst_video_test_src_checkers2 (GstVideoTestSrc * v, GstClockTime pts,
676 GstVideoFrame * frame)
679 paintinfo pi = PAINT_INFO_INIT;
681 int w = frame->info.width, h = frame->info.height;
683 videotestsrc_setup_paintinfo (v, p, w, h);
685 for (y = 0; y < h; y++) {
686 for (x = 0; x < w; x += 2) {
687 guint len = MIN (2, w - x);
690 p->color = p->colors + COLOR_GREEN;
692 p->color = p->colors + COLOR_RED;
694 p->paint_tmpline (p, x, len);
696 videotestsrc_convert_tmpline (p, frame, y);
701 gst_video_test_src_checkers4 (GstVideoTestSrc * v, GstClockTime pts,
702 GstVideoFrame * frame)
705 paintinfo pi = PAINT_INFO_INIT;
707 int w = frame->info.width, h = frame->info.height;
709 videotestsrc_setup_paintinfo (v, p, w, h);
711 for (y = 0; y < h; y++) {
712 for (x = 0; x < w; x += 4) {
713 guint len = MIN (4, w - x);
716 p->color = p->colors + COLOR_GREEN;
718 p->color = p->colors + COLOR_RED;
720 p->paint_tmpline (p, x, len);
722 videotestsrc_convert_tmpline (p, frame, y);
727 gst_video_test_src_checkers8 (GstVideoTestSrc * v, GstClockTime pts,
728 GstVideoFrame * frame)
731 paintinfo pi = PAINT_INFO_INIT;
733 int w = frame->info.width, h = frame->info.height;
735 videotestsrc_setup_paintinfo (v, p, w, h);
737 for (y = 0; y < h; y++) {
738 for (x = 0; x < w; x += 8) {
739 guint len = MIN (8, w - x);
742 p->color = p->colors + COLOR_GREEN;
744 p->color = p->colors + COLOR_RED;
746 p->paint_tmpline (p, x, len);
748 videotestsrc_convert_tmpline (p, frame, y);
752 static const guint8 sine_table[256] = {
753 128, 131, 134, 137, 140, 143, 146, 149,
754 152, 156, 159, 162, 165, 168, 171, 174,
755 176, 179, 182, 185, 188, 191, 193, 196,
756 199, 201, 204, 206, 209, 211, 213, 216,
757 218, 220, 222, 224, 226, 228, 230, 232,
758 234, 236, 237, 239, 240, 242, 243, 245,
759 246, 247, 248, 249, 250, 251, 252, 252,
760 253, 254, 254, 255, 255, 255, 255, 255,
761 255, 255, 255, 255, 255, 255, 254, 254,
762 253, 252, 252, 251, 250, 249, 248, 247,
763 246, 245, 243, 242, 240, 239, 237, 236,
764 234, 232, 230, 228, 226, 224, 222, 220,
765 218, 216, 213, 211, 209, 206, 204, 201,
766 199, 196, 193, 191, 188, 185, 182, 179,
767 176, 174, 171, 168, 165, 162, 159, 156,
768 152, 149, 146, 143, 140, 137, 134, 131,
769 128, 124, 121, 118, 115, 112, 109, 106,
770 103, 99, 96, 93, 90, 87, 84, 81,
771 79, 76, 73, 70, 67, 64, 62, 59,
772 56, 54, 51, 49, 46, 44, 42, 39,
773 37, 35, 33, 31, 29, 27, 25, 23,
774 21, 19, 18, 16, 15, 13, 12, 10,
775 9, 8, 7, 6, 5, 4, 3, 3,
776 2, 1, 1, 0, 0, 0, 0, 0,
777 0, 0, 0, 0, 0, 0, 1, 1,
778 2, 3, 3, 4, 5, 6, 7, 8,
779 9, 10, 12, 13, 15, 16, 18, 19,
780 21, 23, 25, 27, 29, 31, 33, 35,
781 37, 39, 42, 44, 46, 49, 51, 54,
782 56, 59, 62, 64, 67, 70, 73, 76,
783 79, 81, 84, 87, 90, 93, 96, 99,
784 103, 106, 109, 112, 115, 118, 121, 124
789 gst_video_test_src_zoneplate (GstVideoTestSrc * v, GstClockTime pts,
790 GstVideoFrame * frame)
794 paintinfo pi = PAINT_INFO_INIT;
796 struct vts_color_struct color;
798 int w = frame->info.width, h = frame->info.height;
799 int xreset = -(w / 2) - v->xoffset; /* starting values for x^2 and y^2, centering the ellipse */
800 int yreset = -(h / 2) - v->yoffset;
811 int delta_kxt = v->kxt * t;
813 int scale_kxy = 0xffff / (w / 2);
814 int scale_kx2 = 0xffff / w;
816 videotestsrc_setup_paintinfo (v, p, w, h);
818 color = p->colors[COLOR_BLACK];
821 /* Zoneplate equation:
823 * phase = k0 + kx*x + ky*y + kt*t
824 * + kxt*x*t + kyt*y*t + kxy*x*y
825 * + kx2*x*x + ky2*y*y + Kt2*t*t
829 for (j = 0, y = yreset; j < h; j++, y++) {
830 for (i = 0, x = xreset; i < w; i++, x++) {
836 phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
839 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
840 /* phase = phase + (v->kxy * x * y) / (w/2); */
843 /*normalise x/y terms to rate of change of phase at the picture edge */
845 phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
846 ((v->kt2 * t * t) >> 1);
848 color.Y = sine_table[phase & 0xff];
853 p->paint_tmpline (p, i, 1);
858 /* optimised version, with original code shown in comments */
862 kt2 = v->kt2 * t * t;
863 for (j = 0, y = yreset; j < h; j++, y++) {
867 accum_kyt += v->kyt * t;
868 delta_kxy = v->kxy * y * scale_kxy;
869 accum_kxy = delta_kxy * xreset;
870 ky2 = (v->ky2 * y * y) / h;
871 for (i = 0, x = xreset; i < w; i++, x++) {
878 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
879 phase = phase + accum_kx + accum_ky + kt;
882 accum_kxt += delta_kxt;
883 accum_kxy += delta_kxy;
884 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
885 phase = phase + accum_kxt + accum_kyt;
887 /* phase = phase + (v->kxy * x * y) / (w/2); */
888 /* phase = phase + accum_kxy / (w/2); */
889 phase = phase + (accum_kxy >> 16);
892 /*normalise x/y terms to rate of change of phase at the picture edge */
893 /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
894 phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
896 p->tmpline_u8[i] = sine_table[phase & 0xff];
898 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
899 &p->foreground_color, &p->background_color, 0, w);
900 videotestsrc_convert_tmpline (p, frame, j);
905 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, GstClockTime pts,
906 GstVideoFrame * frame)
910 paintinfo pi = PAINT_INFO_INIT;
912 struct vts_color_struct color;
914 int w = frame->info.width, h = frame->info.height;
916 int xreset = -(w / 2) - v->xoffset; /* starting values for x^2 and y^2, centering the ellipse */
917 int yreset = -(h / 2) - v->yoffset;
928 int delta_kxt = v->kxt * t;
930 int scale_kxy = 0xffff / (w / 2);
931 int scale_kx2 = 0xffff / w;
933 videotestsrc_setup_paintinfo (v, p, w, h);
935 color = p->colors[COLOR_BLACK];
938 /* Zoneplate equation:
940 * phase = k0 + kx*x + ky*y + kt*t
941 * + kxt*x*t + kyt*y*t + kxy*x*y
942 * + kx2*x*x + ky2*y*y + Kt2*t*t
945 /* optimised version, with original code shown in comments */
949 kt2 = v->kt2 * t * t;
950 for (j = 0, y = yreset; j < h; j++, y++) {
954 accum_kyt += v->kyt * t;
955 delta_kxy = v->kxy * y * scale_kxy;
956 accum_kxy = delta_kxy * xreset;
957 ky2 = (v->ky2 * y * y) / h;
958 for (i = 0, x = xreset; i < w; i++, x++) {
965 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
966 phase = phase + accum_kx + accum_ky + kt;
969 accum_kxt += delta_kxt;
970 accum_kxy += delta_kxy;
971 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
972 phase = phase + accum_kxt + accum_kyt;
974 /* phase = phase + (v->kxy * x * y) / (w/2); */
975 /* phase = phase + accum_kxy / (w/2); */
976 phase = phase + (accum_kxy >> 16);
979 /*normalise x/y terms to rate of change of phase at the picture edge */
980 /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
981 phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
984 color.U = sine_table[phase & 0xff];
985 color.V = sine_table[phase & 0xff];
991 color.gray = color.Y << 8;
992 p->paint_tmpline (p, i, 1);
994 videotestsrc_convert_tmpline (p, frame, j);
998 #undef SCALE_AMPLITUDE
1000 gst_video_test_src_circular (GstVideoTestSrc * v, GstClockTime pts,
1001 GstVideoFrame * frame)
1005 paintinfo pi = PAINT_INFO_INIT;
1008 int w = frame->info.width, h = frame->info.height;
1012 videotestsrc_setup_paintinfo (v, p, w, h);
1014 for (i = 1; i < 8; i++) {
1015 freq[i] = 200 * pow (2.0, -(i - 1) / 4.0);
1018 for (j = 0; j < h; j++) {
1019 for (i = 0; i < w; i++) {
1024 sqrt ((2 * i - w) * (2 * i - w) + (2 * j - h) * (2 * j -
1026 seg = floor (dist * 16);
1027 if (seg == 0 || seg >= 8) {
1028 p->tmpline_u8[i] = 0;
1030 d = floor (256 * dist * freq[seg] + 0.5);
1031 p->tmpline_u8[i] = sine_table[d & 0xff];
1034 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1035 &p->foreground_color, &p->background_color, 0, w);
1036 videotestsrc_convert_tmpline (p, frame, j);
1041 gst_video_test_src_gamut (GstVideoTestSrc * v, GstClockTime pts,
1042 GstVideoFrame * frame)
1045 paintinfo pi = PAINT_INFO_INIT;
1047 struct vts_color_struct yuv_primary;
1048 struct vts_color_struct yuv_secondary;
1049 int w = frame->info.width, h = frame->info.height;
1051 videotestsrc_setup_paintinfo (v, p, w, h);
1053 for (y = 0; y < h; y++) {
1054 int region = (y * 4) / h;
1058 yuv_primary = p->colors[COLOR_BLACK];
1059 yuv_secondary = p->colors[COLOR_BLACK];
1060 yuv_secondary.Y = 0;
1063 yuv_primary = p->colors[COLOR_WHITE];
1064 yuv_secondary = p->colors[COLOR_WHITE];
1065 yuv_secondary.Y = 255;
1068 yuv_primary = p->colors[COLOR_RED];
1069 yuv_secondary = p->colors[COLOR_RED];
1070 yuv_secondary.V = 255;
1073 yuv_primary = p->colors[COLOR_BLUE];
1074 yuv_secondary = p->colors[COLOR_BLUE];
1075 yuv_secondary.U = 255;
1079 for (x = 0; x < w; x += 8) {
1080 int len = MIN (8, w - x);
1082 if ((x ^ y) & (1 << 4)) {
1083 p->color = &yuv_primary;
1085 p->color = &yuv_secondary;
1087 p->paint_tmpline (p, x, len);
1089 videotestsrc_convert_tmpline (p, frame, y);
1094 gst_video_test_src_ball (GstVideoTestSrc * v, GstClockTime pts,
1095 GstVideoFrame * frame)
1099 int w = frame->info.width, h = frame->info.height;
1105 paintinfo pi = PAINT_INFO_INIT;
1108 struct vts_color_struct
1109 *foreground_color = &p->foreground_color,
1110 *background_color = &p->background_color;
1112 switch (v->animation_mode) {
1113 case GST_VIDEO_TEST_SRC_FRAMES:
1114 rad = (gdouble) (v->n_frames) / 200;
1115 flipit = (v->n_frames / 50) % 2;
1117 case GST_VIDEO_TEST_SRC_WALL_TIME:
1118 wall_time = g_get_real_time ();
1120 rad = (gdouble) wall_time / 1000000.0;
1121 flipit = (wall_time / 1000000) % 2;
1123 case GST_VIDEO_TEST_SRC_RUNNING_TIME:
1124 rad = (gdouble) (pts) / GST_SECOND;
1125 flipit = (pts / GST_SECOND) % 2;
1128 if (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP) {
1129 /* Periodic reset for half sweep */
1131 rad -= floor (2 * rad) / 2;
1134 /* Scale for the animation calcs */
1135 rad = 2 * G_PI * rad;
1137 if (v->motion_type == GST_VIDEO_TEST_SRC_WAVY) {
1138 x = radius + (0.5 + 0.5 * sin (rad)) * (w - 2 * radius);
1139 y = radius + (0.5 + 0.5 * sin (rad * sqrt (2))) * (h - 2 * radius);
1141 /* sweep and hsweep */
1142 /* x,y is center of circle,
1144 * rad = angle .. of sweep.
1147 radius = MIN (h, w) / 4 - 0;
1149 /* 0 is the margin between edge of screen and top of ball */
1150 x = w / 2 + sin (rad) * radius;
1151 y = h / 2 - cos (rad) * radius;
1154 if (v->flip && flipit) {
1155 foreground_color = &p->background_color;
1156 background_color = &p->foreground_color;
1159 /* draw ball on frame */
1160 videotestsrc_setup_paintinfo (v, p, w, h);
1161 for (i = 0; i < h; i++) {
1162 if (i < y - radius || i > y + radius) {
1163 memset (p->tmpline_u8, 0, w);
1165 double o = MAX (0, (radius * radius - (i - y) * (i - y)));
1166 int r = rint (sqrt (o));
1171 x2 = MAX (0, x - r);
1172 for (j = x1; j < x2; j++) {
1173 p->tmpline_u8[j] = 0;
1176 x1 = MAX (0, x - r);
1177 x2 = MIN (w, x + r + 1);
1178 for (j = x1; j < x2; j++) {
1179 double rr = radius - sqrt ((j - x) * (j - x) + (i - y) * (i - y));
1182 p->tmpline_u8[j] = CLAMP ((int) floor (256 * rr), 0, 255);
1185 x1 = MIN (w, x + r + 1);
1187 for (j = x1; j < x2; j++) {
1188 p->tmpline_u8[j] = 0;
1192 if ((v->motion_type == GST_VIDEO_TEST_SRC_SWEEP) ||
1193 (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP)) {
1194 /* dot in the middle (to draw a line down the center) */
1195 p->tmpline_u8[w / 2] = 255;
1196 p->tmpline_u8[(int) x] = 255;
1199 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1200 foreground_color, background_color, 0, w);
1201 videotestsrc_convert_tmpline (p, frame, i);
1204 if ((v->motion_type == GST_VIDEO_TEST_SRC_SWEEP) ||
1205 (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP)) {
1206 /* draw a line across the middle of frame and ball. */
1207 for (i = 0; i < w; i++) {
1208 p->tmpline_u8[i] = 255;
1210 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1211 foreground_color, background_color, 0, w);
1212 videotestsrc_convert_tmpline (p, frame, h / 2);
1213 videotestsrc_convert_tmpline (p, frame, y);
1218 paint_tmpline_ARGB (paintinfo * p, int x, int w)
1223 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1224 value = (p->color->A << 0) | (p->color->R << 8) |
1225 (p->color->G << 16) | ((guint32) p->color->B << 24);
1227 value = ((guint32) p->color->A << 24) | (p->color->R << 16) |
1228 (p->color->G << 8) | (p->color->B << 0);
1232 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1236 paint_tmpline_AYUV (paintinfo * p, int x, int w)
1241 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1242 value = (p->color->A << 0) | (p->color->Y << 8) |
1243 (p->color->U << 16) | ((guint32) p->color->V << 24);
1245 value = ((guint32) p->color->A << 24) | (p->color->Y << 16) |
1246 (p->color->U << 8) | (p->color->V << 0);
1250 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1254 convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y)
1256 const GstVideoFormatInfo *finfo, *uinfo;
1257 gint line, offset, i, width, height, bits;
1261 finfo = frame->info.finfo;
1262 uinfo = gst_video_format_get_info (finfo->unpack_format);
1264 width = GST_VIDEO_FRAME_WIDTH (frame);
1265 height = GST_VIDEO_FRAME_HEIGHT (frame);
1267 bits = GST_VIDEO_FORMAT_INFO_DEPTH (uinfo, 0);
1269 n_lines = p->n_lines;
1272 dest = p->lines[line];
1276 for (i = 0; i < width; i++) {
1277 p->tmpline_u16[i * 4 + 0] = TO_16 (p->tmpline[i * 4 + 0]);
1278 p->tmpline_u16[i * 4 + 1] = TO_16 (p->tmpline[i * 4 + 1]);
1279 p->tmpline_u16[i * 4 + 2] = TO_16 (p->tmpline[i * 4 + 2]);
1280 p->tmpline_u16[i * 4 + 3] = TO_16 (p->tmpline[i * 4 + 3]);
1282 memcpy (dest, p->tmpline_u16, width * 8);
1284 memcpy (dest, p->tmpline, width * 4);
1287 if (line - offset == n_lines - 1) {
1293 for (i = 0; i < n_lines; i++) {
1294 idx = CLAMP (y + i + offset, 0, height - 1);
1295 lines[i] = p->lines[idx % n_lines];
1299 gst_video_chroma_resample (p->subsample, lines, width);
1301 for (i = 0; i < n_lines; i++) {
1302 idx = y + i + offset;
1303 if (idx > height - 1)
1305 finfo->pack_func (finfo, GST_VIDEO_PACK_FLAG_NONE,
1306 lines[i], 0, frame->data, frame->info.stride,
1307 frame->info.chroma_site, idx, width);
1313 convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y)
1316 guint8 *data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
1317 guint8 *R = data + y * GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
1318 guint8 *argb = p->tmpline;
1319 gint width = GST_VIDEO_FRAME_WIDTH (frame);
1320 int x_inv = p->x_invert;
1321 int y_inv = p->y_invert;
1323 if ((y ^ y_inv) & 1) {
1324 for (i = 0; i < width; i++) {
1325 if ((i ^ x_inv) & 1) {
1326 R[i] = argb[4 * i + 1];
1328 R[i] = argb[4 * i + 2];
1332 for (i = 0; i < width; i++) {
1333 if ((i ^ x_inv) & 1) {
1334 R[i] = argb[4 * i + 2];
1336 R[i] = argb[4 * i + 3];
1343 gst_video_test_src_pinwheel (GstVideoTestSrc * v, GstClockTime pts,
1344 GstVideoFrame * frame)
1349 int t = v->n_frames;
1350 paintinfo pi = PAINT_INFO_INIT;
1352 struct vts_color_struct color;
1353 int w = frame->info.width, h = frame->info.height;
1357 videotestsrc_setup_paintinfo (v, p, w, h);
1359 color = p->colors[COLOR_BLACK];
1362 for (k = 0; k < 19; k++) {
1363 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1368 for (j = 0; j < h; j++) {
1369 for (i = 0; i < w; i++) {
1372 for (k = 0; k < 19; k++) {
1375 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1378 y = CLAMP (x, -1, 1);
1385 p->tmpline_u8[i] = CLAMP (rint (v * 128 + 128), 0, 255);
1387 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1388 &p->foreground_color, &p->background_color, 0, w);
1389 videotestsrc_convert_tmpline (p, frame, j);
1394 gst_video_test_src_spokes (GstVideoTestSrc * v, GstClockTime pts,
1395 GstVideoFrame * frame)
1400 int t = v->n_frames;
1401 paintinfo pi = PAINT_INFO_INIT;
1403 struct vts_color_struct color;
1404 int w = frame->info.width, h = frame->info.height;
1408 videotestsrc_setup_paintinfo (v, p, w, h);
1410 color = p->colors[COLOR_BLACK];
1413 for (k = 0; k < 19; k++) {
1414 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1419 for (j = 0; j < h; j++) {
1420 for (i = 0; i < w; i++) {
1423 for (k = 0; k < 19; k++) {
1425 double sharpness = 1.0;
1426 double linewidth = 2.0;
1428 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1429 x = linewidth * 0.5 - fabs (x);
1432 y = CLAMP (x + 0.5, 0.0, 1.0);
1437 p->tmpline_u8[i] = CLAMP (rint (v * 255), 0, 255);
1439 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1440 &p->foreground_color, &p->background_color, 0, w);
1441 videotestsrc_convert_tmpline (p, frame, j);
1446 gst_video_test_src_gradient (GstVideoTestSrc * v, GstClockTime pts,
1447 GstVideoFrame * frame)
1451 paintinfo pi = PAINT_INFO_INIT;
1453 struct vts_color_struct color;
1454 int w = frame->info.width, h = frame->info.height;
1456 videotestsrc_setup_paintinfo (v, p, w, h);
1458 color = p->colors[COLOR_BLACK];
1461 for (j = 0; j < h; j++) {
1462 int y = j * 255.0 / h;
1463 for (i = 0; i < w; i++) {
1464 p->tmpline_u8[i] = y;
1466 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1467 &p->foreground_color, &p->background_color, 0, w);
1468 videotestsrc_convert_tmpline (p, frame, j);
1473 gst_video_test_src_colors (GstVideoTestSrc * v, GstClockTime pts,
1474 GstVideoFrame * frame)
1478 paintinfo pi = PAINT_INFO_INIT;
1480 struct vts_color_struct color;
1481 int w = frame->info.width, h = frame->info.height;
1483 videotestsrc_setup_paintinfo (v, p, w, h);
1485 color = p->colors[COLOR_BLACK];
1488 for (j = 0; j < h; j++) {
1489 for (i = 0; i < w; i++) {
1490 p->tmpline[i * 4 + 0] = 0xff;
1491 p->tmpline[i * 4 + 1] = ((i * 4096) / w) % 256;
1492 p->tmpline[i * 4 + 2] = (((j * 16) / h) << 4) | ((i * 16) / w);
1493 p->tmpline[i * 4 + 3] = ((j * 4096) / h) % 256;
1495 videotestsrc_convert_tmpline (p, frame, j);