1 /* GStreamer
2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 *
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.
8 *
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.
13 *
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.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 /* non-GST-specific stuff */
25
26 #include "gstvideotestsrc.h"
27 #include "videotestsrc.h"
28 #include "gstvideotestsrcorc.h"
29
30 #include <gst/math-compat.h>
31
32 #include <string.h>
33 #include <stdlib.h>
34
35 #define TO_16(x) (((x)<<8) | (x))
36
37 static unsigned char
random_char(guint * state)38 random_char (guint * state)
39 {
40 *state *= 1103515245;
41 *state += 12345;
42 return (*state >> 16) & 0xff;
43 }
44
45 enum
46 {
47 COLOR_WHITE = 0,
48 COLOR_YELLOW,
49 COLOR_CYAN,
50 COLOR_GREEN,
51 COLOR_MAGENTA,
52 COLOR_RED,
53 COLOR_BLUE,
54 COLOR_BLACK,
55 COLOR_NEG_I,
56 COLOR_POS_Q,
57 COLOR_SUPER_BLACK,
58 COLOR_DARK_GREY
59 };
60
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)},
74 };
75
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)},
89 };
90
91 /* 8-bit values, the selection and order of the colors is done by the
92 drawing function */
93 static const struct vts_color_struct vts_colors_bt709_ycbcr_rp_219[] = {
94 /* Pattern 1, smpte75 with 16:9 gray extensions */
95 {104, 128, 128, 255, 102, 102, 102, (104 << 8)}, /* row 0, 40% gray */
96 {180, 128, 128, 255, 191, 191, 191, (180 << 8)}, /* row 1, 75% white */
97 {168, 44, 136, 255, 190, 203, 8, (168 << 8)}, /* row 2, 75% yellow */
98 {145, 147, 44, 255, 16, 211, 189, (145 << 8)}, /* row 3, 75% cyan */
99 {133, 63, 52, 255, 15, 223, 5, (133 << 8)}, /* row 4, 75% green */
100 {63, 193, 204, 255, 176, 0, 186, (63 << 8)}, /* row 5, 75% magenta */
101 {51, 109, 212, 255, 175, 0, 2, (51 << 8)}, /* row 6, 75% red */
102 {28, 212, 120, 255, 1, 0, 183, (28 << 8)}, /* row 7, 75% blue */
103
104 /* Pattern 2 */
105 {188, 154, 16, 255, 22, 255, 253, (188 << 8)}, /* row 8, 100% cyan */
106 {235, 128, 128, 255, 255, 255, 255, (235 << 8)}, /* row 9, 100% white */
107 {61, 103, 157, 255, 99, 48, 15, (61 << 8)}, /* row 10, *2=+I */
108 {61, 153, 99, 255, 6, 66, 103, (61 << 8)}, /* row 11, *2=-I */
109 {32, 240, 118, 255, 3, 0, 245, (32 << 8)}, /* row 12, 100% blue */
110
111 /* Pattern 3 */
112 {219, 16, 138, 255, 252, 255, 10, (219 << 8)}, /* row 13, 100% yellow */
113 {16, 128, 128, 255, 0, 0, 0, (16 << 8)}, /* row 14, 0% black */
114 {35, 174, 152, 255, 60, 0, 115, (35 << 8)}, /* row 15, +Q */
115 {63, 102, 240, 255, 233, 0, 2, (63 << 8)}, /* row 16, 100% red */
116
117 /* Pattern 4 */
118 {49, 128, 128, 255, 38, 38, 38, (47 << 8)}, /* row 17, 15% gray */
119 {1, 128, 128, 255, 0, 0, 0, (1 << 8)}, /* row 18, sub-black valley */
120 {254, 128, 128, 255, 255, 255, 255, (254 << 8)}, /* row 19, super-white peak */
121 {12, 128, 128, 255, 0, 0, 0, (12 << 8)}, /* row 20, -2% black */
122 {20, 128, 128, 255, 5, 5, 5, (20 << 8)}, /* row 21, +2% black */
123 {25, 128, 128, 255, 10, 11, 10, (25 << 8)}, /* row 22, +4% black */
124 };
125
126 static const struct vts_color_struct vts_colors_bt601_ycbcr_100[] = {
127 {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
128 {210, 16, 146, 255, 255, 255, 0, (219 << 8)},
129 {170, 166, 16, 255, 0, 255, 255, (188 << 8)},
130 {145, 54, 34, 255, 0, 255, 0, (173 << 8)},
131 {106, 202, 222, 255, 255, 0, 255, (78 << 8)},
132 {81, 90, 240, 255, 255, 0, 0, (64 << 8)},
133 {41, 240, 110, 255, 0, 0, 255, (32 << 8)},
134 {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
135 {16, 198, 21, 255, 0, 0, 128, (16 << 8)}, /* -I ? */
136 {16, 235, 198, 255, 0, 128, 255, (16 << 8)}, /* +Q ? */
137 {-0, 128, 128, 255, 0, 0, 0, 0},
138 {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
139 };
140
141 static const struct vts_color_struct vts_colors_bt601_ycbcr_75[] = {
142 {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
143 {162, 44, 142, 255, 191, 191, 0, (168 << 8)},
144 {131, 156, 44, 255, 0, 191, 191, (145 << 8)},
145 {112, 72, 58, 255, 0, 191, 0, (133 << 8)},
146 {84, 184, 198, 255, 191, 0, 191, (63 << 8)},
147 {65, 100, 212, 255, 191, 0, 0, (51 << 8)},
148 {35, 212, 114, 255, 0, 0, 191, (28 << 8)},
149 {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
150 {16, 198, 21, 255, 0, 0, 128, (16 << 8)}, /* -I ? */
151 {16, 235, 198, 255, 0, 128, 255, (16 << 8)}, /* +Q ? */
152 {-0, 128, 128, 255, 0, 0, 0, 0},
153 {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
154 };
155
156
157 static void paint_tmpline_ARGB (paintinfo * p, int x, int w);
158 static void paint_tmpline_AYUV (paintinfo * p, int x, int w);
159
160 static void convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y);
161 static void convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y);
162
163 #define SCALEBITS 10
164 #define ONE_HALF (1 << (SCALEBITS - 1))
165 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
166
167 #define RGB_TO_Y(r, g, b) \
168 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
169 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
170
171 #define RGB_TO_U(r1, g1, b1, shift)\
172 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
173 FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
174
175 #define RGB_TO_V(r1, g1, b1, shift)\
176 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
177 FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
178
179 #define RGB_TO_Y_CCIR(r, g, b) \
180 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
181 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
182
183 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
184 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
185 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
186
187 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
188 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
189 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
190
191 #define RGB_TO_Y_CCIR_709(r, g, b) \
192 ((FIX(0.212600*219.0/255.0) * (r) + FIX(0.715200*219.0/255.0) * (g) + \
193 FIX(0.072200*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
194
195 #define RGB_TO_U_CCIR_709(r1, g1, b1, shift)\
196 (((- FIX(0.114572*224.0/255.0) * r1 - FIX(0.385427*224.0/255.0) * g1 + \
197 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
198
199 #define RGB_TO_V_CCIR_709(r1, g1, b1, shift)\
200 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.454153*224.0/255.0) * g1 - \
201 FIX(0.045847*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
202
203 static void
videotestsrc_setup_paintinfo(GstVideoTestSrc * v,paintinfo * p,int w,int h)204 videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
205 {
206 gint a, r, g, b;
207 gint width;
208 GstVideoInfo *info = &v->info;
209
210 width = GST_VIDEO_INFO_WIDTH (info);
211
212 if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
213 p->colors = vts_colors_bt601_ycbcr_100;
214 } else {
215 p->colors = vts_colors_bt709_ycbcr_100;
216 }
217
218 if (v->bayer) {
219 p->paint_tmpline = paint_tmpline_ARGB;
220 p->convert_tmpline = convert_hline_bayer;
221 } else {
222 p->convert_tmpline = convert_hline_generic;
223 if (GST_VIDEO_INFO_IS_RGB (info)) {
224 p->paint_tmpline = paint_tmpline_ARGB;
225 } else {
226 p->paint_tmpline = paint_tmpline_AYUV;
227 }
228 }
229 p->tmpline = v->tmpline;
230 p->tmpline2 = v->tmpline2;
231 p->tmpline_u8 = v->tmpline_u8;
232 p->tmpline_u16 = v->tmpline_u16;
233 p->n_lines = v->n_lines;
234 p->offset = v->offset;
235 p->lines = v->lines;
236 p->x_offset = (v->horizontal_speed * v->n_frames) % width;
237 if (p->x_offset < 0)
238 p->x_offset += width;
239 p->x_invert = v->x_invert;
240 p->y_invert = v->y_invert;
241
242 a = (v->foreground_color >> 24) & 0xff;
243 r = (v->foreground_color >> 16) & 0xff;
244 g = (v->foreground_color >> 8) & 0xff;
245 b = (v->foreground_color >> 0) & 0xff;
246 p->foreground_color.A = a;
247 p->foreground_color.R = r;
248 p->foreground_color.G = g;
249 p->foreground_color.B = b;
250
251 if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
252 p->foreground_color.Y = RGB_TO_Y_CCIR (r, g, b);
253 p->foreground_color.U = RGB_TO_U_CCIR (r, g, b, 0);
254 p->foreground_color.V = RGB_TO_V_CCIR (r, g, b, 0);
255 } else {
256 p->foreground_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
257 p->foreground_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
258 p->foreground_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
259 }
260 p->foreground_color.gray = RGB_TO_Y (r, g, b);
261
262 a = (v->background_color >> 24) & 0xff;
263 r = (v->background_color >> 16) & 0xff;
264 g = (v->background_color >> 8) & 0xff;
265 b = (v->background_color >> 0) & 0xff;
266 p->background_color.A = a;
267 p->background_color.R = r;
268 p->background_color.G = g;
269 p->background_color.B = b;
270
271 if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
272 p->background_color.Y = RGB_TO_Y_CCIR (r, g, b);
273 p->background_color.U = RGB_TO_U_CCIR (r, g, b, 0);
274 p->background_color.V = RGB_TO_V_CCIR (r, g, b, 0);
275 } else {
276 p->background_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
277 p->background_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
278 p->background_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
279 }
280 p->background_color.gray = RGB_TO_Y (r, g, b);
281
282 p->subsample = v->subsample;
283 }
284
285 static void
videotestsrc_convert_tmpline(paintinfo * p,GstVideoFrame * frame,int j)286 videotestsrc_convert_tmpline (paintinfo * p, GstVideoFrame * frame, int j)
287 {
288 int x = p->x_offset;
289 int i;
290 int width = frame->info.width;
291 int height = frame->info.height;
292 int n_lines = p->n_lines;
293 int offset = p->offset;
294 guint8 *tmpline = p->tmpline, *tmpline2 = p->tmpline2;
295
296 /* `tmpline2` is only used here and when the shift amount `x` is
297 * non-zero, which only applies when `horizontal-speed` is set.
298 *
299 * Instead of copying the rotated line back to `tmpline` for
300 * `p->convert_tmpline` to use, swap the pointers briefly. Besides
301 * being cheaper, this also lets us reuse the painted `tmpline` for
302 * subsequent lines.
303 */
304 if (x != 0) {
305 memcpy (tmpline2, tmpline + x * 4, (width - x) * 4);
306 memcpy (tmpline2 + (width - x) * 4, tmpline, x * 4);
307 p->tmpline = tmpline2;
308 p->tmpline2 = tmpline;
309 }
310
311 for (i = width; i < width + 5; i++) {
312 p->tmpline[4 * i + 0] = p->tmpline[4 * (width - 1) + 0];
313 p->tmpline[4 * i + 1] = p->tmpline[4 * (width - 1) + 1];
314 p->tmpline[4 * i + 2] = p->tmpline[4 * (width - 1) + 2];
315 p->tmpline[4 * i + 3] = p->tmpline[4 * (width - 1) + 3];
316 }
317
318 p->convert_tmpline (p, frame, j);
319
320 if (j == height - 1) {
321 while (j % n_lines - offset != n_lines - 1) {
322 j++;
323 p->convert_tmpline (p, frame, j);
324 }
325 }
326
327 if (x != 0) {
328 p->tmpline = tmpline;
329 p->tmpline2 = tmpline2;
330 }
331 }
332
333 #define BLEND1(a,b,x) ((a)*(x) + (b)*(255-(x)))
334 #define DIV255(x) (((x) + (((x)+128)>>8) + 128)>>8)
335 #define BLEND(a,b,x) DIV255(BLEND1(a,b,x))
336
337 #ifdef unused
338 static void
videotestsrc_blend_color(struct vts_color_struct * dest,struct vts_color_struct * a,struct vts_color_struct * b,int x)339 videotestsrc_blend_color (struct vts_color_struct *dest,
340 struct vts_color_struct *a, struct vts_color_struct *b, int x)
341 {
342 dest->Y = BLEND (a->Y, b->Y, x);
343 dest->U = BLEND (a->U, b->U, x);
344 dest->V = BLEND (a->V, b->V, x);
345 dest->R = BLEND (a->R, b->R, x);
346 dest->G = BLEND (a->G, b->G, x);
347 dest->B = BLEND (a->B, b->B, x);
348 dest->gray = BLEND (a->gray, b->gray, x);
349
350 }
351 #endif
352
353 static void
videotestsrc_blend_line(GstVideoTestSrc * v,guint8 * dest,const guint8 * src,const struct vts_color_struct * a,const struct vts_color_struct * b,int x1,int x2)354 videotestsrc_blend_line (GstVideoTestSrc * v, guint8 * dest,
355 const guint8 * src, const struct vts_color_struct *a,
356 const struct vts_color_struct *b, int x1, int x2)
357 {
358 int i;
359 if (v->bayer || GST_VIDEO_INFO_IS_RGB (&v->info)) {
360 for (i = x1; i < x2; i++) {
361 dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
362 dest[i * 4 + 1] = BLEND (a->R, b->R, src[i]);
363 dest[i * 4 + 2] = BLEND (a->G, b->G, src[i]);
364 dest[i * 4 + 3] = BLEND (a->B, b->B, src[i]);
365 }
366 } else {
367 for (i = x1; i < x2; i++) {
368 dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
369 dest[i * 4 + 1] = BLEND (a->Y, b->Y, src[i]);
370 dest[i * 4 + 2] = BLEND (a->U, b->U, src[i]);
371 dest[i * 4 + 3] = BLEND (a->V, b->V, src[i]);
372 }
373 }
374 #undef BLEND
375 }
376
377 void
gst_video_test_src_smpte(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)378 gst_video_test_src_smpte (GstVideoTestSrc * v, GstClockTime pts,
379 GstVideoFrame * frame)
380 {
381 int i;
382 int y1, y2;
383 int j;
384 paintinfo pi = PAINT_INFO_INIT;
385 paintinfo *p = π
386 int w = frame->info.width, h = frame->info.height;
387
388 videotestsrc_setup_paintinfo (v, p, w, h);
389
390 y1 = 2 * h / 3;
391 y2 = 3 * h / 4;
392
393 /* color bars */
394 for (j = 0; j < y1; j++) {
395 for (i = 0; i < 7; i++) {
396 int x1 = i * w / 7;
397 int x2 = (i + 1) * w / 7;
398
399 p->color = p->colors + i;
400 p->paint_tmpline (p, x1, (x2 - x1));
401 }
402 videotestsrc_convert_tmpline (p, frame, j);
403 }
404
405 /* inverse blue bars */
406 for (j = y1; j < y2; j++) {
407 for (i = 0; i < 7; i++) {
408 int x1 = i * w / 7;
409 int x2 = (i + 1) * w / 7;
410 int k;
411
412 if (i & 1) {
413 k = 7;
414 } else {
415 k = 6 - i;
416 }
417 p->color = p->colors + k;
418 p->paint_tmpline (p, x1, (x2 - x1));
419 }
420 videotestsrc_convert_tmpline (p, frame, j);
421 }
422
423 for (j = y2; j < h; j++) {
424 /* -I, white, Q regions */
425 for (i = 0; i < 3; i++) {
426 int x1 = i * w / 6;
427 int x2 = (i + 1) * w / 6;
428 int k;
429
430 if (i == 0) {
431 k = 8;
432 } else if (i == 1) {
433 k = 0;
434 } else
435 k = 9;
436
437 p->color = p->colors + k;
438 p->paint_tmpline (p, x1, (x2 - x1));
439 }
440
441 /* superblack, black, dark grey */
442 for (i = 0; i < 3; i++) {
443 int x1 = w / 2 + i * w / 12;
444 int x2 = w / 2 + (i + 1) * w / 12;
445 int k;
446
447 if (i == 0) {
448 k = COLOR_SUPER_BLACK;
449 } else if (i == 1) {
450 k = COLOR_BLACK;
451 } else
452 k = COLOR_DARK_GREY;
453
454 p->color = p->colors + k;
455 p->paint_tmpline (p, x1, (x2 - x1));
456 }
457
458 {
459 int x1 = w * 3 / 4;
460 struct vts_color_struct color;
461
462 color = p->colors[COLOR_BLACK];
463 p->color = &color;
464
465 for (i = x1; i < w; i++) {
466 int y = random_char (&v->random_state);
467 p->tmpline_u8[i] = y;
468 }
469 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
470 &p->foreground_color, &p->background_color, x1, w);
471
472 }
473 videotestsrc_convert_tmpline (p, frame, j);
474
475 }
476 }
477
478 void
gst_video_test_src_smpte_rp_219(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)479 gst_video_test_src_smpte_rp_219 (GstVideoTestSrc * v, GstClockTime pts,
480 GstVideoFrame * frame)
481 {
482 /* heights */
483 int b, b1;
484 int bs[6]; /* bottom-half 6 rows */
485
486 /* widths */
487 int a, d, k, g, h, m, k1, k2, g1, g2;
488 int cs[7]; /* 'c's and 'f's */
489 int ij[5]; /* parts of 'x' and 'y' */
490 int x, y, x1, x2, y1, y2;
491
492 paintinfo pi = PAINT_INFO_INIT;
493 paintinfo *p = π
494
495 a = frame->info.width;
496 b = frame->info.height;
497
498 videotestsrc_setup_paintinfo (v, p, a, b);
499 p->colors = vts_colors_bt709_ycbcr_rp_219;
500
501 /* heights */
502 {
503 /* error distribution for the bottom 6 rows
504 * x.e., pattern 1 is always shorter when b%12 != 0 */
505 static const int b12_err[6][6] = {
506 {0, 0, 0, 0, 0, 0},
507 {0, 1, 0, 0, 0, 0},
508 {0, 1, 1, 0, 0, 0},
509 {0, 0, 0, 1, 1, 1},
510 {0, 1, 1, 1, 0, 1},
511 {0, 1, 1, 1, 1, 1},
512 };
513
514 int b2, b12, b12_r, x;
515
516 b1 = b / 2;
517 b2 = b - b1;
518
519 b12 = b2 / 6;
520 b12_r = b2 % 6;
521 for (x = 0; x < 6; x++) {
522 bs[x] = b12 + b12_err[b12_r][x];
523 }
524 }
525
526 /* widths */
527 {
528 /* error distribution for 'c' columns */
529 static const int c_w_err[7][7] = {
530 {0, 0, 0, 0, 0, 0, 0},
531 {0, 0, 0, 1, 0, 0, 0},
532 {1, 0, 0, 0, 0, 0, 1},
533 {0, 1, 0, 1, 0, 1, 0},
534 {1, 0, 1, 0, 1, 0, 1},
535 {0, 1, 1, 1, 1, 1, 0},
536 {1, 1, 1, 0, 1, 1, 1}
537 };
538
539 /* error distribution for 'x' column in pattern 4 */
540 static const int i_err[3][3] = {
541 {0, 0, 0},
542 {0, 1, 0},
543 {1, 0, 1}
544 };
545
546 int a34, c, cr, kg, dkg, hijm, hijmd, c3, c3r, i;
547
548 d = a / 8;
549 a34 = a - 2 * d;
550
551 /* 'c's and 'f's */
552 c = a34 / 7;
553 cr = a34 % 7;
554 for (i = 0; i < 7; i++) {
555 cs[i] = c + c_w_err[cr][i];
556 }
557
558 dkg = a / 2;
559 hijmd = a - dkg;
560
561 kg = dkg - d;
562 g = cs[0] + cs[1];
563 k = kg - g;
564 k1 = k / 2;
565 k2 = k - k1;
566 g1 = g / 2;
567 g2 = g - g1;
568
569 hijm = hijmd - d;
570
571 /* i = c = 3 * c3 */
572 c3 = cs[5] / 3;
573 c3r = cs[5] % 3;
574 for (i = 0; i < 3; i++) {
575 ij[i] = c3 + i_err[c3r][i];
576 }
577 ij[3] = ij[1];
578 ij[4] = ij[2];
579
580 m = cs[5]; /* m = c */
581 h = hijm - ij[0] - ij[1] - ij[2] - ij[3] - ij[4] - m;
582 }
583
584 /* pattern 1 */
585 x1 = 0;
586 x2 = d; /* 'd' bar size */
587 p->color = p->colors; /* 40% gray */
588 p->paint_tmpline (p, x1, (x2 - x1));
589
590 x1 = x2;
591 x2 = x1 + cs[0]; /* 'f' bar size */
592 p->color = p->colors + 1; /* 75% white */
593 p->paint_tmpline (p, x1, (x2 - x1));
594
595 x1 = x2;
596 x2 = x1 + cs[1]; /* 'c' bar size */
597 p->color = p->colors + 2; /* 75% yellow */
598 p->paint_tmpline (p, x1, (x2 - x1));
599
600 x1 = x2;
601 x2 = x1 + cs[2]; /* 'c' bar size */
602 p->color = p->colors + 3; /* 75% cyan */
603 p->paint_tmpline (p, x1, (x2 - x1));
604
605 x1 = x2;
606 x2 = x1 + cs[3]; /* 'c' bar size */
607 p->color = p->colors + 4; /* 75% green */
608 p->paint_tmpline (p, x1, (x2 - x1));
609
610 x1 = x2;
611 x2 = x1 + cs[4]; /* 'c' bar size */
612 p->color = p->colors + 5; /* 75% magenta */
613 p->paint_tmpline (p, x1, (x2 - x1));
614
615 x1 = x2;
616 x2 = x1 + cs[5]; /* 'c' bar size */
617 p->color = p->colors + 6; /* 75% red */
618 p->paint_tmpline (p, x1, (x2 - x1));
619
620 x1 = x2;
621 x2 = x1 + cs[6]; /* 'f' bar size */
622 p->color = p->colors + 7; /* 75% blue */
623 p->paint_tmpline (p, x1, (x2 - x1));
624
625 x1 = x2;
626 x2 = x1 + d; /* 'd' bar size */
627 p->color = p->colors; /* 40% gray */
628 p->paint_tmpline (p, x1, (x2 - x1));
629
630 y1 = 0;
631 y2 = b1 + bs[0];
632 for (y = y1; y < y2; y++)
633 videotestsrc_convert_tmpline (p, frame, y);
634
635 /* pattern 2 */
636 x1 = 0;
637 x2 = d;
638 p->color = p->colors + 8; /* 100% cyan */
639 p->paint_tmpline (p, x1, (x2 - x1));
640
641 x1 = x2;
642 x2 = x1 + cs[0];
643 p->color = p->colors + 11; /* *2: -I, +Q in *3 */
644 p->paint_tmpline (p, x1, (x2 - x1));
645
646 x1 = x2;
647 x2 = x1 + cs[1] + cs[2] + cs[3] + cs[4] + cs[5] + cs[6];
648 p->color = p->colors + 1; /* 75% white */
649 p->paint_tmpline (p, x1, (x2 - x1));
650
651 x1 = x2;
652 x2 = x1 + d;
653 p->color = p->colors + 12; /* 100% blue */
654 p->paint_tmpline (p, x1, (x2 - x1));
655
656 y1 = y2;
657 y2 = y1 + bs[1];
658 for (y = y1; y < y2; y++)
659 videotestsrc_convert_tmpline (p, frame, y);
660
661 /* pattern 3 */
662 x1 = 0;
663 x2 = d;
664 p->color = p->colors + 13; /* 100% yellow */
665 p->paint_tmpline (p, x1, (x2 - x1));
666
667 x1 = x2;
668 x2 = x1 + cs[0];
669 p->color = p->colors + 15; /* *3: +Q, -I in *2 */
670 p->paint_tmpline (p, x1, (x2 - x1));
671
672 /* Y-Ramp, from row 14 to row 9 */
673 x1 = x2;
674 x2 = x1 + cs[1] + cs[2] + cs[3] + cs[4] + cs[5];
675 for (x = x1; x < x2; x++)
676 p->tmpline_u8[x] = 255 * (x - x1) / (x2 - x1);
677 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8, p->colors + 9,
678 p->colors + 14, x1, x2);
679
680 x1 = x2;
681 x2 = x1 + cs[6];
682 p->color = p->colors + 9; /* 100% white */
683 p->paint_tmpline (p, x1, (x2 - x1));
684
685 x1 = x2;
686 x2 = x1 + d;
687 p->color = p->colors + 16; /* 100% red */
688 p->paint_tmpline (p, x1, (x2 - x1));
689
690 y1 = y2;
691 y2 = y1 + bs[2];
692 for (y = y1; y < y2; y++)
693 videotestsrc_convert_tmpline (p, frame, y);
694
695 /* pattern 4, subdivision 1 */
696 x1 = 0;
697 x2 = d;
698 p->color = p->colors + 17; /* *4: 15% gray */
699 p->paint_tmpline (p, x1, (x2 - x1));
700
701 x1 = x2;
702 x2 = x1 + k; /* 3 sub divisions */
703 p->color = p->colors + 14; /* 0% black */
704 p->paint_tmpline (p, x1, (x2 - x1));
705
706 x1 = x2;
707 x2 = x1 + g; /* 3 sub divisions */
708 p->color = p->colors + 9; /* 100% white */
709 p->paint_tmpline (p, x1, (x2 - x1));
710
711 x1 = x2;
712 x2 = x1 + h;
713 p->color = p->colors + 14; /* 0% black */
714 p->paint_tmpline (p, x1, (x2 - x1));
715
716 x1 = x2;
717 x2 = x1 + ij[0];
718 p->color = p->colors + 20; /* -2% black */
719 p->paint_tmpline (p, x1, (x2 - x1));
720
721 x1 = x2;
722 x2 = x1 + ij[1];
723 p->color = p->colors + 14; /* 0% black */
724 p->paint_tmpline (p, x1, (x2 - x1));
725
726 x1 = x2;
727 x2 = x1 + ij[2];
728 p->color = p->colors + 21; /* +2% black */
729 p->paint_tmpline (p, x1, (x2 - x1));
730
731 x1 = x2;
732 x2 = x1 + ij[3];
733 p->color = p->colors + 20; /* 0% black */
734 p->paint_tmpline (p, x1, (x2 - x1));
735
736 x1 = x2;
737 x2 = x1 + ij[4];
738 p->color = p->colors + 22; /* +4% black */
739 p->paint_tmpline (p, x1, (x2 - x1));
740
741 x1 = x2;
742 x2 = x1 + m;
743 p->color = p->colors + 14; /* 0% black */
744 p->paint_tmpline (p, x1, (x2 - x1));
745
746 x1 = x2;
747 x2 = x1 + d;
748 p->color = p->colors + 17; /* *4: 15% gray */
749 p->paint_tmpline (p, x1, (x2 - x1));
750
751 y1 = y2;
752 y2 = y1 + bs[3];
753 for (y = y1; y < y2; y++)
754 videotestsrc_convert_tmpline (p, frame, y);
755
756 /* pattern 4, subdivision 2 */
757
758 /* *5: sub-black valley, from row 14 to row 18 (first half) */
759 x1 = d;
760 x2 = x1 + k1;
761 for (x = x1; x < x2; x++)
762 p->tmpline_u8[x] = 255 * (x - x1) / (x2 - x1);
763 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8, p->colors + 18,
764 p->colors + 14, x1, x2);
765
766 /* *5: sub-black valley, from row 18 to row 14 (second half) */
767 x1 = x2;
768 x2 = x1 + k2;
769 for (x = x1; x < x2; x++)
770 p->tmpline_u8[x] = 255 * (x - x1) / (x2 - x1);
771 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8, p->colors + 14,
772 p->colors + 18, x1, x2);
773
774 /* *6: super-white peak, from row 9 to row 19 (first half) */
775 x1 = x2;
776 x2 = x1 + g1;
777 for (x = x1; x < x2; x++)
778 p->tmpline_u8[x] = 255 * (x - x1) / (x2 - x1);
779 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8, p->colors + 19,
780 p->colors + 9, x1, x2);
781
782 /* *6: super-white peak, from row 19 to row 9 (second half) */
783 x1 = x2;
784 x2 = x1 + g2;
785 for (x = x1; x < x2; x++)
786 p->tmpline_u8[x] = 255 * (x - x1) / (x2 - x1);
787 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8, p->colors + 9,
788 p->colors + 19, x1, x2);
789
790 y1 = y2;
791 y2 = y1 + bs[4];
792 for (y = y1; y < y2; y++)
793 videotestsrc_convert_tmpline (p, frame, y);
794
795 /* pattern 4, subdivision 3 */
796 x1 = d;
797 x2 = x1 + k;
798 p->color = p->colors + 14; /* 0% black */
799 p->paint_tmpline (p, x1, (x2 - x1));
800
801 x1 = x2;
802 x2 = x1 + g;
803 p->color = p->colors + 9; /* 100% white */
804 p->paint_tmpline (p, x1, (x2 - x1));
805
806 y1 = y2;
807 y2 = y1 + bs[5];
808 for (y = y1; y < y2; y++)
809 videotestsrc_convert_tmpline (p, frame, y);
810 }
811
812 void
gst_video_test_src_smpte75(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)813 gst_video_test_src_smpte75 (GstVideoTestSrc * v, GstClockTime pts,
814 GstVideoFrame * frame)
815 {
816 int i;
817 int j;
818 paintinfo pi = PAINT_INFO_INIT;
819 paintinfo *p = π
820 int w = frame->info.width, h = frame->info.height;
821
822 videotestsrc_setup_paintinfo (v, p, w, h);
823 if (v->info.colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
824 p->colors = vts_colors_bt601_ycbcr_75;
825 } else {
826 p->colors = vts_colors_bt709_ycbcr_75;
827 }
828
829 /* color bars */
830 for (j = 0; j < h; j++) {
831 for (i = 0; i < 7; i++) {
832 int x1 = i * w / 7;
833 int x2 = (i + 1) * w / 7;
834
835 p->color = p->colors + i;
836 p->paint_tmpline (p, x1, (x2 - x1));
837 }
838 videotestsrc_convert_tmpline (p, frame, j);
839 }
840 }
841
842 void
gst_video_test_src_smpte100(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)843 gst_video_test_src_smpte100 (GstVideoTestSrc * v, GstClockTime pts,
844 GstVideoFrame * frame)
845 {
846 int i;
847 int j;
848 paintinfo pi = PAINT_INFO_INIT;
849 paintinfo *p = π
850 int w = frame->info.width, h = frame->info.height;
851
852 videotestsrc_setup_paintinfo (v, p, w, h);
853
854 /* color bars */
855 for (j = 0; j < h; j++) {
856 for (i = 0; i < 7; i++) {
857 int x1 = i * w / 7;
858 int x2 = (i + 1) * w / 7;
859
860 p->color = p->colors + i;
861 p->paint_tmpline (p, x1, (x2 - x1));
862 }
863 videotestsrc_convert_tmpline (p, frame, j);
864 }
865 }
866
867 void
gst_video_test_src_bar(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)868 gst_video_test_src_bar (GstVideoTestSrc * v, GstClockTime pts,
869 GstVideoFrame * frame)
870 {
871 int j;
872 paintinfo pi = PAINT_INFO_INIT;
873 paintinfo *p = π
874 int w = frame->info.width, h = frame->info.height;
875
876 videotestsrc_setup_paintinfo (v, p, w, h);
877
878 for (j = 0; j < h; j++) {
879 /* use fixed size for now */
880 int x2 = w / 7;
881
882 p->color = &p->foreground_color;
883 p->paint_tmpline (p, 0, x2);
884 p->color = &p->background_color;
885 p->paint_tmpline (p, x2, (w - x2));
886 videotestsrc_convert_tmpline (p, frame, j);
887 }
888 }
889
890 void
gst_video_test_src_snow(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)891 gst_video_test_src_snow (GstVideoTestSrc * v, GstClockTime pts,
892 GstVideoFrame * frame)
893 {
894 int i;
895 int j;
896 paintinfo pi = PAINT_INFO_INIT;
897 paintinfo *p = π
898 struct vts_color_struct color;
899 int w = frame->info.width, h = frame->info.height;
900
901 videotestsrc_setup_paintinfo (v, p, w, h);
902
903 color = p->colors[COLOR_BLACK];
904 p->color = &color;
905
906 for (j = 0; j < h; j++) {
907 for (i = 0; i < w; i++) {
908 int y = random_char (&v->random_state);
909 p->tmpline_u8[i] = y;
910 }
911 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
912 &p->foreground_color, &p->background_color, 0, w);
913 videotestsrc_convert_tmpline (p, frame, j);
914 }
915 }
916
917 static void
gst_video_test_src_unicolor(GstVideoTestSrc * v,GstVideoFrame * frame,int color_index)918 gst_video_test_src_unicolor (GstVideoTestSrc * v, GstVideoFrame * frame,
919 int color_index)
920 {
921 int i;
922 paintinfo pi = PAINT_INFO_INIT;
923 paintinfo *p = π
924 int w = frame->info.width, h = frame->info.height;
925
926 videotestsrc_setup_paintinfo (v, p, w, h);
927
928 p->color = p->colors + color_index;
929 if (color_index == COLOR_BLACK) {
930 p->color = &p->background_color;
931 }
932 if (color_index == COLOR_WHITE) {
933 p->color = &p->foreground_color;
934 }
935
936 for (i = 0; i < h; i++) {
937 p->paint_tmpline (p, 0, w);
938 videotestsrc_convert_tmpline (p, frame, i);
939 }
940 }
941
942 void
gst_video_test_src_black(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)943 gst_video_test_src_black (GstVideoTestSrc * v, GstClockTime pts,
944 GstVideoFrame * frame)
945 {
946 gst_video_test_src_unicolor (v, frame, COLOR_BLACK);
947 }
948
949 void
gst_video_test_src_white(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)950 gst_video_test_src_white (GstVideoTestSrc * v, GstClockTime pts,
951 GstVideoFrame * frame)
952 {
953 gst_video_test_src_unicolor (v, frame, COLOR_WHITE);
954 }
955
956 void
gst_video_test_src_red(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)957 gst_video_test_src_red (GstVideoTestSrc * v, GstClockTime pts,
958 GstVideoFrame * frame)
959 {
960 gst_video_test_src_unicolor (v, frame, COLOR_RED);
961 }
962
963 void
gst_video_test_src_green(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)964 gst_video_test_src_green (GstVideoTestSrc * v, GstClockTime pts,
965 GstVideoFrame * frame)
966 {
967 gst_video_test_src_unicolor (v, frame, COLOR_GREEN);
968 }
969
970 void
gst_video_test_src_blue(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)971 gst_video_test_src_blue (GstVideoTestSrc * v, GstClockTime pts,
972 GstVideoFrame * frame)
973 {
974 gst_video_test_src_unicolor (v, frame, COLOR_BLUE);
975 }
976
977 void
gst_video_test_src_blink(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)978 gst_video_test_src_blink (GstVideoTestSrc * v, GstClockTime pts,
979 GstVideoFrame * frame)
980 {
981 int i;
982 paintinfo pi = PAINT_INFO_INIT;
983 paintinfo *p = π
984 int w = frame->info.width, h = frame->info.height;
985
986 videotestsrc_setup_paintinfo (v, p, w, h);
987
988 if (v->n_frames & 1) {
989 p->color = &p->foreground_color;
990 } else {
991 p->color = &p->background_color;
992 }
993
994 for (i = 0; i < h; i++) {
995 p->paint_tmpline (p, 0, w);
996 videotestsrc_convert_tmpline (p, frame, i);
997 }
998 }
999
1000 void
gst_video_test_src_solid(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1001 gst_video_test_src_solid (GstVideoTestSrc * v, GstClockTime pts,
1002 GstVideoFrame * frame)
1003 {
1004 int i;
1005 paintinfo pi = PAINT_INFO_INIT;
1006 paintinfo *p = π
1007 int w = frame->info.width, h = frame->info.height;
1008
1009 videotestsrc_setup_paintinfo (v, p, w, h);
1010
1011 p->color = &p->foreground_color;
1012
1013 for (i = 0; i < h; i++) {
1014 p->paint_tmpline (p, 0, w);
1015 videotestsrc_convert_tmpline (p, frame, i);
1016 }
1017 }
1018
1019 void
gst_video_test_src_checkers1(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1020 gst_video_test_src_checkers1 (GstVideoTestSrc * v, GstClockTime pts,
1021 GstVideoFrame * frame)
1022 {
1023 int x, y;
1024 paintinfo pi = PAINT_INFO_INIT;
1025 paintinfo *p = π
1026 int w = frame->info.width, h = frame->info.height;
1027
1028 videotestsrc_setup_paintinfo (v, p, w, h);
1029
1030 for (y = 0; y < h; y++) {
1031 for (x = 0; x < w; x++) {
1032 if ((x ^ y) & 1) {
1033 p->color = p->colors + COLOR_GREEN;
1034 } else {
1035 p->color = p->colors + COLOR_RED;
1036 }
1037 p->paint_tmpline (p, x, 1);
1038 }
1039 videotestsrc_convert_tmpline (p, frame, y);
1040 }
1041 }
1042
1043 void
gst_video_test_src_checkers2(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1044 gst_video_test_src_checkers2 (GstVideoTestSrc * v, GstClockTime pts,
1045 GstVideoFrame * frame)
1046 {
1047 int x, y;
1048 paintinfo pi = PAINT_INFO_INIT;
1049 paintinfo *p = π
1050 int w = frame->info.width, h = frame->info.height;
1051
1052 videotestsrc_setup_paintinfo (v, p, w, h);
1053
1054 for (y = 0; y < h; y++) {
1055 for (x = 0; x < w; x += 2) {
1056 guint len = MIN (2, w - x);
1057
1058 if ((x ^ y) & 2) {
1059 p->color = p->colors + COLOR_GREEN;
1060 } else {
1061 p->color = p->colors + COLOR_RED;
1062 }
1063 p->paint_tmpline (p, x, len);
1064 }
1065 videotestsrc_convert_tmpline (p, frame, y);
1066 }
1067 }
1068
1069 void
gst_video_test_src_checkers4(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1070 gst_video_test_src_checkers4 (GstVideoTestSrc * v, GstClockTime pts,
1071 GstVideoFrame * frame)
1072 {
1073 int x, y;
1074 paintinfo pi = PAINT_INFO_INIT;
1075 paintinfo *p = π
1076 int w = frame->info.width, h = frame->info.height;
1077
1078 videotestsrc_setup_paintinfo (v, p, w, h);
1079
1080 for (y = 0; y < h; y++) {
1081 for (x = 0; x < w; x += 4) {
1082 guint len = MIN (4, w - x);
1083
1084 if ((x ^ y) & 4) {
1085 p->color = p->colors + COLOR_GREEN;
1086 } else {
1087 p->color = p->colors + COLOR_RED;
1088 }
1089 p->paint_tmpline (p, x, len);
1090 }
1091 videotestsrc_convert_tmpline (p, frame, y);
1092 }
1093 }
1094
1095 void
gst_video_test_src_checkers8(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1096 gst_video_test_src_checkers8 (GstVideoTestSrc * v, GstClockTime pts,
1097 GstVideoFrame * frame)
1098 {
1099 int x, y;
1100 paintinfo pi = PAINT_INFO_INIT;
1101 paintinfo *p = π
1102 int w = frame->info.width, h = frame->info.height;
1103
1104 videotestsrc_setup_paintinfo (v, p, w, h);
1105
1106 for (y = 0; y < h; y++) {
1107 for (x = 0; x < w; x += 8) {
1108 guint len = MIN (8, w - x);
1109
1110 if ((x ^ y) & 8) {
1111 p->color = p->colors + COLOR_GREEN;
1112 } else {
1113 p->color = p->colors + COLOR_RED;
1114 }
1115 p->paint_tmpline (p, x, len);
1116 }
1117 videotestsrc_convert_tmpline (p, frame, y);
1118 }
1119 }
1120
1121 static const guint8 sine_table[256] = {
1122 128, 131, 134, 137, 140, 143, 146, 149,
1123 152, 156, 159, 162, 165, 168, 171, 174,
1124 176, 179, 182, 185, 188, 191, 193, 196,
1125 199, 201, 204, 206, 209, 211, 213, 216,
1126 218, 220, 222, 224, 226, 228, 230, 232,
1127 234, 236, 237, 239, 240, 242, 243, 245,
1128 246, 247, 248, 249, 250, 251, 252, 252,
1129 253, 254, 254, 255, 255, 255, 255, 255,
1130 255, 255, 255, 255, 255, 255, 254, 254,
1131 253, 252, 252, 251, 250, 249, 248, 247,
1132 246, 245, 243, 242, 240, 239, 237, 236,
1133 234, 232, 230, 228, 226, 224, 222, 220,
1134 218, 216, 213, 211, 209, 206, 204, 201,
1135 199, 196, 193, 191, 188, 185, 182, 179,
1136 176, 174, 171, 168, 165, 162, 159, 156,
1137 152, 149, 146, 143, 140, 137, 134, 131,
1138 128, 124, 121, 118, 115, 112, 109, 106,
1139 103, 99, 96, 93, 90, 87, 84, 81,
1140 79, 76, 73, 70, 67, 64, 62, 59,
1141 56, 54, 51, 49, 46, 44, 42, 39,
1142 37, 35, 33, 31, 29, 27, 25, 23,
1143 21, 19, 18, 16, 15, 13, 12, 10,
1144 9, 8, 7, 6, 5, 4, 3, 3,
1145 2, 1, 1, 0, 0, 0, 0, 0,
1146 0, 0, 0, 0, 0, 0, 1, 1,
1147 2, 3, 3, 4, 5, 6, 7, 8,
1148 9, 10, 12, 13, 15, 16, 18, 19,
1149 21, 23, 25, 27, 29, 31, 33, 35,
1150 37, 39, 42, 44, 46, 49, 51, 54,
1151 56, 59, 62, 64, 67, 70, 73, 76,
1152 79, 81, 84, 87, 90, 93, 96, 99,
1153 103, 106, 109, 112, 115, 118, 121, 124
1154 };
1155
1156
1157 void
gst_video_test_src_zoneplate(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1158 gst_video_test_src_zoneplate (GstVideoTestSrc * v, GstClockTime pts,
1159 GstVideoFrame * frame)
1160 {
1161 int i;
1162 int j;
1163 paintinfo pi = PAINT_INFO_INIT;
1164 paintinfo *p = π
1165 struct vts_color_struct color;
1166 int t = v->n_frames;
1167 int w = frame->info.width, h = frame->info.height;
1168 int xreset = -(w / 2) - v->xoffset; /* starting values for x^2 and y^2, centering the ellipse */
1169 int yreset = -(h / 2) - v->yoffset;
1170
1171 int x, y;
1172 int accum_kx;
1173 int accum_kxt;
1174 int accum_ky;
1175 int accum_kyt;
1176 int accum_kxy;
1177 int kt;
1178 int kt2;
1179 int ky2;
1180 int delta_kxt = v->kxt * t;
1181 int delta_kxy;
1182 int scale_kxy = 0xffff / (w / 2);
1183 int scale_kx2 = 0xffff / w;
1184
1185 videotestsrc_setup_paintinfo (v, p, w, h);
1186
1187 color = p->colors[COLOR_BLACK];
1188 p->color = &color;
1189
1190 /* Zoneplate equation:
1191 *
1192 * phase = k0 + kx*x + ky*y + kt*t
1193 * + kxt*x*t + kyt*y*t + kxy*x*y
1194 * + kx2*x*x + ky2*y*y + Kt2*t*t
1195 */
1196
1197 #if 0
1198 for (j = 0, y = yreset; j < h; j++, y++) {
1199 for (i = 0, x = xreset; i < w; i++, x++) {
1200
1201 /* zero order */
1202 int phase = v->k0;
1203
1204 /* first order */
1205 phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
1206
1207 /* cross term */
1208 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1209 /* phase = phase + (v->kxy * x * y) / (w/2); */
1210
1211 /*second order */
1212 /*normalise x/y terms to rate of change of phase at the picture edge */
1213 phase =
1214 phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
1215 ((v->kt2 * t * t) >> 1);
1216
1217 color.Y = sine_table[phase & 0xff];
1218
1219 color.R = color.Y;
1220 color.G = color.Y;
1221 color.B = color.Y;
1222 p->paint_tmpline (p, i, 1);
1223 }
1224 }
1225 #endif
1226
1227 /* optimised version, with original code shown in comments */
1228 accum_ky = 0;
1229 accum_kyt = 0;
1230 kt = v->kt * t;
1231 kt2 = v->kt2 * t * t;
1232 for (j = 0, y = yreset; j < h; j++, y++) {
1233 accum_kx = 0;
1234 accum_kxt = 0;
1235 accum_ky += v->ky;
1236 accum_kyt += v->kyt * t;
1237 delta_kxy = v->kxy * y * scale_kxy;
1238 accum_kxy = delta_kxy * xreset;
1239 ky2 = (v->ky2 * y * y) / h;
1240 for (i = 0, x = xreset; i < w; i++, x++) {
1241
1242 /* zero order */
1243 int phase = v->k0;
1244
1245 /* first order */
1246 accum_kx += v->kx;
1247 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1248 phase = phase + accum_kx + accum_ky + kt;
1249
1250 /* cross term */
1251 accum_kxt += delta_kxt;
1252 accum_kxy += delta_kxy;
1253 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1254 phase = phase + accum_kxt + accum_kyt;
1255
1256 /* phase = phase + (v->kxy * x * y) / (w/2); */
1257 /* phase = phase + accum_kxy / (w/2); */
1258 phase = phase + (accum_kxy >> 16);
1259
1260 /*second order */
1261 /*normalise x/y terms to rate of change of phase at the picture edge */
1262 /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1263 phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1264
1265 p->tmpline_u8[i] = sine_table[phase & 0xff];
1266 }
1267 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1268 &p->foreground_color, &p->background_color, 0, w);
1269 videotestsrc_convert_tmpline (p, frame, j);
1270 }
1271 }
1272
1273 void
gst_video_test_src_chromazoneplate(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1274 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, GstClockTime pts,
1275 GstVideoFrame * frame)
1276 {
1277 int i;
1278 int j;
1279 paintinfo pi = PAINT_INFO_INIT;
1280 paintinfo *p = π
1281 struct vts_color_struct color;
1282 int t = v->n_frames;
1283 int w = frame->info.width, h = frame->info.height;
1284
1285 int xreset = -(w / 2) - v->xoffset; /* starting values for x^2 and y^2, centering the ellipse */
1286 int yreset = -(h / 2) - v->yoffset;
1287
1288 int x, y;
1289 int accum_kx;
1290 int accum_kxt;
1291 int accum_ky;
1292 int accum_kyt;
1293 int accum_kxy;
1294 int kt;
1295 int kt2;
1296 int ky2;
1297 int delta_kxt = v->kxt * t;
1298 int delta_kxy;
1299 int scale_kxy = 0xffff / (w / 2);
1300 int scale_kx2 = 0xffff / w;
1301
1302 videotestsrc_setup_paintinfo (v, p, w, h);
1303
1304 color = p->colors[COLOR_BLACK];
1305 p->color = &color;
1306
1307 /* Zoneplate equation:
1308 *
1309 * phase = k0 + kx*x + ky*y + kt*t
1310 * + kxt*x*t + kyt*y*t + kxy*x*y
1311 * + kx2*x*x + ky2*y*y + Kt2*t*t
1312 */
1313
1314 /* optimised version, with original code shown in comments */
1315 accum_ky = 0;
1316 accum_kyt = 0;
1317 kt = v->kt * t;
1318 kt2 = v->kt2 * t * t;
1319 for (j = 0, y = yreset; j < h; j++, y++) {
1320 accum_kx = 0;
1321 accum_kxt = 0;
1322 accum_ky += v->ky;
1323 accum_kyt += v->kyt * t;
1324 delta_kxy = v->kxy * y * scale_kxy;
1325 accum_kxy = delta_kxy * xreset;
1326 ky2 = (v->ky2 * y * y) / h;
1327 for (i = 0, x = xreset; i < w; i++, x++) {
1328
1329 /* zero order */
1330 int phase = v->k0;
1331
1332 /* first order */
1333 accum_kx += v->kx;
1334 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1335 phase = phase + accum_kx + accum_ky + kt;
1336
1337 /* cross term */
1338 accum_kxt += delta_kxt;
1339 accum_kxy += delta_kxy;
1340 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1341 phase = phase + accum_kxt + accum_kyt;
1342
1343 /* phase = phase + (v->kxy * x * y) / (w/2); */
1344 /* phase = phase + accum_kxy / (w/2); */
1345 phase = phase + (accum_kxy >> 16);
1346
1347 /*second order */
1348 /*normalise x/y terms to rate of change of phase at the picture edge */
1349 /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1350 phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1351
1352 color.Y = 128;
1353 color.U = sine_table[phase & 0xff];
1354 color.V = sine_table[phase & 0xff];
1355
1356 color.R = 128;
1357 color.G = 128;
1358 color.B = color.V;
1359
1360 color.gray = color.Y << 8;
1361 p->paint_tmpline (p, i, 1);
1362 }
1363 videotestsrc_convert_tmpline (p, frame, j);
1364 }
1365 }
1366
1367 #undef SCALE_AMPLITUDE
1368 void
gst_video_test_src_circular(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1369 gst_video_test_src_circular (GstVideoTestSrc * v, GstClockTime pts,
1370 GstVideoFrame * frame)
1371 {
1372 int i;
1373 int j;
1374 paintinfo pi = PAINT_INFO_INIT;
1375 paintinfo *p = π
1376 double freq[8];
1377 int w = frame->info.width, h = frame->info.height;
1378
1379 int d;
1380
1381 videotestsrc_setup_paintinfo (v, p, w, h);
1382
1383 for (i = 1; i < 8; i++) {
1384 freq[i] = 200 * pow (2.0, -(i - 1) / 4.0);
1385 }
1386
1387 for (j = 0; j < h; j++) {
1388 for (i = 0; i < w; i++) {
1389 double dist;
1390 int seg;
1391
1392 dist =
1393 sqrt ((2 * i - w) * (2 * i - w) + (2 * j - h) * (2 * j -
1394 h)) / (2 * w);
1395 seg = floor (dist * 16);
1396 if (seg == 0 || seg >= 8) {
1397 p->tmpline_u8[i] = 0;
1398 } else {
1399 d = floor (256 * dist * freq[seg] + 0.5);
1400 p->tmpline_u8[i] = sine_table[d & 0xff];
1401 }
1402 }
1403 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1404 &p->foreground_color, &p->background_color, 0, w);
1405 videotestsrc_convert_tmpline (p, frame, j);
1406 }
1407 }
1408
1409 void
gst_video_test_src_gamut(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1410 gst_video_test_src_gamut (GstVideoTestSrc * v, GstClockTime pts,
1411 GstVideoFrame * frame)
1412 {
1413 int x, y;
1414 paintinfo pi = PAINT_INFO_INIT;
1415 paintinfo *p = π
1416 struct vts_color_struct yuv_primary;
1417 struct vts_color_struct yuv_secondary;
1418 int w = frame->info.width, h = frame->info.height;
1419
1420 videotestsrc_setup_paintinfo (v, p, w, h);
1421
1422 for (y = 0; y < h; y++) {
1423 int region = (y * 4) / h;
1424
1425 switch (region) {
1426 case 0: /* black */
1427 yuv_primary = p->colors[COLOR_BLACK];
1428 yuv_secondary = p->colors[COLOR_BLACK];
1429 yuv_secondary.Y = 0;
1430 break;
1431 case 1:
1432 yuv_primary = p->colors[COLOR_WHITE];
1433 yuv_secondary = p->colors[COLOR_WHITE];
1434 yuv_secondary.Y = 255;
1435 break;
1436 case 2:
1437 yuv_primary = p->colors[COLOR_RED];
1438 yuv_secondary = p->colors[COLOR_RED];
1439 yuv_secondary.V = 255;
1440 break;
1441 case 3:
1442 yuv_primary = p->colors[COLOR_BLUE];
1443 yuv_secondary = p->colors[COLOR_BLUE];
1444 yuv_secondary.U = 255;
1445 break;
1446 }
1447
1448 for (x = 0; x < w; x += 8) {
1449 int len = MIN (8, w - x);
1450
1451 if ((x ^ y) & (1 << 4)) {
1452 p->color = &yuv_primary;
1453 } else {
1454 p->color = &yuv_secondary;
1455 }
1456 p->paint_tmpline (p, x, len);
1457 }
1458 videotestsrc_convert_tmpline (p, frame, y);
1459 }
1460 }
1461
1462 void
gst_video_test_src_ball(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1463 gst_video_test_src_ball (GstVideoTestSrc * v, GstClockTime pts,
1464 GstVideoFrame * frame)
1465 {
1466 int i;
1467 int radius = 20;
1468 int w = frame->info.width, h = frame->info.height;
1469 gint64 wall_time;
1470 gdouble rad = 0;
1471 double x, y;
1472 int flipit = 0;
1473
1474 paintinfo pi = PAINT_INFO_INIT;
1475 paintinfo *p = π
1476
1477 struct vts_color_struct
1478 *foreground_color = &p->foreground_color,
1479 *background_color = &p->background_color;
1480
1481 switch (v->animation_mode) {
1482 case GST_VIDEO_TEST_SRC_FRAMES:
1483 rad = (gdouble) (v->n_frames) / 200;
1484 flipit = (v->n_frames / 50) % 2;
1485 break;
1486 case GST_VIDEO_TEST_SRC_WALL_TIME:
1487 wall_time = g_get_real_time ();
1488
1489 rad = (gdouble) wall_time / 1000000.0;
1490 flipit = (wall_time / 1000000) % 2;
1491 break;
1492 case GST_VIDEO_TEST_SRC_RUNNING_TIME:
1493 rad = (gdouble) (pts) / GST_SECOND;
1494 flipit = (pts / GST_SECOND) % 2;
1495 break;
1496 }
1497 if (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP) {
1498 /* Periodic reset for half sweep */
1499 rad /= 2;
1500 rad -= floor (2 * rad) / 2;
1501 }
1502
1503 /* Scale for the animation calcs */
1504 rad = 2 * G_PI * rad;
1505
1506 if (v->motion_type == GST_VIDEO_TEST_SRC_WAVY) {
1507 x = radius + (0.5 + 0.5 * sin (rad)) * (w - 2 * radius);
1508 y = radius + (0.5 + 0.5 * sin (rad * sqrt (2))) * (h - 2 * radius);
1509 } else {
1510 /* sweep and hsweep */
1511 /* x,y is center of circle,
1512 * radius is radius
1513 * rad = angle .. of sweep.
1514 */
1515
1516 radius = MIN (h, w) / 4 - 0;
1517
1518 /* 0 is the margin between edge of screen and top of ball */
1519 x = w / 2 + sin (rad) * radius;
1520 y = h / 2 - cos (rad) * radius;
1521 }
1522
1523 if (v->flip && flipit) {
1524 foreground_color = &p->background_color;
1525 background_color = &p->foreground_color;
1526 }
1527
1528 /* draw ball on frame */
1529 videotestsrc_setup_paintinfo (v, p, w, h);
1530 for (i = 0; i < h; i++) {
1531 if (i < y - radius || i > y + radius) {
1532 memset (p->tmpline_u8, 0, w);
1533 } else {
1534 double o = MAX (0, (radius * radius - (i - y) * (i - y)));
1535 int r = rint (sqrt (o));
1536 int x1, x2;
1537 int j;
1538
1539 x1 = 0;
1540 x2 = MAX (0, x - r);
1541 for (j = x1; j < x2; j++) {
1542 p->tmpline_u8[j] = 0;
1543 }
1544
1545 x1 = MAX (0, x - r);
1546 x2 = MIN (w, x + r + 1);
1547 for (j = x1; j < x2; j++) {
1548 double rr = radius - sqrt ((j - x) * (j - x) + (i - y) * (i - y));
1549
1550 rr *= 0.5;
1551 p->tmpline_u8[j] = CLAMP ((int) floor (256 * rr), 0, 255);
1552 }
1553
1554 x1 = MIN (w, x + r + 1);
1555 x2 = w;
1556 for (j = x1; j < x2; j++) {
1557 p->tmpline_u8[j] = 0;
1558 }
1559 }
1560
1561 if ((v->motion_type == GST_VIDEO_TEST_SRC_SWEEP) ||
1562 (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP)) {
1563 /* dot in the middle (to draw a line down the center) */
1564 p->tmpline_u8[w / 2] = 255;
1565 p->tmpline_u8[(int) x] = 255;
1566 }
1567
1568 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1569 foreground_color, background_color, 0, w);
1570 videotestsrc_convert_tmpline (p, frame, i);
1571 }
1572
1573 if ((v->motion_type == GST_VIDEO_TEST_SRC_SWEEP) ||
1574 (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP)) {
1575 /* draw a line across the middle of frame and ball. */
1576 for (i = 0; i < w; i++) {
1577 p->tmpline_u8[i] = 255;
1578 }
1579 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1580 foreground_color, background_color, 0, w);
1581 videotestsrc_convert_tmpline (p, frame, h / 2);
1582 videotestsrc_convert_tmpline (p, frame, y);
1583 }
1584 }
1585
1586 static void
paint_tmpline_ARGB(paintinfo * p,int x,int w)1587 paint_tmpline_ARGB (paintinfo * p, int x, int w)
1588 {
1589 int offset;
1590 guint32 value;
1591
1592 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1593 value = (p->color->A << 0) | (p->color->R << 8) |
1594 (p->color->G << 16) | ((guint32) p->color->B << 24);
1595 #else
1596 value = ((guint32) p->color->A << 24) | (p->color->R << 16) |
1597 (p->color->G << 8) | (p->color->B << 0);
1598 #endif
1599
1600 offset = (x * 4);
1601 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1602 }
1603
1604 static void
paint_tmpline_AYUV(paintinfo * p,int x,int w)1605 paint_tmpline_AYUV (paintinfo * p, int x, int w)
1606 {
1607 int offset;
1608 guint32 value;
1609
1610 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1611 value = (p->color->A << 0) | (p->color->Y << 8) |
1612 (p->color->U << 16) | ((guint32) p->color->V << 24);
1613 #else
1614 value = ((guint32) p->color->A << 24) | (p->color->Y << 16) |
1615 (p->color->U << 8) | (p->color->V << 0);
1616 #endif
1617
1618 offset = (x * 4);
1619 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1620 }
1621
1622 static void
convert_hline_generic(paintinfo * p,GstVideoFrame * frame,int y)1623 convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y)
1624 {
1625 const GstVideoFormatInfo *finfo, *uinfo;
1626 gint line, offset, i, width, height, bits;
1627 guint n_lines;
1628 gpointer dest;
1629
1630 finfo = frame->info.finfo;
1631 uinfo = gst_video_format_get_info (finfo->unpack_format);
1632
1633 width = GST_VIDEO_FRAME_WIDTH (frame);
1634 height = GST_VIDEO_FRAME_HEIGHT (frame);
1635
1636 bits = GST_VIDEO_FORMAT_INFO_DEPTH (uinfo, 0);
1637
1638 n_lines = p->n_lines;
1639 offset = p->offset;
1640 line = y % n_lines;
1641 dest = p->lines[line];
1642
1643 if (bits == 16) {
1644 /* 16 bits */
1645 for (i = 0; i < width; i++) {
1646 p->tmpline_u16[i * 4 + 0] = TO_16 (p->tmpline[i * 4 + 0]);
1647 p->tmpline_u16[i * 4 + 1] = TO_16 (p->tmpline[i * 4 + 1]);
1648 p->tmpline_u16[i * 4 + 2] = TO_16 (p->tmpline[i * 4 + 2]);
1649 p->tmpline_u16[i * 4 + 3] = TO_16 (p->tmpline[i * 4 + 3]);
1650 }
1651 memcpy (dest, p->tmpline_u16, width * 8);
1652 } else {
1653 memcpy (dest, p->tmpline, width * 4);
1654 }
1655
1656 if (line - offset == n_lines - 1) {
1657 gpointer lines[8];
1658 guint idx;
1659
1660 y -= n_lines - 1;
1661
1662 for (i = 0; i < n_lines; i++) {
1663 idx = CLAMP (y + i + offset, 0, height - 1);
1664 lines[i] = p->lines[idx % n_lines];
1665 }
1666
1667 if (p->subsample)
1668 gst_video_chroma_resample (p->subsample, lines, width);
1669
1670 for (i = 0; i < n_lines; i++) {
1671 idx = y + i + offset;
1672 if (idx > height - 1)
1673 break;
1674 finfo->pack_func (finfo, GST_VIDEO_PACK_FLAG_NONE,
1675 lines[i], 0, frame->data, frame->info.stride,
1676 frame->info.chroma_site, idx, width);
1677 }
1678 }
1679 }
1680
1681 static void
convert_hline_bayer(paintinfo * p,GstVideoFrame * frame,int y)1682 convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y)
1683 {
1684 int i;
1685 guint8 *data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
1686 guint8 *R = data + y * GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
1687 guint8 *argb = p->tmpline;
1688 gint width = GST_VIDEO_FRAME_WIDTH (frame);
1689 int x_inv = p->x_invert;
1690 int y_inv = p->y_invert;
1691
1692 if ((y ^ y_inv) & 1) {
1693 for (i = 0; i < width; i++) {
1694 if ((i ^ x_inv) & 1) {
1695 R[i] = argb[4 * i + 1];
1696 } else {
1697 R[i] = argb[4 * i + 2];
1698 }
1699 }
1700 } else {
1701 for (i = 0; i < width; i++) {
1702 if ((i ^ x_inv) & 1) {
1703 R[i] = argb[4 * i + 2];
1704 } else {
1705 R[i] = argb[4 * i + 3];
1706 }
1707 }
1708 }
1709 }
1710
1711 void
gst_video_test_src_pinwheel(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1712 gst_video_test_src_pinwheel (GstVideoTestSrc * v, GstClockTime pts,
1713 GstVideoFrame * frame)
1714 {
1715 int i;
1716 int j;
1717 int k;
1718 int t = v->n_frames;
1719 paintinfo pi = PAINT_INFO_INIT;
1720 paintinfo *p = π
1721 struct vts_color_struct color;
1722 int w = frame->info.width, h = frame->info.height;
1723 double c[20];
1724 double s[20];
1725
1726 videotestsrc_setup_paintinfo (v, p, w, h);
1727
1728 color = p->colors[COLOR_BLACK];
1729 p->color = &color;
1730
1731 for (k = 0; k < 19; k++) {
1732 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1733 c[k] = cos (theta);
1734 s[k] = sin (theta);
1735 }
1736
1737 for (j = 0; j < h; j++) {
1738 for (i = 0; i < w; i++) {
1739 double v;
1740 v = 0;
1741 for (k = 0; k < 19; k++) {
1742 double x, y;
1743
1744 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1745 x *= 1.0;
1746
1747 y = CLAMP (x, -1, 1);
1748 if (k & 1)
1749 y = -y;
1750
1751 v += y;
1752 }
1753
1754 p->tmpline_u8[i] = CLAMP (rint (v * 128 + 128), 0, 255);
1755 }
1756 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1757 &p->foreground_color, &p->background_color, 0, w);
1758 videotestsrc_convert_tmpline (p, frame, j);
1759 }
1760 }
1761
1762 void
gst_video_test_src_spokes(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1763 gst_video_test_src_spokes (GstVideoTestSrc * v, GstClockTime pts,
1764 GstVideoFrame * frame)
1765 {
1766 int i;
1767 int j;
1768 int k;
1769 int t = v->n_frames;
1770 paintinfo pi = PAINT_INFO_INIT;
1771 paintinfo *p = π
1772 struct vts_color_struct color;
1773 int w = frame->info.width, h = frame->info.height;
1774 double c[20];
1775 double s[20];
1776
1777 videotestsrc_setup_paintinfo (v, p, w, h);
1778
1779 color = p->colors[COLOR_BLACK];
1780 p->color = &color;
1781
1782 for (k = 0; k < 19; k++) {
1783 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1784 c[k] = cos (theta);
1785 s[k] = sin (theta);
1786 }
1787
1788 for (j = 0; j < h; j++) {
1789 for (i = 0; i < w; i++) {
1790 double v;
1791 v = 0;
1792 for (k = 0; k < 19; k++) {
1793 double x, y;
1794 double sharpness = 1.0;
1795 double linewidth = 2.0;
1796
1797 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1798 x = linewidth * 0.5 - fabs (x);
1799 x *= sharpness;
1800
1801 y = CLAMP (x + 0.5, 0.0, 1.0);
1802
1803 v += y;
1804 }
1805
1806 p->tmpline_u8[i] = CLAMP (rint (v * 255), 0, 255);
1807 }
1808 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1809 &p->foreground_color, &p->background_color, 0, w);
1810 videotestsrc_convert_tmpline (p, frame, j);
1811 }
1812 }
1813
1814 void
gst_video_test_src_gradient(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1815 gst_video_test_src_gradient (GstVideoTestSrc * v, GstClockTime pts,
1816 GstVideoFrame * frame)
1817 {
1818 int i;
1819 int j;
1820 paintinfo pi = PAINT_INFO_INIT;
1821 paintinfo *p = π
1822 struct vts_color_struct color;
1823 int w = frame->info.width, h = frame->info.height;
1824
1825 videotestsrc_setup_paintinfo (v, p, w, h);
1826
1827 color = p->colors[COLOR_BLACK];
1828 p->color = &color;
1829
1830 for (j = 0; j < h; j++) {
1831 int y = j * 255.0 / h;
1832 for (i = 0; i < w; i++) {
1833 p->tmpline_u8[i] = y;
1834 }
1835 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1836 &p->foreground_color, &p->background_color, 0, w);
1837 videotestsrc_convert_tmpline (p, frame, j);
1838 }
1839 }
1840
1841 void
gst_video_test_src_colors(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1842 gst_video_test_src_colors (GstVideoTestSrc * v, GstClockTime pts,
1843 GstVideoFrame * frame)
1844 {
1845 int i;
1846 int j;
1847 paintinfo pi = PAINT_INFO_INIT;
1848 paintinfo *p = π
1849 struct vts_color_struct color;
1850 int w = frame->info.width, h = frame->info.height;
1851
1852 videotestsrc_setup_paintinfo (v, p, w, h);
1853
1854 color = p->colors[COLOR_BLACK];
1855 p->color = &color;
1856
1857 for (j = 0; j < h; j++) {
1858 for (i = 0; i < w; i++) {
1859 p->tmpline[i * 4 + 0] = 0xff;
1860 p->tmpline[i * 4 + 1] = ((i * 4096) / w) % 256;
1861 p->tmpline[i * 4 + 2] = (((j * 16) / h) << 4) | ((i * 16) / w);
1862 p->tmpline[i * 4 + 3] = ((j * 4096) / h) % 256;
1863 }
1864 videotestsrc_convert_tmpline (p, frame, j);
1865 }
1866 }
1867