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;
261 memcpy (p->tmpline2, p->tmpline, width * 4);
262 memcpy (p->tmpline, p->tmpline2 + x * 4, (width - x) * 4);
263 memcpy (p->tmpline + (width - x) * 4, p->tmpline2, x * 4);
266 for (i = width; i < width + 5; i++) {
267 p->tmpline[4 * i + 0] = p->tmpline[4 * (width - 1) + 0];
268 p->tmpline[4 * i + 1] = p->tmpline[4 * (width - 1) + 1];
269 p->tmpline[4 * i + 2] = p->tmpline[4 * (width - 1) + 2];
270 p->tmpline[4 * i + 3] = p->tmpline[4 * (width - 1) + 3];
273 p->convert_tmpline (p, frame, j);
275 if (j == height - 1) {
276 while (j % n_lines - offset != n_lines - 1) {
278 p->convert_tmpline (p, frame, j);
283 #define BLEND1(a,b,x) ((a)*(x) + (b)*(255-(x)))
284 #define DIV255(x) (((x) + (((x)+128)>>8) + 128)>>8)
285 #define BLEND(a,b,x) DIV255(BLEND1(a,b,x))
289 videotestsrc_blend_color (struct vts_color_struct *dest,
290 struct vts_color_struct *a, struct vts_color_struct *b, int x)
292 dest->Y = BLEND (a->Y, b->Y, x);
293 dest->U = BLEND (a->U, b->U, x);
294 dest->V = BLEND (a->V, b->V, x);
295 dest->R = BLEND (a->R, b->R, x);
296 dest->G = BLEND (a->G, b->G, x);
297 dest->B = BLEND (a->B, b->B, x);
298 dest->gray = BLEND (a->gray, b->gray, x);
304 videotestsrc_blend_line (GstVideoTestSrc * v, guint8 * dest, guint8 * src,
305 struct vts_color_struct *a, struct vts_color_struct *b, int n)
308 if (v->bayer || GST_VIDEO_INFO_IS_RGB (&v->info)) {
309 for (i = 0; i < n; i++) {
310 dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
311 dest[i * 4 + 1] = BLEND (a->R, b->R, src[i]);
312 dest[i * 4 + 2] = BLEND (a->G, b->G, src[i]);
313 dest[i * 4 + 3] = BLEND (a->B, b->B, src[i]);
316 for (i = 0; i < n; i++) {
317 dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
318 dest[i * 4 + 1] = BLEND (a->Y, b->Y, src[i]);
319 dest[i * 4 + 2] = BLEND (a->U, b->U, src[i]);
320 dest[i * 4 + 3] = BLEND (a->V, b->V, src[i]);
327 gst_video_test_src_smpte (GstVideoTestSrc * v, GstClockTime pts,
328 GstVideoFrame * frame)
333 paintinfo pi = PAINT_INFO_INIT;
335 int w = frame->info.width, h = frame->info.height;
337 videotestsrc_setup_paintinfo (v, p, w, h);
343 for (j = 0; j < y1; j++) {
344 for (i = 0; i < 7; i++) {
346 int x2 = (i + 1) * w / 7;
348 p->color = p->colors + i;
349 p->paint_tmpline (p, x1, (x2 - x1));
351 videotestsrc_convert_tmpline (p, frame, j);
354 /* inverse blue bars */
355 for (j = y1; j < y2; j++) {
356 for (i = 0; i < 7; i++) {
358 int x2 = (i + 1) * w / 7;
366 p->color = p->colors + k;
367 p->paint_tmpline (p, x1, (x2 - x1));
369 videotestsrc_convert_tmpline (p, frame, j);
372 for (j = y2; j < h; j++) {
373 /* -I, white, Q regions */
374 for (i = 0; i < 3; i++) {
376 int x2 = (i + 1) * w / 6;
386 p->color = p->colors + k;
387 p->paint_tmpline (p, x1, (x2 - x1));
390 /* superblack, black, dark grey */
391 for (i = 0; i < 3; i++) {
392 int x1 = w / 2 + i * w / 12;
393 int x2 = w / 2 + (i + 1) * w / 12;
397 k = COLOR_SUPER_BLACK;
403 p->color = p->colors + k;
404 p->paint_tmpline (p, x1, (x2 - x1));
409 struct vts_color_struct color;
411 color = p->colors[COLOR_BLACK];
414 for (i = x1; i < w; i++) {
415 int y = random_char (&v->random_state);
416 p->tmpline_u8[i] = y;
418 videotestsrc_blend_line (v, p->tmpline + x1 * 4, p->tmpline_u8 + x1,
419 &p->foreground_color, &p->background_color, w - x1);
422 videotestsrc_convert_tmpline (p, frame, j);
428 gst_video_test_src_smpte75 (GstVideoTestSrc * v, GstClockTime pts,
429 GstVideoFrame * frame)
433 paintinfo pi = PAINT_INFO_INIT;
435 int w = frame->info.width, h = frame->info.height;
437 videotestsrc_setup_paintinfo (v, p, w, h);
438 if (v->info.colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
439 p->colors = vts_colors_bt601_ycbcr_75;
441 p->colors = vts_colors_bt709_ycbcr_75;
445 for (j = 0; j < h; j++) {
446 for (i = 0; i < 7; i++) {
448 int x2 = (i + 1) * w / 7;
450 p->color = p->colors + i;
451 p->paint_tmpline (p, x1, (x2 - x1));
453 videotestsrc_convert_tmpline (p, frame, j);
458 gst_video_test_src_smpte100 (GstVideoTestSrc * v, GstClockTime pts,
459 GstVideoFrame * frame)
463 paintinfo pi = PAINT_INFO_INIT;
465 int w = frame->info.width, h = frame->info.height;
467 videotestsrc_setup_paintinfo (v, p, w, h);
470 for (j = 0; j < h; j++) {
471 for (i = 0; i < 7; i++) {
473 int x2 = (i + 1) * w / 7;
475 p->color = p->colors + i;
476 p->paint_tmpline (p, x1, (x2 - x1));
478 videotestsrc_convert_tmpline (p, frame, j);
483 gst_video_test_src_bar (GstVideoTestSrc * v, GstClockTime pts,
484 GstVideoFrame * frame)
487 paintinfo pi = PAINT_INFO_INIT;
489 int w = frame->info.width, h = frame->info.height;
491 videotestsrc_setup_paintinfo (v, p, w, h);
493 for (j = 0; j < h; j++) {
494 /* use fixed size for now */
497 p->color = &p->foreground_color;
498 p->paint_tmpline (p, 0, x2);
499 p->color = &p->background_color;
500 p->paint_tmpline (p, x2, (w - x2));
501 videotestsrc_convert_tmpline (p, frame, j);
506 gst_video_test_src_snow (GstVideoTestSrc * v, GstClockTime pts,
507 GstVideoFrame * frame)
511 paintinfo pi = PAINT_INFO_INIT;
513 struct vts_color_struct color;
514 int w = frame->info.width, h = frame->info.height;
516 videotestsrc_setup_paintinfo (v, p, w, h);
518 color = p->colors[COLOR_BLACK];
521 for (j = 0; j < h; j++) {
522 for (i = 0; i < w; i++) {
523 int y = random_char (&v->random_state);
524 p->tmpline_u8[i] = y;
526 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
527 &p->foreground_color, &p->background_color, w);
528 videotestsrc_convert_tmpline (p, frame, j);
533 gst_video_test_src_unicolor (GstVideoTestSrc * v, GstVideoFrame * frame,
537 paintinfo pi = PAINT_INFO_INIT;
539 int w = frame->info.width, h = frame->info.height;
541 videotestsrc_setup_paintinfo (v, p, w, h);
543 p->color = p->colors + color_index;
544 if (color_index == COLOR_BLACK) {
545 p->color = &p->background_color;
547 if (color_index == COLOR_WHITE) {
548 p->color = &p->foreground_color;
551 for (i = 0; i < h; i++) {
552 p->paint_tmpline (p, 0, w);
553 videotestsrc_convert_tmpline (p, frame, i);
558 gst_video_test_src_black (GstVideoTestSrc * v, GstClockTime pts,
559 GstVideoFrame * frame)
561 gst_video_test_src_unicolor (v, frame, COLOR_BLACK);
565 gst_video_test_src_white (GstVideoTestSrc * v, GstClockTime pts,
566 GstVideoFrame * frame)
568 gst_video_test_src_unicolor (v, frame, COLOR_WHITE);
572 gst_video_test_src_red (GstVideoTestSrc * v, GstClockTime pts,
573 GstVideoFrame * frame)
575 gst_video_test_src_unicolor (v, frame, COLOR_RED);
579 gst_video_test_src_green (GstVideoTestSrc * v, GstClockTime pts,
580 GstVideoFrame * frame)
582 gst_video_test_src_unicolor (v, frame, COLOR_GREEN);
586 gst_video_test_src_blue (GstVideoTestSrc * v, GstClockTime pts,
587 GstVideoFrame * frame)
589 gst_video_test_src_unicolor (v, frame, COLOR_BLUE);
593 gst_video_test_src_blink (GstVideoTestSrc * v, GstClockTime pts,
594 GstVideoFrame * frame)
597 paintinfo pi = PAINT_INFO_INIT;
599 int w = frame->info.width, h = frame->info.height;
601 videotestsrc_setup_paintinfo (v, p, w, h);
603 if (v->n_frames & 1) {
604 p->color = &p->foreground_color;
606 p->color = &p->background_color;
609 for (i = 0; i < h; i++) {
610 p->paint_tmpline (p, 0, w);
611 videotestsrc_convert_tmpline (p, frame, i);
616 gst_video_test_src_solid (GstVideoTestSrc * v, GstClockTime pts,
617 GstVideoFrame * frame)
620 paintinfo pi = PAINT_INFO_INIT;
622 int w = frame->info.width, h = frame->info.height;
624 videotestsrc_setup_paintinfo (v, p, w, h);
626 p->color = &p->foreground_color;
628 for (i = 0; i < h; i++) {
629 p->paint_tmpline (p, 0, w);
630 videotestsrc_convert_tmpline (p, frame, i);
635 gst_video_test_src_checkers1 (GstVideoTestSrc * v, GstClockTime pts,
636 GstVideoFrame * frame)
639 paintinfo pi = PAINT_INFO_INIT;
641 int w = frame->info.width, h = frame->info.height;
643 videotestsrc_setup_paintinfo (v, p, w, h);
645 for (y = 0; y < h; y++) {
646 for (x = 0; x < w; x++) {
648 p->color = p->colors + COLOR_GREEN;
650 p->color = p->colors + COLOR_RED;
652 p->paint_tmpline (p, x, 1);
654 videotestsrc_convert_tmpline (p, frame, y);
659 gst_video_test_src_checkers2 (GstVideoTestSrc * v, GstClockTime pts,
660 GstVideoFrame * frame)
663 paintinfo pi = PAINT_INFO_INIT;
665 int w = frame->info.width, h = frame->info.height;
667 videotestsrc_setup_paintinfo (v, p, w, h);
669 for (y = 0; y < h; y++) {
670 for (x = 0; x < w; x += 2) {
671 guint len = MIN (2, w - x);
674 p->color = p->colors + COLOR_GREEN;
676 p->color = p->colors + COLOR_RED;
678 p->paint_tmpline (p, x, len);
680 videotestsrc_convert_tmpline (p, frame, y);
685 gst_video_test_src_checkers4 (GstVideoTestSrc * v, GstClockTime pts,
686 GstVideoFrame * frame)
689 paintinfo pi = PAINT_INFO_INIT;
691 int w = frame->info.width, h = frame->info.height;
693 videotestsrc_setup_paintinfo (v, p, w, h);
695 for (y = 0; y < h; y++) {
696 for (x = 0; x < w; x += 4) {
697 guint len = MIN (4, w - x);
700 p->color = p->colors + COLOR_GREEN;
702 p->color = p->colors + COLOR_RED;
704 p->paint_tmpline (p, x, len);
706 videotestsrc_convert_tmpline (p, frame, y);
711 gst_video_test_src_checkers8 (GstVideoTestSrc * v, GstClockTime pts,
712 GstVideoFrame * frame)
715 paintinfo pi = PAINT_INFO_INIT;
717 int w = frame->info.width, h = frame->info.height;
719 videotestsrc_setup_paintinfo (v, p, w, h);
721 for (y = 0; y < h; y++) {
722 for (x = 0; x < w; x += 8) {
723 guint len = MIN (8, w - x);
726 p->color = p->colors + COLOR_GREEN;
728 p->color = p->colors + COLOR_RED;
730 p->paint_tmpline (p, x, len);
732 videotestsrc_convert_tmpline (p, frame, y);
736 static const guint8 sine_table[256] = {
737 128, 131, 134, 137, 140, 143, 146, 149,
738 152, 156, 159, 162, 165, 168, 171, 174,
739 176, 179, 182, 185, 188, 191, 193, 196,
740 199, 201, 204, 206, 209, 211, 213, 216,
741 218, 220, 222, 224, 226, 228, 230, 232,
742 234, 236, 237, 239, 240, 242, 243, 245,
743 246, 247, 248, 249, 250, 251, 252, 252,
744 253, 254, 254, 255, 255, 255, 255, 255,
745 255, 255, 255, 255, 255, 255, 254, 254,
746 253, 252, 252, 251, 250, 249, 248, 247,
747 246, 245, 243, 242, 240, 239, 237, 236,
748 234, 232, 230, 228, 226, 224, 222, 220,
749 218, 216, 213, 211, 209, 206, 204, 201,
750 199, 196, 193, 191, 188, 185, 182, 179,
751 176, 174, 171, 168, 165, 162, 159, 156,
752 152, 149, 146, 143, 140, 137, 134, 131,
753 128, 124, 121, 118, 115, 112, 109, 106,
754 103, 99, 96, 93, 90, 87, 84, 81,
755 79, 76, 73, 70, 67, 64, 62, 59,
756 56, 54, 51, 49, 46, 44, 42, 39,
757 37, 35, 33, 31, 29, 27, 25, 23,
758 21, 19, 18, 16, 15, 13, 12, 10,
759 9, 8, 7, 6, 5, 4, 3, 3,
760 2, 1, 1, 0, 0, 0, 0, 0,
761 0, 0, 0, 0, 0, 0, 1, 1,
762 2, 3, 3, 4, 5, 6, 7, 8,
763 9, 10, 12, 13, 15, 16, 18, 19,
764 21, 23, 25, 27, 29, 31, 33, 35,
765 37, 39, 42, 44, 46, 49, 51, 54,
766 56, 59, 62, 64, 67, 70, 73, 76,
767 79, 81, 84, 87, 90, 93, 96, 99,
768 103, 106, 109, 112, 115, 118, 121, 124
773 gst_video_test_src_zoneplate (GstVideoTestSrc * v, GstClockTime pts,
774 GstVideoFrame * frame)
778 paintinfo pi = PAINT_INFO_INIT;
780 struct vts_color_struct color;
782 int w = frame->info.width, h = frame->info.height;
783 int xreset = -(w / 2) - v->xoffset; /* starting values for x^2 and y^2, centering the ellipse */
784 int yreset = -(h / 2) - v->yoffset;
795 int delta_kxt = v->kxt * t;
797 int scale_kxy = 0xffff / (w / 2);
798 int scale_kx2 = 0xffff / w;
800 videotestsrc_setup_paintinfo (v, p, w, h);
802 color = p->colors[COLOR_BLACK];
805 /* Zoneplate equation:
807 * phase = k0 + kx*x + ky*y + kt*t
808 * + kxt*x*t + kyt*y*t + kxy*x*y
809 * + kx2*x*x + ky2*y*y + Kt2*t*t
813 for (j = 0, y = yreset; j < h; j++, y++) {
814 for (i = 0, x = xreset; i < w; i++, x++) {
820 phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
823 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
824 /* phase = phase + (v->kxy * x * y) / (w/2); */
827 /*normalise x/y terms to rate of change of phase at the picture edge */
829 phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
830 ((v->kt2 * t * t) >> 1);
832 color.Y = sine_table[phase & 0xff];
837 p->paint_tmpline (p, i, 1);
842 /* optimised version, with original code shown in comments */
846 kt2 = v->kt2 * t * t;
847 for (j = 0, y = yreset; j < h; j++, y++) {
851 accum_kyt += v->kyt * t;
852 delta_kxy = v->kxy * y * scale_kxy;
853 accum_kxy = delta_kxy * xreset;
854 ky2 = (v->ky2 * y * y) / h;
855 for (i = 0, x = xreset; i < w; i++, x++) {
862 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
863 phase = phase + accum_kx + accum_ky + kt;
866 accum_kxt += delta_kxt;
867 accum_kxy += delta_kxy;
868 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
869 phase = phase + accum_kxt + accum_kyt;
871 /* phase = phase + (v->kxy * x * y) / (w/2); */
872 /* phase = phase + accum_kxy / (w/2); */
873 phase = phase + (accum_kxy >> 16);
876 /*normalise x/y terms to rate of change of phase at the picture edge */
877 /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
878 phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
880 p->tmpline_u8[i] = sine_table[phase & 0xff];
882 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
883 &p->foreground_color, &p->background_color, w);
884 videotestsrc_convert_tmpline (p, frame, j);
889 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, GstClockTime pts,
890 GstVideoFrame * frame)
894 paintinfo pi = PAINT_INFO_INIT;
896 struct vts_color_struct color;
898 int w = frame->info.width, h = frame->info.height;
900 int xreset = -(w / 2) - v->xoffset; /* starting values for x^2 and y^2, centering the ellipse */
901 int yreset = -(h / 2) - v->yoffset;
912 int delta_kxt = v->kxt * t;
914 int scale_kxy = 0xffff / (w / 2);
915 int scale_kx2 = 0xffff / w;
917 videotestsrc_setup_paintinfo (v, p, w, h);
919 color = p->colors[COLOR_BLACK];
922 /* Zoneplate equation:
924 * phase = k0 + kx*x + ky*y + kt*t
925 * + kxt*x*t + kyt*y*t + kxy*x*y
926 * + kx2*x*x + ky2*y*y + Kt2*t*t
929 /* optimised version, with original code shown in comments */
933 kt2 = v->kt2 * t * t;
934 for (j = 0, y = yreset; j < h; j++, y++) {
938 accum_kyt += v->kyt * t;
939 delta_kxy = v->kxy * y * scale_kxy;
940 accum_kxy = delta_kxy * xreset;
941 ky2 = (v->ky2 * y * y) / h;
942 for (i = 0, x = xreset; i < w; i++, x++) {
949 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
950 phase = phase + accum_kx + accum_ky + kt;
953 accum_kxt += delta_kxt;
954 accum_kxy += delta_kxy;
955 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
956 phase = phase + accum_kxt + accum_kyt;
958 /* phase = phase + (v->kxy * x * y) / (w/2); */
959 /* phase = phase + accum_kxy / (w/2); */
960 phase = phase + (accum_kxy >> 16);
963 /*normalise x/y terms to rate of change of phase at the picture edge */
964 /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
965 phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
968 color.U = sine_table[phase & 0xff];
969 color.V = sine_table[phase & 0xff];
975 color.gray = color.Y << 8;
976 p->paint_tmpline (p, i, 1);
978 videotestsrc_convert_tmpline (p, frame, j);
982 #undef SCALE_AMPLITUDE
984 gst_video_test_src_circular (GstVideoTestSrc * v, GstClockTime pts,
985 GstVideoFrame * frame)
989 paintinfo pi = PAINT_INFO_INIT;
992 int w = frame->info.width, h = frame->info.height;
996 videotestsrc_setup_paintinfo (v, p, w, h);
998 for (i = 1; i < 8; i++) {
999 freq[i] = 200 * pow (2.0, -(i - 1) / 4.0);
1002 for (j = 0; j < h; j++) {
1003 for (i = 0; i < w; i++) {
1008 sqrt ((2 * i - w) * (2 * i - w) + (2 * j - h) * (2 * j -
1010 seg = floor (dist * 16);
1011 if (seg == 0 || seg >= 8) {
1012 p->tmpline_u8[i] = 0;
1014 d = floor (256 * dist * freq[seg] + 0.5);
1015 p->tmpline_u8[i] = sine_table[d & 0xff];
1018 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1019 &p->foreground_color, &p->background_color, w);
1020 videotestsrc_convert_tmpline (p, frame, j);
1025 gst_video_test_src_gamut (GstVideoTestSrc * v, GstClockTime pts,
1026 GstVideoFrame * frame)
1029 paintinfo pi = PAINT_INFO_INIT;
1031 struct vts_color_struct yuv_primary;
1032 struct vts_color_struct yuv_secondary;
1033 int w = frame->info.width, h = frame->info.height;
1035 videotestsrc_setup_paintinfo (v, p, w, h);
1037 for (y = 0; y < h; y++) {
1038 int region = (y * 4) / h;
1042 yuv_primary = p->colors[COLOR_BLACK];
1043 yuv_secondary = p->colors[COLOR_BLACK];
1044 yuv_secondary.Y = 0;
1047 yuv_primary = p->colors[COLOR_WHITE];
1048 yuv_secondary = p->colors[COLOR_WHITE];
1049 yuv_secondary.Y = 255;
1052 yuv_primary = p->colors[COLOR_RED];
1053 yuv_secondary = p->colors[COLOR_RED];
1054 yuv_secondary.V = 255;
1057 yuv_primary = p->colors[COLOR_BLUE];
1058 yuv_secondary = p->colors[COLOR_BLUE];
1059 yuv_secondary.U = 255;
1063 for (x = 0; x < w; x += 8) {
1064 int len = MIN (8, w - x);
1066 if ((x ^ y) & (1 << 4)) {
1067 p->color = &yuv_primary;
1069 p->color = &yuv_secondary;
1071 p->paint_tmpline (p, x, len);
1073 videotestsrc_convert_tmpline (p, frame, y);
1078 gst_video_test_src_ball (GstVideoTestSrc * v, GstClockTime pts,
1079 GstVideoFrame * frame)
1083 int w = frame->info.width, h = frame->info.height;
1089 paintinfo pi = PAINT_INFO_INIT;
1092 struct vts_color_struct
1093 *foreground_color = &p->foreground_color,
1094 *background_color = &p->background_color;
1096 switch (v->animation_mode) {
1097 case GST_VIDEO_TEST_SRC_FRAMES:
1098 rad = (gdouble) (v->n_frames) / 200;
1099 flipit = (v->n_frames / 50) % 2;
1101 case GST_VIDEO_TEST_SRC_WALL_TIME:
1102 g_get_current_time (&rand_tv);
1104 rad = (gdouble) (rand_tv.tv_usec) / 1000000.0 + rand_tv.tv_sec;
1105 flipit = rand_tv.tv_sec % 2;
1107 case GST_VIDEO_TEST_SRC_RUNNING_TIME:
1108 rad = (gdouble) (pts) / GST_SECOND;
1109 flipit = (pts / GST_SECOND) % 2;
1112 if (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP) {
1113 /* Periodic reset for half sweep */
1115 rad -= floor (2 * rad) / 2;
1118 /* Scale for the animation calcs */
1119 rad = 2 * G_PI * rad;
1121 if (v->motion_type == GST_VIDEO_TEST_SRC_WAVY) {
1122 x = radius + (0.5 + 0.5 * sin (rad)) * (w - 2 * radius);
1123 y = radius + (0.5 + 0.5 * sin (rad * sqrt (2))) * (h - 2 * radius);
1125 /* sweep and hsweep */
1126 /* x,y is center of circle,
1128 * rad = angle .. of sweep.
1131 radius = MIN (h, w) / 4 - 0;
1133 /* 0 is the margin between edge of screen and top of ball */
1134 x = w / 2 + sin (rad) * radius;
1135 y = h / 2 - cos (rad) * radius;
1138 if (v->flip && flipit) {
1139 foreground_color = &p->background_color;
1140 background_color = &p->foreground_color;
1143 /* draw ball on frame */
1144 videotestsrc_setup_paintinfo (v, p, w, h);
1145 for (i = 0; i < h; i++) {
1146 if (i < y - radius || i > y + radius) {
1147 memset (p->tmpline_u8, 0, w);
1149 double o = MAX (0, (radius * radius - (i - y) * (i - y)));
1150 int r = rint (sqrt (o));
1155 x2 = MAX (0, x - r);
1156 for (j = x1; j < x2; j++) {
1157 p->tmpline_u8[j] = 0;
1160 x1 = MAX (0, x - r);
1161 x2 = MIN (w, x + r + 1);
1162 for (j = x1; j < x2; j++) {
1163 double rr = radius - sqrt ((j - x) * (j - x) + (i - y) * (i - y));
1166 p->tmpline_u8[j] = CLAMP ((int) floor (256 * rr), 0, 255);
1169 x1 = MIN (w, x + r + 1);
1171 for (j = x1; j < x2; j++) {
1172 p->tmpline_u8[j] = 0;
1176 if ((v->motion_type == GST_VIDEO_TEST_SRC_SWEEP) ||
1177 (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP)) {
1178 /* dot in the middle (to draw a line down the center) */
1179 p->tmpline_u8[w / 2] = 255;
1180 p->tmpline_u8[(int) x] = 255;
1183 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1184 foreground_color, background_color, w);
1185 videotestsrc_convert_tmpline (p, frame, i);
1188 if ((v->motion_type == GST_VIDEO_TEST_SRC_SWEEP) ||
1189 (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP)) {
1190 /* draw a line across the middle of frame and ball. */
1191 for (i = 0; i < w; i++) {
1192 p->tmpline_u8[i] = 255;
1194 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1195 foreground_color, background_color, w);
1196 videotestsrc_convert_tmpline (p, frame, h / 2);
1197 videotestsrc_convert_tmpline (p, frame, y);
1202 paint_tmpline_ARGB (paintinfo * p, int x, int w)
1207 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1208 value = (p->color->A << 0) | (p->color->R << 8) |
1209 (p->color->G << 16) | ((guint32) p->color->B << 24);
1211 value = ((guint32) p->color->A << 24) | (p->color->R << 16) |
1212 (p->color->G << 8) | (p->color->B << 0);
1216 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1220 paint_tmpline_AYUV (paintinfo * p, int x, int w)
1225 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1226 value = (p->color->A << 0) | (p->color->Y << 8) |
1227 (p->color->U << 16) | ((guint32) p->color->V << 24);
1229 value = ((guint32) p->color->A << 24) | (p->color->Y << 16) |
1230 (p->color->U << 8) | (p->color->V << 0);
1234 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1238 convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y)
1240 const GstVideoFormatInfo *finfo, *uinfo;
1241 gint line, offset, i, width, height, bits;
1245 finfo = frame->info.finfo;
1246 uinfo = gst_video_format_get_info (finfo->unpack_format);
1248 width = GST_VIDEO_FRAME_WIDTH (frame);
1249 height = GST_VIDEO_FRAME_HEIGHT (frame);
1251 bits = GST_VIDEO_FORMAT_INFO_DEPTH (uinfo, 0);
1253 n_lines = p->n_lines;
1256 dest = p->lines[line];
1260 for (i = 0; i < width; i++) {
1261 p->tmpline_u16[i * 4 + 0] = TO_16 (p->tmpline[i * 4 + 0]);
1262 p->tmpline_u16[i * 4 + 1] = TO_16 (p->tmpline[i * 4 + 1]);
1263 p->tmpline_u16[i * 4 + 2] = TO_16 (p->tmpline[i * 4 + 2]);
1264 p->tmpline_u16[i * 4 + 3] = TO_16 (p->tmpline[i * 4 + 3]);
1266 memcpy (dest, p->tmpline_u16, width * 8);
1268 memcpy (dest, p->tmpline, width * 4);
1271 if (line - offset == n_lines - 1) {
1277 for (i = 0; i < n_lines; i++) {
1278 idx = CLAMP (y + i + offset, 0, height - 1);
1279 lines[i] = p->lines[idx % n_lines];
1283 gst_video_chroma_resample (p->subsample, lines, width);
1285 for (i = 0; i < n_lines; i++) {
1286 idx = y + i + offset;
1287 if (idx > height - 1)
1289 finfo->pack_func (finfo, GST_VIDEO_PACK_FLAG_NONE,
1290 lines[i], 0, frame->data, frame->info.stride,
1291 frame->info.chroma_site, idx, width);
1297 convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y)
1300 guint8 *data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
1301 guint8 *R = data + y * GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
1302 guint8 *argb = p->tmpline;
1303 gint width = GST_VIDEO_FRAME_WIDTH (frame);
1304 int x_inv = p->x_invert;
1305 int y_inv = p->y_invert;
1307 if ((y ^ y_inv) & 1) {
1308 for (i = 0; i < width; i++) {
1309 if ((i ^ x_inv) & 1) {
1310 R[i] = argb[4 * i + 1];
1312 R[i] = argb[4 * i + 2];
1316 for (i = 0; i < width; i++) {
1317 if ((i ^ x_inv) & 1) {
1318 R[i] = argb[4 * i + 2];
1320 R[i] = argb[4 * i + 3];
1327 gst_video_test_src_pinwheel (GstVideoTestSrc * v, GstClockTime pts,
1328 GstVideoFrame * frame)
1333 int t = v->n_frames;
1334 paintinfo pi = PAINT_INFO_INIT;
1336 struct vts_color_struct color;
1337 int w = frame->info.width, h = frame->info.height;
1341 videotestsrc_setup_paintinfo (v, p, w, h);
1343 color = p->colors[COLOR_BLACK];
1346 for (k = 0; k < 19; k++) {
1347 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1352 for (j = 0; j < h; j++) {
1353 for (i = 0; i < w; i++) {
1356 for (k = 0; k < 19; k++) {
1359 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1362 y = CLAMP (x, -1, 1);
1369 p->tmpline_u8[i] = CLAMP (rint (v * 128 + 128), 0, 255);
1371 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1372 &p->foreground_color, &p->background_color, w);
1373 videotestsrc_convert_tmpline (p, frame, j);
1378 gst_video_test_src_spokes (GstVideoTestSrc * v, GstClockTime pts,
1379 GstVideoFrame * frame)
1384 int t = v->n_frames;
1385 paintinfo pi = PAINT_INFO_INIT;
1387 struct vts_color_struct color;
1388 int w = frame->info.width, h = frame->info.height;
1392 videotestsrc_setup_paintinfo (v, p, w, h);
1394 color = p->colors[COLOR_BLACK];
1397 for (k = 0; k < 19; k++) {
1398 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1403 for (j = 0; j < h; j++) {
1404 for (i = 0; i < w; i++) {
1407 for (k = 0; k < 19; k++) {
1409 double sharpness = 1.0;
1410 double linewidth = 2.0;
1412 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1413 x = linewidth * 0.5 - fabs (x);
1416 y = CLAMP (x + 0.5, 0.0, 1.0);
1421 p->tmpline_u8[i] = CLAMP (rint (v * 255), 0, 255);
1423 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1424 &p->foreground_color, &p->background_color, w);
1425 videotestsrc_convert_tmpline (p, frame, j);
1430 gst_video_test_src_gradient (GstVideoTestSrc * v, GstClockTime pts,
1431 GstVideoFrame * frame)
1435 paintinfo pi = PAINT_INFO_INIT;
1437 struct vts_color_struct color;
1438 int w = frame->info.width, h = frame->info.height;
1440 videotestsrc_setup_paintinfo (v, p, w, h);
1442 color = p->colors[COLOR_BLACK];
1445 for (j = 0; j < h; j++) {
1446 int y = j * 255.0 / h;
1447 for (i = 0; i < w; i++) {
1448 p->tmpline_u8[i] = y;
1450 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1451 &p->foreground_color, &p->background_color, w);
1452 videotestsrc_convert_tmpline (p, frame, j);
1457 gst_video_test_src_colors (GstVideoTestSrc * v, GstClockTime pts,
1458 GstVideoFrame * frame)
1462 paintinfo pi = PAINT_INFO_INIT;
1464 struct vts_color_struct color;
1465 int w = frame->info.width, h = frame->info.height;
1467 videotestsrc_setup_paintinfo (v, p, w, h);
1469 color = p->colors[COLOR_BLACK];
1472 for (j = 0; j < h; j++) {
1473 for (i = 0; i < w; i++) {
1474 p->tmpline[i * 4 + 0] = 0xff;
1475 p->tmpline[i * 4 + 1] = ((i * 4096) / w) % 256;
1476 p->tmpline[i * 4 + 2] = (((j * 16) / h) << 4) | ((i * 16) / w);
1477 p->tmpline[i * 4 + 3] = ((j * 4096) / h) % 256;
1479 videotestsrc_convert_tmpline (p, frame, j);