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