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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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 = &pi;
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