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 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)},
104 };
105
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)},
119 };
120
121
122 static void paint_tmpline_ARGB (paintinfo * p, int x, int w);
123 static void paint_tmpline_AYUV (paintinfo * p, int x, int w);
124
125 static void convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y);
126 static void convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y);
127
128 #define SCALEBITS 10
129 #define ONE_HALF (1 << (SCALEBITS - 1))
130 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
131
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)
135
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)
139
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)
143
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)
147
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)
151
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)
155
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)
159
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)
163
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)
167
168 static void
videotestsrc_setup_paintinfo(GstVideoTestSrc * v,paintinfo * p,int w,int h)169 videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
170 {
171 gint a, r, g, b;
172 gint width;
173 GstVideoInfo *info = &v->info;
174
175 width = GST_VIDEO_INFO_WIDTH (info);
176
177 if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
178 p->colors = vts_colors_bt601_ycbcr_100;
179 } else {
180 p->colors = vts_colors_bt709_ycbcr_100;
181 }
182
183 if (v->bayer) {
184 p->paint_tmpline = paint_tmpline_ARGB;
185 p->convert_tmpline = convert_hline_bayer;
186 } else {
187 p->convert_tmpline = convert_hline_generic;
188 if (GST_VIDEO_INFO_IS_RGB (info)) {
189 p->paint_tmpline = paint_tmpline_ARGB;
190 } else {
191 p->paint_tmpline = paint_tmpline_AYUV;
192 }
193 }
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;
200 p->lines = v->lines;
201 p->x_offset = (v->horizontal_speed * v->n_frames) % width;
202 if (p->x_offset < 0)
203 p->x_offset += width;
204 p->x_invert = v->x_invert;
205 p->y_invert = v->y_invert;
206
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;
215
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);
220 } else {
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);
224 }
225 p->foreground_color.gray = RGB_TO_Y (r, g, b);
226
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;
235
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);
240 } else {
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);
244 }
245 p->background_color.gray = RGB_TO_Y (r, g, b);
246
247 p->subsample = v->subsample;
248 }
249
250 static void
videotestsrc_convert_tmpline(paintinfo * p,GstVideoFrame * frame,int j)251 videotestsrc_convert_tmpline (paintinfo * p, GstVideoFrame * frame, int j)
252 {
253 int x = p->x_offset;
254 int i;
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
260 if (x != 0) {
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);
264 }
265
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];
271 }
272
273 p->convert_tmpline (p, frame, j);
274
275 if (j == height - 1) {
276 while (j % n_lines - offset != n_lines - 1) {
277 j++;
278 p->convert_tmpline (p, frame, j);
279 }
280 }
281 }
282
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))
286
287 #ifdef unused
288 static void
videotestsrc_blend_color(struct vts_color_struct * dest,struct vts_color_struct * a,struct vts_color_struct * b,int x)289 videotestsrc_blend_color (struct vts_color_struct *dest,
290 struct vts_color_struct *a, struct vts_color_struct *b, int x)
291 {
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);
299
300 }
301 #endif
302
303 static void
videotestsrc_blend_line(GstVideoTestSrc * v,guint8 * dest,guint8 * src,struct vts_color_struct * a,struct vts_color_struct * b,int n)304 videotestsrc_blend_line (GstVideoTestSrc * v, guint8 * dest, guint8 * src,
305 struct vts_color_struct *a, struct vts_color_struct *b, int n)
306 {
307 int i;
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]);
314 }
315 } else {
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]);
321 }
322 }
323 #undef BLEND
324 }
325
326 void
gst_video_test_src_smpte(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)327 gst_video_test_src_smpte (GstVideoTestSrc * v, GstClockTime pts,
328 GstVideoFrame * frame)
329 {
330 int i;
331 int y1, y2;
332 int j;
333 paintinfo pi = PAINT_INFO_INIT;
334 paintinfo *p = π
335 int w = frame->info.width, h = frame->info.height;
336
337 videotestsrc_setup_paintinfo (v, p, w, h);
338
339 y1 = 2 * h / 3;
340 y2 = 3 * h / 4;
341
342 /* color bars */
343 for (j = 0; j < y1; j++) {
344 for (i = 0; i < 7; i++) {
345 int x1 = i * w / 7;
346 int x2 = (i + 1) * w / 7;
347
348 p->color = p->colors + i;
349 p->paint_tmpline (p, x1, (x2 - x1));
350 }
351 videotestsrc_convert_tmpline (p, frame, j);
352 }
353
354 /* inverse blue bars */
355 for (j = y1; j < y2; j++) {
356 for (i = 0; i < 7; i++) {
357 int x1 = i * w / 7;
358 int x2 = (i + 1) * w / 7;
359 int k;
360
361 if (i & 1) {
362 k = 7;
363 } else {
364 k = 6 - i;
365 }
366 p->color = p->colors + k;
367 p->paint_tmpline (p, x1, (x2 - x1));
368 }
369 videotestsrc_convert_tmpline (p, frame, j);
370 }
371
372 for (j = y2; j < h; j++) {
373 /* -I, white, Q regions */
374 for (i = 0; i < 3; i++) {
375 int x1 = i * w / 6;
376 int x2 = (i + 1) * w / 6;
377 int k;
378
379 if (i == 0) {
380 k = 8;
381 } else if (i == 1) {
382 k = 0;
383 } else
384 k = 9;
385
386 p->color = p->colors + k;
387 p->paint_tmpline (p, x1, (x2 - x1));
388 }
389
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;
394 int k;
395
396 if (i == 0) {
397 k = COLOR_SUPER_BLACK;
398 } else if (i == 1) {
399 k = COLOR_BLACK;
400 } else
401 k = COLOR_DARK_GREY;
402
403 p->color = p->colors + k;
404 p->paint_tmpline (p, x1, (x2 - x1));
405 }
406
407 {
408 int x1 = w * 3 / 4;
409 struct vts_color_struct color;
410
411 color = p->colors[COLOR_BLACK];
412 p->color = &color;
413
414 for (i = x1; i < w; i++) {
415 int y = random_char (&v->random_state);
416 p->tmpline_u8[i] = y;
417 }
418 videotestsrc_blend_line (v, p->tmpline + x1 * 4, p->tmpline_u8 + x1,
419 &p->foreground_color, &p->background_color, w - x1);
420
421 }
422 videotestsrc_convert_tmpline (p, frame, j);
423
424 }
425 }
426
427 void
gst_video_test_src_smpte75(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)428 gst_video_test_src_smpte75 (GstVideoTestSrc * v, GstClockTime pts,
429 GstVideoFrame * frame)
430 {
431 int i;
432 int j;
433 paintinfo pi = PAINT_INFO_INIT;
434 paintinfo *p = π
435 int w = frame->info.width, h = frame->info.height;
436
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;
440 } else {
441 p->colors = vts_colors_bt709_ycbcr_75;
442 }
443
444 /* color bars */
445 for (j = 0; j < h; j++) {
446 for (i = 0; i < 7; i++) {
447 int x1 = i * w / 7;
448 int x2 = (i + 1) * w / 7;
449
450 p->color = p->colors + i;
451 p->paint_tmpline (p, x1, (x2 - x1));
452 }
453 videotestsrc_convert_tmpline (p, frame, j);
454 }
455 }
456
457 void
gst_video_test_src_smpte100(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)458 gst_video_test_src_smpte100 (GstVideoTestSrc * v, GstClockTime pts,
459 GstVideoFrame * frame)
460 {
461 int i;
462 int j;
463 paintinfo pi = PAINT_INFO_INIT;
464 paintinfo *p = π
465 int w = frame->info.width, h = frame->info.height;
466
467 videotestsrc_setup_paintinfo (v, p, w, h);
468
469 /* color bars */
470 for (j = 0; j < h; j++) {
471 for (i = 0; i < 7; i++) {
472 int x1 = i * w / 7;
473 int x2 = (i + 1) * w / 7;
474
475 p->color = p->colors + i;
476 p->paint_tmpline (p, x1, (x2 - x1));
477 }
478 videotestsrc_convert_tmpline (p, frame, j);
479 }
480 }
481
482 void
gst_video_test_src_bar(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)483 gst_video_test_src_bar (GstVideoTestSrc * v, GstClockTime pts,
484 GstVideoFrame * frame)
485 {
486 int j;
487 paintinfo pi = PAINT_INFO_INIT;
488 paintinfo *p = π
489 int w = frame->info.width, h = frame->info.height;
490
491 videotestsrc_setup_paintinfo (v, p, w, h);
492
493 for (j = 0; j < h; j++) {
494 /* use fixed size for now */
495 int x2 = w / 7;
496
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);
502 }
503 }
504
505 void
gst_video_test_src_snow(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)506 gst_video_test_src_snow (GstVideoTestSrc * v, GstClockTime pts,
507 GstVideoFrame * frame)
508 {
509 int i;
510 int j;
511 paintinfo pi = PAINT_INFO_INIT;
512 paintinfo *p = π
513 struct vts_color_struct color;
514 int w = frame->info.width, h = frame->info.height;
515
516 videotestsrc_setup_paintinfo (v, p, w, h);
517
518 color = p->colors[COLOR_BLACK];
519 p->color = &color;
520
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;
525 }
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);
529 }
530 }
531
532 static void
gst_video_test_src_unicolor(GstVideoTestSrc * v,GstVideoFrame * frame,int color_index)533 gst_video_test_src_unicolor (GstVideoTestSrc * v, GstVideoFrame * frame,
534 int color_index)
535 {
536 int i;
537 paintinfo pi = PAINT_INFO_INIT;
538 paintinfo *p = π
539 int w = frame->info.width, h = frame->info.height;
540
541 videotestsrc_setup_paintinfo (v, p, w, h);
542
543 p->color = p->colors + color_index;
544 if (color_index == COLOR_BLACK) {
545 p->color = &p->background_color;
546 }
547 if (color_index == COLOR_WHITE) {
548 p->color = &p->foreground_color;
549 }
550
551 for (i = 0; i < h; i++) {
552 p->paint_tmpline (p, 0, w);
553 videotestsrc_convert_tmpline (p, frame, i);
554 }
555 }
556
557 void
gst_video_test_src_black(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)558 gst_video_test_src_black (GstVideoTestSrc * v, GstClockTime pts,
559 GstVideoFrame * frame)
560 {
561 gst_video_test_src_unicolor (v, frame, COLOR_BLACK);
562 }
563
564 void
gst_video_test_src_white(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)565 gst_video_test_src_white (GstVideoTestSrc * v, GstClockTime pts,
566 GstVideoFrame * frame)
567 {
568 gst_video_test_src_unicolor (v, frame, COLOR_WHITE);
569 }
570
571 void
gst_video_test_src_red(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)572 gst_video_test_src_red (GstVideoTestSrc * v, GstClockTime pts,
573 GstVideoFrame * frame)
574 {
575 gst_video_test_src_unicolor (v, frame, COLOR_RED);
576 }
577
578 void
gst_video_test_src_green(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)579 gst_video_test_src_green (GstVideoTestSrc * v, GstClockTime pts,
580 GstVideoFrame * frame)
581 {
582 gst_video_test_src_unicolor (v, frame, COLOR_GREEN);
583 }
584
585 void
gst_video_test_src_blue(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)586 gst_video_test_src_blue (GstVideoTestSrc * v, GstClockTime pts,
587 GstVideoFrame * frame)
588 {
589 gst_video_test_src_unicolor (v, frame, COLOR_BLUE);
590 }
591
592 void
gst_video_test_src_blink(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)593 gst_video_test_src_blink (GstVideoTestSrc * v, GstClockTime pts,
594 GstVideoFrame * frame)
595 {
596 int i;
597 paintinfo pi = PAINT_INFO_INIT;
598 paintinfo *p = π
599 int w = frame->info.width, h = frame->info.height;
600
601 videotestsrc_setup_paintinfo (v, p, w, h);
602
603 if (v->n_frames & 1) {
604 p->color = &p->foreground_color;
605 } else {
606 p->color = &p->background_color;
607 }
608
609 for (i = 0; i < h; i++) {
610 p->paint_tmpline (p, 0, w);
611 videotestsrc_convert_tmpline (p, frame, i);
612 }
613 }
614
615 void
gst_video_test_src_solid(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)616 gst_video_test_src_solid (GstVideoTestSrc * v, GstClockTime pts,
617 GstVideoFrame * frame)
618 {
619 int i;
620 paintinfo pi = PAINT_INFO_INIT;
621 paintinfo *p = π
622 int w = frame->info.width, h = frame->info.height;
623
624 videotestsrc_setup_paintinfo (v, p, w, h);
625
626 p->color = &p->foreground_color;
627
628 for (i = 0; i < h; i++) {
629 p->paint_tmpline (p, 0, w);
630 videotestsrc_convert_tmpline (p, frame, i);
631 }
632 }
633
634 void
gst_video_test_src_checkers1(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)635 gst_video_test_src_checkers1 (GstVideoTestSrc * v, GstClockTime pts,
636 GstVideoFrame * frame)
637 {
638 int x, y;
639 paintinfo pi = PAINT_INFO_INIT;
640 paintinfo *p = π
641 int w = frame->info.width, h = frame->info.height;
642
643 videotestsrc_setup_paintinfo (v, p, w, h);
644
645 for (y = 0; y < h; y++) {
646 for (x = 0; x < w; x++) {
647 if ((x ^ y) & 1) {
648 p->color = p->colors + COLOR_GREEN;
649 } else {
650 p->color = p->colors + COLOR_RED;
651 }
652 p->paint_tmpline (p, x, 1);
653 }
654 videotestsrc_convert_tmpline (p, frame, y);
655 }
656 }
657
658 void
gst_video_test_src_checkers2(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)659 gst_video_test_src_checkers2 (GstVideoTestSrc * v, GstClockTime pts,
660 GstVideoFrame * frame)
661 {
662 int x, y;
663 paintinfo pi = PAINT_INFO_INIT;
664 paintinfo *p = π
665 int w = frame->info.width, h = frame->info.height;
666
667 videotestsrc_setup_paintinfo (v, p, w, h);
668
669 for (y = 0; y < h; y++) {
670 for (x = 0; x < w; x += 2) {
671 guint len = MIN (2, w - x);
672
673 if ((x ^ y) & 2) {
674 p->color = p->colors + COLOR_GREEN;
675 } else {
676 p->color = p->colors + COLOR_RED;
677 }
678 p->paint_tmpline (p, x, len);
679 }
680 videotestsrc_convert_tmpline (p, frame, y);
681 }
682 }
683
684 void
gst_video_test_src_checkers4(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)685 gst_video_test_src_checkers4 (GstVideoTestSrc * v, GstClockTime pts,
686 GstVideoFrame * frame)
687 {
688 int x, y;
689 paintinfo pi = PAINT_INFO_INIT;
690 paintinfo *p = π
691 int w = frame->info.width, h = frame->info.height;
692
693 videotestsrc_setup_paintinfo (v, p, w, h);
694
695 for (y = 0; y < h; y++) {
696 for (x = 0; x < w; x += 4) {
697 guint len = MIN (4, w - x);
698
699 if ((x ^ y) & 4) {
700 p->color = p->colors + COLOR_GREEN;
701 } else {
702 p->color = p->colors + COLOR_RED;
703 }
704 p->paint_tmpline (p, x, len);
705 }
706 videotestsrc_convert_tmpline (p, frame, y);
707 }
708 }
709
710 void
gst_video_test_src_checkers8(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)711 gst_video_test_src_checkers8 (GstVideoTestSrc * v, GstClockTime pts,
712 GstVideoFrame * frame)
713 {
714 int x, y;
715 paintinfo pi = PAINT_INFO_INIT;
716 paintinfo *p = π
717 int w = frame->info.width, h = frame->info.height;
718
719 videotestsrc_setup_paintinfo (v, p, w, h);
720
721 for (y = 0; y < h; y++) {
722 for (x = 0; x < w; x += 8) {
723 guint len = MIN (8, w - x);
724
725 if ((x ^ y) & 8) {
726 p->color = p->colors + COLOR_GREEN;
727 } else {
728 p->color = p->colors + COLOR_RED;
729 }
730 p->paint_tmpline (p, x, len);
731 }
732 videotestsrc_convert_tmpline (p, frame, y);
733 }
734 }
735
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
769 };
770
771
772 void
gst_video_test_src_zoneplate(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)773 gst_video_test_src_zoneplate (GstVideoTestSrc * v, GstClockTime pts,
774 GstVideoFrame * frame)
775 {
776 int i;
777 int j;
778 paintinfo pi = PAINT_INFO_INIT;
779 paintinfo *p = π
780 struct vts_color_struct color;
781 int t = v->n_frames;
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;
785
786 int x, y;
787 int accum_kx;
788 int accum_kxt;
789 int accum_ky;
790 int accum_kyt;
791 int accum_kxy;
792 int kt;
793 int kt2;
794 int ky2;
795 int delta_kxt = v->kxt * t;
796 int delta_kxy;
797 int scale_kxy = 0xffff / (w / 2);
798 int scale_kx2 = 0xffff / w;
799
800 videotestsrc_setup_paintinfo (v, p, w, h);
801
802 color = p->colors[COLOR_BLACK];
803 p->color = &color;
804
805 /* Zoneplate equation:
806 *
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
810 */
811
812 #if 0
813 for (j = 0, y = yreset; j < h; j++, y++) {
814 for (i = 0, x = xreset; i < w; i++, x++) {
815
816 /* zero order */
817 int phase = v->k0;
818
819 /* first order */
820 phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
821
822 /* cross term */
823 /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
824 /* phase = phase + (v->kxy * x * y) / (w/2); */
825
826 /*second order */
827 /*normalise x/y terms to rate of change of phase at the picture edge */
828 phase =
829 phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
830 ((v->kt2 * t * t) >> 1);
831
832 color.Y = sine_table[phase & 0xff];
833
834 color.R = color.Y;
835 color.G = color.Y;
836 color.B = color.Y;
837 p->paint_tmpline (p, i, 1);
838 }
839 }
840 #endif
841
842 /* optimised version, with original code shown in comments */
843 accum_ky = 0;
844 accum_kyt = 0;
845 kt = v->kt * t;
846 kt2 = v->kt2 * t * t;
847 for (j = 0, y = yreset; j < h; j++, y++) {
848 accum_kx = 0;
849 accum_kxt = 0;
850 accum_ky += v->ky;
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++) {
856
857 /* zero order */
858 int phase = v->k0;
859
860 /* first order */
861 accum_kx += v->kx;
862 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
863 phase = phase + accum_kx + accum_ky + kt;
864
865 /* cross term */
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;
870
871 /* phase = phase + (v->kxy * x * y) / (w/2); */
872 /* phase = phase + accum_kxy / (w/2); */
873 phase = phase + (accum_kxy >> 16);
874
875 /*second order */
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);
879
880 p->tmpline_u8[i] = sine_table[phase & 0xff];
881 }
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);
885 }
886 }
887
888 void
gst_video_test_src_chromazoneplate(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)889 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, GstClockTime pts,
890 GstVideoFrame * frame)
891 {
892 int i;
893 int j;
894 paintinfo pi = PAINT_INFO_INIT;
895 paintinfo *p = π
896 struct vts_color_struct color;
897 int t = v->n_frames;
898 int w = frame->info.width, h = frame->info.height;
899
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;
902
903 int x, y;
904 int accum_kx;
905 int accum_kxt;
906 int accum_ky;
907 int accum_kyt;
908 int accum_kxy;
909 int kt;
910 int kt2;
911 int ky2;
912 int delta_kxt = v->kxt * t;
913 int delta_kxy;
914 int scale_kxy = 0xffff / (w / 2);
915 int scale_kx2 = 0xffff / w;
916
917 videotestsrc_setup_paintinfo (v, p, w, h);
918
919 color = p->colors[COLOR_BLACK];
920 p->color = &color;
921
922 /* Zoneplate equation:
923 *
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
927 */
928
929 /* optimised version, with original code shown in comments */
930 accum_ky = 0;
931 accum_kyt = 0;
932 kt = v->kt * t;
933 kt2 = v->kt2 * t * t;
934 for (j = 0, y = yreset; j < h; j++, y++) {
935 accum_kx = 0;
936 accum_kxt = 0;
937 accum_ky += v->ky;
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++) {
943
944 /* zero order */
945 int phase = v->k0;
946
947 /* first order */
948 accum_kx += v->kx;
949 /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
950 phase = phase + accum_kx + accum_ky + kt;
951
952 /* cross term */
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;
957
958 /* phase = phase + (v->kxy * x * y) / (w/2); */
959 /* phase = phase + accum_kxy / (w/2); */
960 phase = phase + (accum_kxy >> 16);
961
962 /*second order */
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);
966
967 color.Y = 128;
968 color.U = sine_table[phase & 0xff];
969 color.V = sine_table[phase & 0xff];
970
971 color.R = 128;
972 color.G = 128;
973 color.B = color.V;
974
975 color.gray = color.Y << 8;
976 p->paint_tmpline (p, i, 1);
977 }
978 videotestsrc_convert_tmpline (p, frame, j);
979 }
980 }
981
982 #undef SCALE_AMPLITUDE
983 void
gst_video_test_src_circular(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)984 gst_video_test_src_circular (GstVideoTestSrc * v, GstClockTime pts,
985 GstVideoFrame * frame)
986 {
987 int i;
988 int j;
989 paintinfo pi = PAINT_INFO_INIT;
990 paintinfo *p = π
991 double freq[8];
992 int w = frame->info.width, h = frame->info.height;
993
994 int d;
995
996 videotestsrc_setup_paintinfo (v, p, w, h);
997
998 for (i = 1; i < 8; i++) {
999 freq[i] = 200 * pow (2.0, -(i - 1) / 4.0);
1000 }
1001
1002 for (j = 0; j < h; j++) {
1003 for (i = 0; i < w; i++) {
1004 double dist;
1005 int seg;
1006
1007 dist =
1008 sqrt ((2 * i - w) * (2 * i - w) + (2 * j - h) * (2 * j -
1009 h)) / (2 * w);
1010 seg = floor (dist * 16);
1011 if (seg == 0 || seg >= 8) {
1012 p->tmpline_u8[i] = 0;
1013 } else {
1014 d = floor (256 * dist * freq[seg] + 0.5);
1015 p->tmpline_u8[i] = sine_table[d & 0xff];
1016 }
1017 }
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);
1021 }
1022 }
1023
1024 void
gst_video_test_src_gamut(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1025 gst_video_test_src_gamut (GstVideoTestSrc * v, GstClockTime pts,
1026 GstVideoFrame * frame)
1027 {
1028 int x, y;
1029 paintinfo pi = PAINT_INFO_INIT;
1030 paintinfo *p = π
1031 struct vts_color_struct yuv_primary;
1032 struct vts_color_struct yuv_secondary;
1033 int w = frame->info.width, h = frame->info.height;
1034
1035 videotestsrc_setup_paintinfo (v, p, w, h);
1036
1037 for (y = 0; y < h; y++) {
1038 int region = (y * 4) / h;
1039
1040 switch (region) {
1041 case 0: /* black */
1042 yuv_primary = p->colors[COLOR_BLACK];
1043 yuv_secondary = p->colors[COLOR_BLACK];
1044 yuv_secondary.Y = 0;
1045 break;
1046 case 1:
1047 yuv_primary = p->colors[COLOR_WHITE];
1048 yuv_secondary = p->colors[COLOR_WHITE];
1049 yuv_secondary.Y = 255;
1050 break;
1051 case 2:
1052 yuv_primary = p->colors[COLOR_RED];
1053 yuv_secondary = p->colors[COLOR_RED];
1054 yuv_secondary.V = 255;
1055 break;
1056 case 3:
1057 yuv_primary = p->colors[COLOR_BLUE];
1058 yuv_secondary = p->colors[COLOR_BLUE];
1059 yuv_secondary.U = 255;
1060 break;
1061 }
1062
1063 for (x = 0; x < w; x += 8) {
1064 int len = MIN (8, w - x);
1065
1066 if ((x ^ y) & (1 << 4)) {
1067 p->color = &yuv_primary;
1068 } else {
1069 p->color = &yuv_secondary;
1070 }
1071 p->paint_tmpline (p, x, len);
1072 }
1073 videotestsrc_convert_tmpline (p, frame, y);
1074 }
1075 }
1076
1077 void
gst_video_test_src_ball(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1078 gst_video_test_src_ball (GstVideoTestSrc * v, GstClockTime pts,
1079 GstVideoFrame * frame)
1080 {
1081 int i;
1082 int radius = 20;
1083 int w = frame->info.width, h = frame->info.height;
1084 GTimeVal rand_tv;
1085 gdouble rad = 0;
1086 double x, y;
1087 int flipit = 0;
1088
1089 paintinfo pi = PAINT_INFO_INIT;
1090 paintinfo *p = π
1091
1092 struct vts_color_struct
1093 *foreground_color = &p->foreground_color,
1094 *background_color = &p->background_color;
1095
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;
1100 break;
1101 case GST_VIDEO_TEST_SRC_WALL_TIME:
1102 g_get_current_time (&rand_tv);
1103
1104 rad = (gdouble) (rand_tv.tv_usec) / 1000000.0 + rand_tv.tv_sec;
1105 flipit = rand_tv.tv_sec % 2;
1106 break;
1107 case GST_VIDEO_TEST_SRC_RUNNING_TIME:
1108 rad = (gdouble) (pts) / GST_SECOND;
1109 flipit = (pts / GST_SECOND) % 2;
1110 break;
1111 }
1112 if (v->motion_type == GST_VIDEO_TEST_SRC_HSWEEP) {
1113 /* Periodic reset for half sweep */
1114 rad /= 2;
1115 rad -= floor (2 * rad) / 2;
1116 }
1117
1118 /* Scale for the animation calcs */
1119 rad = 2 * G_PI * rad;
1120
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);
1124 } else {
1125 /* sweep and hsweep */
1126 /* x,y is center of circle,
1127 * radius is radius
1128 * rad = angle .. of sweep.
1129 */
1130
1131 radius = MIN (h, w) / 4 - 0;
1132
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;
1136 }
1137
1138 if (v->flip && flipit) {
1139 foreground_color = &p->background_color;
1140 background_color = &p->foreground_color;
1141 }
1142
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);
1148 } else {
1149 double o = MAX (0, (radius * radius - (i - y) * (i - y)));
1150 int r = rint (sqrt (o));
1151 int x1, x2;
1152 int j;
1153
1154 x1 = 0;
1155 x2 = MAX (0, x - r);
1156 for (j = x1; j < x2; j++) {
1157 p->tmpline_u8[j] = 0;
1158 }
1159
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));
1164
1165 rr *= 0.5;
1166 p->tmpline_u8[j] = CLAMP ((int) floor (256 * rr), 0, 255);
1167 }
1168
1169 x1 = MIN (w, x + r + 1);
1170 x2 = w;
1171 for (j = x1; j < x2; j++) {
1172 p->tmpline_u8[j] = 0;
1173 }
1174 }
1175
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;
1181 }
1182
1183 videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1184 foreground_color, background_color, w);
1185 videotestsrc_convert_tmpline (p, frame, i);
1186 }
1187
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;
1193 }
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);
1198 }
1199 }
1200
1201 static void
paint_tmpline_ARGB(paintinfo * p,int x,int w)1202 paint_tmpline_ARGB (paintinfo * p, int x, int w)
1203 {
1204 int offset;
1205 guint32 value;
1206
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);
1210 #else
1211 value = ((guint32) p->color->A << 24) | (p->color->R << 16) |
1212 (p->color->G << 8) | (p->color->B << 0);
1213 #endif
1214
1215 offset = (x * 4);
1216 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1217 }
1218
1219 static void
paint_tmpline_AYUV(paintinfo * p,int x,int w)1220 paint_tmpline_AYUV (paintinfo * p, int x, int w)
1221 {
1222 int offset;
1223 guint32 value;
1224
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);
1228 #else
1229 value = ((guint32) p->color->A << 24) | (p->color->Y << 16) |
1230 (p->color->U << 8) | (p->color->V << 0);
1231 #endif
1232
1233 offset = (x * 4);
1234 video_test_src_orc_splat_u32 (p->tmpline + offset, value, w);
1235 }
1236
1237 static void
convert_hline_generic(paintinfo * p,GstVideoFrame * frame,int y)1238 convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y)
1239 {
1240 const GstVideoFormatInfo *finfo, *uinfo;
1241 gint line, offset, i, width, height, bits;
1242 guint n_lines;
1243 gpointer dest;
1244
1245 finfo = frame->info.finfo;
1246 uinfo = gst_video_format_get_info (finfo->unpack_format);
1247
1248 width = GST_VIDEO_FRAME_WIDTH (frame);
1249 height = GST_VIDEO_FRAME_HEIGHT (frame);
1250
1251 bits = GST_VIDEO_FORMAT_INFO_DEPTH (uinfo, 0);
1252
1253 n_lines = p->n_lines;
1254 offset = p->offset;
1255 line = y % n_lines;
1256 dest = p->lines[line];
1257
1258 if (bits == 16) {
1259 /* 16 bits */
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]);
1265 }
1266 memcpy (dest, p->tmpline_u16, width * 8);
1267 } else {
1268 memcpy (dest, p->tmpline, width * 4);
1269 }
1270
1271 if (line - offset == n_lines - 1) {
1272 gpointer lines[8];
1273 guint idx;
1274
1275 y -= n_lines - 1;
1276
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];
1280 }
1281
1282 if (p->subsample)
1283 gst_video_chroma_resample (p->subsample, lines, width);
1284
1285 for (i = 0; i < n_lines; i++) {
1286 idx = y + i + offset;
1287 if (idx > height - 1)
1288 break;
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);
1292 }
1293 }
1294 }
1295
1296 static void
convert_hline_bayer(paintinfo * p,GstVideoFrame * frame,int y)1297 convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y)
1298 {
1299 int i;
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;
1306
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];
1311 } else {
1312 R[i] = argb[4 * i + 2];
1313 }
1314 }
1315 } else {
1316 for (i = 0; i < width; i++) {
1317 if ((i ^ x_inv) & 1) {
1318 R[i] = argb[4 * i + 2];
1319 } else {
1320 R[i] = argb[4 * i + 3];
1321 }
1322 }
1323 }
1324 }
1325
1326 void
gst_video_test_src_pinwheel(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1327 gst_video_test_src_pinwheel (GstVideoTestSrc * v, GstClockTime pts,
1328 GstVideoFrame * frame)
1329 {
1330 int i;
1331 int j;
1332 int k;
1333 int t = v->n_frames;
1334 paintinfo pi = PAINT_INFO_INIT;
1335 paintinfo *p = π
1336 struct vts_color_struct color;
1337 int w = frame->info.width, h = frame->info.height;
1338 double c[20];
1339 double s[20];
1340
1341 videotestsrc_setup_paintinfo (v, p, w, h);
1342
1343 color = p->colors[COLOR_BLACK];
1344 p->color = &color;
1345
1346 for (k = 0; k < 19; k++) {
1347 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1348 c[k] = cos (theta);
1349 s[k] = sin (theta);
1350 }
1351
1352 for (j = 0; j < h; j++) {
1353 for (i = 0; i < w; i++) {
1354 double v;
1355 v = 0;
1356 for (k = 0; k < 19; k++) {
1357 double x, y;
1358
1359 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1360 x *= 1.0;
1361
1362 y = CLAMP (x, -1, 1);
1363 if (k & 1)
1364 y = -y;
1365
1366 v += y;
1367 }
1368
1369 p->tmpline_u8[i] = CLAMP (rint (v * 128 + 128), 0, 255);
1370 }
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);
1374 }
1375 }
1376
1377 void
gst_video_test_src_spokes(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1378 gst_video_test_src_spokes (GstVideoTestSrc * v, GstClockTime pts,
1379 GstVideoFrame * frame)
1380 {
1381 int i;
1382 int j;
1383 int k;
1384 int t = v->n_frames;
1385 paintinfo pi = PAINT_INFO_INIT;
1386 paintinfo *p = π
1387 struct vts_color_struct color;
1388 int w = frame->info.width, h = frame->info.height;
1389 double c[20];
1390 double s[20];
1391
1392 videotestsrc_setup_paintinfo (v, p, w, h);
1393
1394 color = p->colors[COLOR_BLACK];
1395 p->color = &color;
1396
1397 for (k = 0; k < 19; k++) {
1398 double theta = M_PI / 19 * k + 0.001 * v->kt * t;
1399 c[k] = cos (theta);
1400 s[k] = sin (theta);
1401 }
1402
1403 for (j = 0; j < h; j++) {
1404 for (i = 0; i < w; i++) {
1405 double v;
1406 v = 0;
1407 for (k = 0; k < 19; k++) {
1408 double x, y;
1409 double sharpness = 1.0;
1410 double linewidth = 2.0;
1411
1412 x = c[k] * (i - 0.5 * w) + s[k] * (j - 0.5 * h);
1413 x = linewidth * 0.5 - fabs (x);
1414 x *= sharpness;
1415
1416 y = CLAMP (x + 0.5, 0.0, 1.0);
1417
1418 v += y;
1419 }
1420
1421 p->tmpline_u8[i] = CLAMP (rint (v * 255), 0, 255);
1422 }
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);
1426 }
1427 }
1428
1429 void
gst_video_test_src_gradient(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1430 gst_video_test_src_gradient (GstVideoTestSrc * v, GstClockTime pts,
1431 GstVideoFrame * frame)
1432 {
1433 int i;
1434 int j;
1435 paintinfo pi = PAINT_INFO_INIT;
1436 paintinfo *p = π
1437 struct vts_color_struct color;
1438 int w = frame->info.width, h = frame->info.height;
1439
1440 videotestsrc_setup_paintinfo (v, p, w, h);
1441
1442 color = p->colors[COLOR_BLACK];
1443 p->color = &color;
1444
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;
1449 }
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);
1453 }
1454 }
1455
1456 void
gst_video_test_src_colors(GstVideoTestSrc * v,GstClockTime pts,GstVideoFrame * frame)1457 gst_video_test_src_colors (GstVideoTestSrc * v, GstClockTime pts,
1458 GstVideoFrame * frame)
1459 {
1460 int i;
1461 int j;
1462 paintinfo pi = PAINT_INFO_INIT;
1463 paintinfo *p = π
1464 struct vts_color_struct color;
1465 int w = frame->info.width, h = frame->info.height;
1466
1467 videotestsrc_setup_paintinfo (v, p, w, h);
1468
1469 color = p->colors[COLOR_BLACK];
1470 p->color = &color;
1471
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;
1478 }
1479 videotestsrc_convert_tmpline (p, frame, j);
1480 }
1481 }
1482