videotestsrc: use generic packing code
[platform/upstream/gstreamer.git] / gst / videotestsrc / videotestsrc.c
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., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, 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 void paint_tmpline_ARGB (paintinfo * p, int x, int w);
38 static void paint_tmpline_AYUV (paintinfo * p, int x, int w);
39
40 static unsigned char
41 random_char (void)
42 {
43   static unsigned int state;
44
45   state *= 1103515245;
46   state += 12345;
47   return (state >> 16) & 0xff;
48 }
49
50 enum
51 {
52   COLOR_WHITE = 0,
53   COLOR_YELLOW,
54   COLOR_CYAN,
55   COLOR_GREEN,
56   COLOR_MAGENTA,
57   COLOR_RED,
58   COLOR_BLUE,
59   COLOR_BLACK,
60   COLOR_NEG_I,
61   COLOR_POS_Q,
62   COLOR_SUPER_BLACK,
63   COLOR_DARK_GREY
64 };
65
66 static const struct vts_color_struct vts_colors_bt709_ycbcr_100[] = {
67   {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
68   {219, 16, 138, 255, 255, 255, 0, (219 << 8)},
69   {188, 154, 16, 255, 0, 255, 255, (188 < 8)},
70   {173, 42, 26, 255, 0, 255, 0, (173 << 8)},
71   {78, 214, 230, 255, 255, 0, 255, (78 << 8)},
72   {63, 102, 240, 255, 255, 0, 0, (64 << 8)},
73   {32, 240, 118, 255, 0, 0, 255, (32 << 8)},
74   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
75   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
76   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
77   {0, 128, 128, 255, 0, 0, 0, 0},
78   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
79 };
80
81 static const struct vts_color_struct vts_colors_bt709_ycbcr_75[] = {
82   {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
83   {168, 44, 136, 255, 191, 191, 0, (168 << 8)},
84   {145, 147, 44, 255, 0, 191, 191, (145 << 8)},
85   {133, 63, 52, 255, 0, 191, 0, (133 << 8)},
86   {63, 193, 204, 255, 191, 0, 191, (63 << 8)},
87   {51, 109, 212, 255, 191, 0, 0, (51 << 8)},
88   {28, 212, 120, 255, 0, 0, 191, (28 << 8)},
89   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
90   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
91   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
92   {0, 128, 128, 255, 0, 0, 0, 0},
93   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
94 };
95
96 static const struct vts_color_struct vts_colors_bt601_ycbcr_100[] = {
97   {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
98   {210, 16, 146, 255, 255, 255, 0, (219 << 8)},
99   {170, 166, 16, 255, 0, 255, 255, (188 < 8)},
100   {145, 54, 34, 255, 0, 255, 0, (173 << 8)},
101   {106, 202, 222, 255, 255, 0, 255, (78 << 8)},
102   {81, 90, 240, 255, 255, 0, 0, (64 << 8)},
103   {41, 240, 110, 255, 0, 0, 255, (32 << 8)},
104   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
105   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
106   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
107   {-0, 128, 128, 255, 0, 0, 0, 0},
108   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
109 };
110
111 static const struct vts_color_struct vts_colors_bt601_ycbcr_75[] = {
112   {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
113   {162, 44, 142, 255, 191, 191, 0, (168 << 8)},
114   {131, 156, 44, 255, 0, 191, 191, (145 << 8)},
115   {112, 72, 58, 255, 0, 191, 0, (133 << 8)},
116   {84, 184, 198, 255, 191, 0, 191, (63 << 8)},
117   {65, 100, 212, 255, 191, 0, 0, (51 << 8)},
118   {35, 212, 114, 255, 0, 0, 191, (28 << 8)},
119   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
120   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
121   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
122   {-0, 128, 128, 255, 0, 0, 0, 0},
123   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
124 };
125
126
127 static void paint_setup_generic (paintinfo * p, GstVideoFrame * frame);
128
129 static void paint_setup_bayer_bggr (paintinfo * p, GstVideoFrame * frame);
130 static void paint_setup_bayer_rggb (paintinfo * p, GstVideoFrame * frame);
131 static void paint_setup_bayer_gbrg (paintinfo * p, GstVideoFrame * frame);
132 static void paint_setup_bayer_grbg (paintinfo * p, GstVideoFrame * frame);
133
134 static void convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y);
135 #if 0
136 static void convert_hline_I420 (paintinfo * p, int y);
137 static void convert_hline_NV12 (paintinfo * p, int y);
138 static void convert_hline_NV21 (paintinfo * p, int y);
139 static void convert_hline_YUY2 (paintinfo * p, int y);
140 #ifdef disabled
141 static void convert_hline_IYU2 (paintinfo * p, int y);
142 #endif
143 static void convert_hline_Y41B (paintinfo * p, int y);
144 static void convert_hline_Y42B (paintinfo * p, int y);
145 static void convert_hline_Y444 (paintinfo * p, int y);
146 static void convert_hline_Y800 (paintinfo * p, int y);
147 static void convert_hline_v308 (paintinfo * p, int y);
148 static void convert_hline_AYUV (paintinfo * p, int y);
149 #ifdef disabled
150 static void convert_hline_v410 (paintinfo * p, int y);
151 #endif
152 static void convert_hline_v216 (paintinfo * p, int y);
153 static void convert_hline_v210 (paintinfo * p, int y);
154 static void convert_hline_UYVP (paintinfo * p, int y);
155 static void convert_hline_AY64 (paintinfo * p, int y);
156
157 static void convert_hline_YUV9 (paintinfo * p, int y);
158 static void convert_hline_astr4 (paintinfo * p, int y);
159 static void convert_hline_astr8 (paintinfo * p, int y);
160 static void convert_hline_str4 (paintinfo * p, int y);
161 static void convert_hline_str3 (paintinfo * p, int y);
162 static void convert_hline_RGB565 (paintinfo * p, int y);
163 static void convert_hline_xRGB1555 (paintinfo * p, int y);
164
165 static void convert_hline_GRAY8 (paintinfo * p, int y);
166 static void convert_hline_GRAY16 (paintinfo * p, int y);
167 static void convert_hline_I420_10LE (paintinfo * p, int y);
168 static void convert_hline_I420_10BE (paintinfo * p, int y);
169 #endif
170
171 static void convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y);
172
173 struct format_list_struct format_list[] = {
174 /* packed */
175   {VTS_YUV, "YUY2", "YUY2", paint_setup_generic, convert_hline_generic},
176   {VTS_YUV, "UYVY", "UYVY", paint_setup_generic, convert_hline_generic},
177 #ifdef disabled
178   {VTS_YUV, "Y422", "Y422", paint_setup_generic, convert_hline_generic},
179   {VTS_YUV, "UYNV", "UYNV", paint_setup_generic, convert_hline_generic},        /* FIXME: UYNV? */
180 #endif
181   {VTS_YUV, "YVYU", "YVYU", paint_setup_generic, convert_hline_generic},
182   {VTS_YUV, "v308", "v308", paint_setup_generic, convert_hline_generic},
183   {VTS_YUV, "AYUV", "AYUV", paint_setup_generic, convert_hline_generic},
184 #ifdef disabled
185   {VTS_YUV, "v410", "v410", paint_setup_generic, convert_hline_generic},
186 #endif
187   {VTS_YUV, "v210", "v210", paint_setup_generic, convert_hline_generic},
188   {VTS_YUV, "v216", "v216", paint_setup_generic, convert_hline_generic},
189   {VTS_YUV, "UYVP", "UYVP", paint_setup_generic, convert_hline_generic},
190   {VTS_YUV, "AYUV64", "AY64", paint_setup_generic, convert_hline_generic},
191
192 #ifdef disabled
193   {VTS_YUV, "IYU2", "IYU2", paint_setup_generic, convert_hline_generic},
194 #endif
195
196 /* planar */
197   /* YVU9 */
198   {VTS_YUV, "YVU9", "YVU9", paint_setup_generic, convert_hline_generic},
199   /* YUV9 */
200   {VTS_YUV, "YUV9", "YUV9", paint_setup_generic, convert_hline_generic},
201   /* IF09 */
202   /* YV12 */
203   {VTS_YUV, "YV12", "YV12", paint_setup_generic, convert_hline_generic},
204   /* I420 */
205   {VTS_YUV, "I420", "I420", paint_setup_generic, convert_hline_generic},
206   /* NV12 */
207   {VTS_YUV, "NV12", "NV12", paint_setup_generic, convert_hline_generic},
208   /* NV21 */
209   {VTS_YUV, "NV21", "NV21", paint_setup_generic, convert_hline_generic},
210   /* CLPL */
211   /* Y41B */
212   {VTS_YUV, "Y41B", "Y41B", paint_setup_generic, convert_hline_generic},
213   /* Y42B */
214   {VTS_YUV, "Y42B", "Y42B", paint_setup_generic, convert_hline_generic},
215   /* Y444 */
216   {VTS_YUV, "Y444", "Y444", paint_setup_generic, convert_hline_generic},
217   /* Y800 grayscale */
218   {VTS_YUV, "Y800", "Y800", paint_setup_generic, convert_hline_generic},
219
220   {VTS_YUV, "I420_10LE", "I420-10LE", paint_setup_generic,
221       convert_hline_generic},
222   {VTS_YUV, "I420_10BE", "I420-10BE", paint_setup_generic,
223       convert_hline_generic},
224
225   /* Not exactly YUV but it's the same as above */
226   {VTS_GRAY, "GRAY8", "GRAY8", paint_setup_generic, convert_hline_generic},
227 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
228   {VTS_GRAY, "GRAY16_LE", "GRAY16", paint_setup_generic,
229       convert_hline_generic},
230 #else
231   {VTS_GRAY, "GRAY16_BE", "GRAY16", paint_setup_generic,
232       convert_hline_generic},
233 #endif
234
235   {VTS_RGB, "xRGB", "xRGB8888", paint_setup_generic, convert_hline_generic},
236   {VTS_RGB, "xBGR", "xBGR8888", paint_setup_generic, convert_hline_generic},
237   {VTS_RGB, "RGBx", "RGBx8888", paint_setup_generic, convert_hline_generic},
238   {VTS_RGB, "BGRx", "BGRx8888", paint_setup_generic, convert_hline_generic},
239   {VTS_RGB, "ARGB", "ARGB8888", paint_setup_generic, convert_hline_generic},
240   {VTS_RGB, "ABGR", "ABGR8888", paint_setup_generic, convert_hline_generic},
241   {VTS_RGB, "RGBA", "RGBA8888", paint_setup_generic, convert_hline_generic},
242   {VTS_RGB, "BGRA", "BGRA8888", paint_setup_generic, convert_hline_generic},
243   {VTS_RGB, "RGB", "RGB888", paint_setup_generic, convert_hline_generic},
244   {VTS_RGB, "BGR", "BGR888", paint_setup_generic, convert_hline_generic},
245   {VTS_RGB, "RGB16", "RGB565", paint_setup_generic, convert_hline_generic},
246   {VTS_RGB, "RGB15", "xRGB1555", paint_setup_generic, convert_hline_generic},
247   {VTS_RGB, "ARGB64", "ARGB8888", paint_setup_generic, convert_hline_generic},
248
249   {VTS_BAYER, "bggr", "Bayer", paint_setup_bayer_bggr, convert_hline_bayer},
250   {VTS_BAYER, "rggb", "Bayer", paint_setup_bayer_rggb, convert_hline_bayer},
251   {VTS_BAYER, "grbg", "Bayer", paint_setup_bayer_grbg, convert_hline_bayer},
252   {VTS_BAYER, "gbrg", "Bayer", paint_setup_bayer_gbrg, convert_hline_bayer}
253 };
254
255 int n_formats = G_N_ELEMENTS (format_list);
256
257 struct format_list_struct *
258 paintinfo_find_by_structure (const GstStructure * structure)
259 {
260   int i;
261   const char *media_type = gst_structure_get_name (structure);
262
263   g_return_val_if_fail (structure, NULL);
264
265   if (strcmp (media_type, "video/x-raw") == 0) {
266     const gchar *format;
267
268     format = gst_structure_get_string (structure, "format");
269     if (!format) {
270       GST_WARNING ("incomplete caps structure: %" GST_PTR_FORMAT, structure);
271       return NULL;
272     }
273
274     for (i = 0; i < n_formats; i++) {
275       if (g_str_equal (format, format_list[i].format)) {
276         return format_list + i;
277       }
278     }
279     return NULL;
280   } else if (strcmp (media_type, "video/x-bayer") == 0) {
281     const gchar *format;
282
283     format = gst_structure_get_string (structure, "format");
284     if (!format) {
285       GST_WARNING ("incomplete caps structure: %" GST_PTR_FORMAT, structure);
286       return NULL;
287     }
288
289     for (i = 0; i < n_formats; i++) {
290       if (format_list[i].type == VTS_BAYER &&
291           g_str_equal (format, format_list[i].format)) {
292         return format_list + i;
293       }
294     }
295     return NULL;
296   }
297
298   g_critical ("format not found for media type %s", media_type);
299
300   return NULL;
301 }
302
303 struct format_list_struct *
304 paintrect_find_format (const gchar * find_format)
305 {
306   int i;
307
308   for (i = 0; i < n_formats; i++) {
309     if (g_str_equal (find_format, format_list[i].format)) {
310       return format_list + i;
311     }
312   }
313   return NULL;
314 }
315
316 struct format_list_struct *
317 paintrect_find_name (const char *name)
318 {
319   int i;
320
321   for (i = 0; i < n_formats; i++) {
322     if (g_str_equal (name, format_list[i].name)) {
323       return format_list + i;
324     }
325   }
326   return NULL;
327 }
328
329
330 GstStructure *
331 paint_get_structure (struct format_list_struct * format)
332 {
333   GstStructure *structure = NULL;
334
335   g_return_val_if_fail (format, NULL);
336
337   switch (format->type) {
338     case VTS_RGB:
339     case VTS_GRAY:
340       structure = gst_structure_new ("video/x-raw",
341           "format", G_TYPE_STRING, format->format, NULL);
342       break;
343     case VTS_YUV:
344     {
345       GValue value_list = { 0 };
346       GValue value = { 0 };
347
348       structure = gst_structure_new ("video/x-raw",
349           "format", G_TYPE_STRING, format->format, NULL);
350
351       if (strcmp (format->format, "Y800") != 0) {
352         g_value_init (&value_list, GST_TYPE_LIST);
353
354         g_value_init (&value, G_TYPE_STRING);
355         g_value_set_static_string (&value, "bt601");
356         gst_value_list_append_value (&value_list, &value);
357
358         g_value_set_static_string (&value, "bt709");
359         gst_value_list_append_value (&value_list, &value);
360
361         gst_structure_set_value (structure, "colorimetry", &value_list);
362         g_value_reset (&value_list);
363
364         if (strcmp (format->format, "AYUV") &&
365             strcmp (format->format, "v308") &&
366             strcmp (format->format, "v410") &&
367             strcmp (format->format, "Y444")) {
368           g_value_set_static_string (&value, "mpeg2");
369           gst_value_list_append_value (&value_list, &value);
370
371           g_value_set_static_string (&value, "jpeg");
372           gst_value_list_append_value (&value_list, &value);
373
374           gst_structure_set_value (structure, "chroma-site", &value_list);
375         }
376         g_value_unset (&value_list);
377       }
378       break;
379     }
380     case VTS_BAYER:
381       structure = gst_structure_new ("video/x-bayer",
382           "format", G_TYPE_STRING, format->format, NULL);
383       break;
384     default:
385       g_assert_not_reached ();
386       break;
387   }
388   return structure;
389 }
390
391 /* returns the size in bytes for one video frame of the given dimensions
392  * given the format in GstVideoTestSrc */
393 int
394 gst_video_test_src_get_size (GstVideoTestSrc * v, int w, int h)
395 {
396   paintinfo pi = PAINT_INFO_INIT;
397   paintinfo *p = &pi;
398   struct format_list_struct *format;
399
400   p->width = w;
401   p->height = h;
402   format = v->format;
403   if (format == NULL)
404     return 0;
405
406   format->paint_setup (p, NULL);
407
408   return p->size;
409 }
410
411 #define SCALEBITS 10
412 #define ONE_HALF  (1 << (SCALEBITS - 1))
413 #define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
414
415 #define RGB_TO_Y(r, g, b) \
416 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
417   FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
418
419 #define RGB_TO_U(r1, g1, b1, shift)\
420 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
421      FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
422
423 #define RGB_TO_V(r1, g1, b1, shift)\
424 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
425    FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
426
427 #define RGB_TO_Y_CCIR(r, g, b) \
428 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
429   FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
430
431 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
432 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
433      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
434
435 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
436 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
437    FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
438
439 #define RGB_TO_Y_CCIR_709(r, g, b) \
440 ((FIX(0.212600*219.0/255.0) * (r) + FIX(0.715200*219.0/255.0) * (g) + \
441   FIX(0.072200*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
442
443 #define RGB_TO_U_CCIR_709(r1, g1, b1, shift)\
444 (((- FIX(0.114572*224.0/255.0) * r1 - FIX(0.385427*224.0/255.0) * g1 +         \
445      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
446
447 #define RGB_TO_V_CCIR_709(r1, g1, b1, shift)\
448 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.454153*224.0/255.0) * g1 -           \
449    FIX(0.045847*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
450
451 static void
452 videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
453 {
454   int a, r, g, b;
455
456   if (v->info.colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
457     p->colors = vts_colors_bt601_ycbcr_100;
458   } else {
459     p->colors = vts_colors_bt709_ycbcr_100;
460   }
461   p->width = w;
462   p->height = h;
463
464   p->convert_tmpline = v->format->convert_hline;
465   if (v->format->type == VTS_RGB || v->format->type == VTS_BAYER) {
466     p->paint_tmpline = paint_tmpline_ARGB;
467   } else {
468     p->paint_tmpline = paint_tmpline_AYUV;
469   }
470   p->tmpline = v->tmpline;
471   p->tmpline2 = v->tmpline2;
472   p->tmpline_u8 = v->tmpline_u8;
473   p->tmpline_u16 = v->tmpline_u16;
474   p->x_offset = (v->horizontal_speed * v->n_frames) % p->width;
475   if (p->x_offset < 0)
476     p->x_offset += p->width;
477
478   a = (v->foreground_color >> 24) & 0xff;
479   r = (v->foreground_color >> 16) & 0xff;
480   g = (v->foreground_color >> 8) & 0xff;
481   b = (v->foreground_color >> 0) & 0xff;
482   p->foreground_color.A = a;
483   p->foreground_color.R = r;
484   p->foreground_color.G = g;
485   p->foreground_color.B = b;
486   if (v->info.colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
487     p->foreground_color.Y = RGB_TO_Y_CCIR (r, g, b);
488     p->foreground_color.U = RGB_TO_U_CCIR (r, g, b, 0);
489     p->foreground_color.V = RGB_TO_V_CCIR (r, g, b, 0);
490   } else {
491     p->foreground_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
492     p->foreground_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
493     p->foreground_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
494   }
495   p->foreground_color.gray = RGB_TO_Y (r, g, b);
496
497   a = (v->background_color >> 24) & 0xff;
498   r = (v->background_color >> 16) & 0xff;
499   g = (v->background_color >> 8) & 0xff;
500   b = (v->background_color >> 0) & 0xff;
501   p->background_color.A = a;
502   p->background_color.R = r;
503   p->background_color.G = g;
504   p->background_color.B = b;
505   if (v->info.colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
506     p->background_color.Y = RGB_TO_Y_CCIR (r, g, b);
507     p->background_color.U = RGB_TO_U_CCIR (r, g, b, 0);
508     p->background_color.V = RGB_TO_V_CCIR (r, g, b, 0);
509   } else {
510     p->background_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
511     p->background_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
512     p->background_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
513   }
514   p->background_color.gray = RGB_TO_Y (r, g, b);
515
516 }
517
518 static void
519 videotestsrc_convert_tmpline (paintinfo * p, GstVideoFrame * frame, int j)
520 {
521   int x = p->x_offset;
522   int i;
523
524   if (x != 0) {
525     memcpy (p->tmpline2, p->tmpline, p->width * 4);
526     memcpy (p->tmpline, p->tmpline2 + x * 4, (p->width - x) * 4);
527     memcpy (p->tmpline + (p->width - x) * 4, p->tmpline2, x * 4);
528   }
529
530   for (i = p->width; i < p->width + 5; i++) {
531     p->tmpline[4 * i + 0] = p->tmpline[4 * (p->width - 1) + 0];
532     p->tmpline[4 * i + 1] = p->tmpline[4 * (p->width - 1) + 1];
533     p->tmpline[4 * i + 2] = p->tmpline[4 * (p->width - 1) + 2];
534     p->tmpline[4 * i + 3] = p->tmpline[4 * (p->width - 1) + 3];
535   }
536
537   p->convert_tmpline (p, frame, j);
538 }
539
540 #define BLEND1(a,b,x) ((a)*(x) + (b)*(255-(x)))
541 #define DIV255(x) (((x) + (((x)+128)>>8) + 128)>>8)
542 #define BLEND(a,b,x) DIV255(BLEND1(a,b,x))
543
544 #ifdef unused
545 static void
546 videotestsrc_blend_color (struct vts_color_struct *dest,
547     struct vts_color_struct *a, struct vts_color_struct *b, int x)
548 {
549   dest->Y = BLEND (a->Y, b->Y, x);
550   dest->U = BLEND (a->U, b->U, x);
551   dest->V = BLEND (a->V, b->V, x);
552   dest->R = BLEND (a->R, b->R, x);
553   dest->G = BLEND (a->G, b->G, x);
554   dest->B = BLEND (a->B, b->B, x);
555   dest->gray = BLEND (a->gray, b->gray, x);
556
557 }
558 #endif
559
560 static void
561 videotestsrc_blend_line (GstVideoTestSrc * v, guint8 * dest, guint8 * src,
562     struct vts_color_struct *a, struct vts_color_struct *b, int n)
563 {
564   int i;
565   if (v->format->type == VTS_RGB || v->format->type == VTS_BAYER) {
566     for (i = 0; i < n; i++) {
567       dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
568       dest[i * 4 + 1] = BLEND (a->R, b->R, src[i]);
569       dest[i * 4 + 2] = BLEND (a->G, b->G, src[i]);
570       dest[i * 4 + 3] = BLEND (a->B, b->B, src[i]);
571     }
572   } else {
573     for (i = 0; i < n; i++) {
574       dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
575       dest[i * 4 + 1] = BLEND (a->Y, b->Y, src[i]);
576       dest[i * 4 + 2] = BLEND (a->U, b->U, src[i]);
577       dest[i * 4 + 3] = BLEND (a->V, b->V, src[i]);
578     }
579   }
580 #undef BLEND
581 }
582
583 void
584 gst_video_test_src_smpte (GstVideoTestSrc * v, GstVideoFrame * frame)
585 {
586   int i;
587   int y1, y2;
588   int j;
589   paintinfo pi = PAINT_INFO_INIT;
590   paintinfo *p = &pi;
591   struct format_list_struct *format;
592   int w = frame->info.width, h = frame->info.height;
593
594   videotestsrc_setup_paintinfo (v, p, frame->info.width, frame->info.height);
595   format = v->format;
596   if (format == NULL)
597     return;
598
599   format->paint_setup (p, frame);
600
601   y1 = 2 * h / 3;
602   y2 = 3 * h / 4;
603
604   /* color bars */
605   for (j = 0; j < y1; j++) {
606     for (i = 0; i < 7; i++) {
607       int x1 = i * w / 7;
608       int x2 = (i + 1) * w / 7;
609
610       p->color = p->colors + i;
611       p->paint_tmpline (p, x1, (x2 - x1));
612     }
613     videotestsrc_convert_tmpline (p, frame, j);
614   }
615
616   /* inverse blue bars */
617   for (j = y1; j < y2; j++) {
618     for (i = 0; i < 7; i++) {
619       int x1 = i * w / 7;
620       int x2 = (i + 1) * w / 7;
621       int k;
622
623       if (i & 1) {
624         k = 7;
625       } else {
626         k = 6 - i;
627       }
628       p->color = p->colors + k;
629       p->paint_tmpline (p, x1, (x2 - x1));
630     }
631     videotestsrc_convert_tmpline (p, frame, j);
632   }
633
634   for (j = y2; j < h; j++) {
635     /* -I, white, Q regions */
636     for (i = 0; i < 3; i++) {
637       int x1 = i * w / 6;
638       int x2 = (i + 1) * w / 6;
639       int k;
640
641       if (i == 0) {
642         k = 8;
643       } else if (i == 1) {
644         k = 0;
645       } else
646         k = 9;
647
648       p->color = p->colors + k;
649       p->paint_tmpline (p, x1, (x2 - x1));
650     }
651
652     /* superblack, black, dark grey */
653     for (i = 0; i < 3; i++) {
654       int x1 = w / 2 + i * w / 12;
655       int x2 = w / 2 + (i + 1) * w / 12;
656       int k;
657
658       if (i == 0) {
659         k = COLOR_SUPER_BLACK;
660       } else if (i == 1) {
661         k = COLOR_BLACK;
662       } else
663         k = COLOR_DARK_GREY;
664
665       p->color = p->colors + k;
666       p->paint_tmpline (p, x1, (x2 - x1));
667     }
668
669     {
670       int x1 = w * 3 / 4;
671       struct vts_color_struct color;
672
673       color = p->colors[COLOR_BLACK];
674       p->color = &color;
675
676       for (i = x1; i < w; i++) {
677         int y = random_char ();
678         p->tmpline_u8[i] = y;
679       }
680       videotestsrc_blend_line (v, p->tmpline + x1 * 4, p->tmpline_u8 + x1,
681           &p->foreground_color, &p->background_color, w - x1);
682
683     }
684     videotestsrc_convert_tmpline (p, frame, j);
685
686   }
687 }
688
689 void
690 gst_video_test_src_smpte75 (GstVideoTestSrc * v, GstVideoFrame * frame)
691 {
692   int i;
693   int j;
694   paintinfo pi = PAINT_INFO_INIT;
695   paintinfo *p = &pi;
696   struct format_list_struct *format;
697   int w = frame->info.width, h = frame->info.height;
698
699   videotestsrc_setup_paintinfo (v, p, w, h);
700   if (v->info.colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
701     p->colors = vts_colors_bt601_ycbcr_75;
702   } else {
703     p->colors = vts_colors_bt709_ycbcr_75;
704   }
705   format = v->format;
706   if (format == NULL)
707     return;
708
709   format->paint_setup (p, frame);
710
711   /* color bars */
712   for (j = 0; j < h; j++) {
713     for (i = 0; i < 7; i++) {
714       int x1 = i * w / 7;
715       int x2 = (i + 1) * w / 7;
716
717       p->color = p->colors + i;
718       p->paint_tmpline (p, x1, (x2 - x1));
719     }
720     videotestsrc_convert_tmpline (p, frame, j);
721   }
722 }
723
724 void
725 gst_video_test_src_smpte100 (GstVideoTestSrc * v, GstVideoFrame * frame)
726 {
727   int i;
728   int j;
729   paintinfo pi = PAINT_INFO_INIT;
730   paintinfo *p = &pi;
731   struct format_list_struct *format;
732   int w = frame->info.width, h = frame->info.height;
733
734   videotestsrc_setup_paintinfo (v, p, w, h);
735   format = v->format;
736   if (format == NULL)
737     return;
738
739   format->paint_setup (p, frame);
740
741   /* color bars */
742   for (j = 0; j < h; j++) {
743     for (i = 0; i < 7; i++) {
744       int x1 = i * w / 7;
745       int x2 = (i + 1) * w / 7;
746
747       p->color = p->colors + i;
748       p->paint_tmpline (p, x1, (x2 - x1));
749     }
750     videotestsrc_convert_tmpline (p, frame, j);
751   }
752 }
753
754 void
755 gst_video_test_src_bar (GstVideoTestSrc * v, GstVideoFrame * frame)
756 {
757   int j;
758   paintinfo pi = PAINT_INFO_INIT;
759   paintinfo *p = &pi;
760   struct format_list_struct *format;
761   int w = frame->info.width, h = frame->info.height;
762
763   videotestsrc_setup_paintinfo (v, p, w, h);
764   format = v->format;
765   if (format == NULL)
766     return;
767
768   format->paint_setup (p, frame);
769
770   for (j = 0; j < h; j++) {
771     /* use fixed size for now */
772     int x2 = w / 7;
773
774     p->color = &p->foreground_color;
775     p->paint_tmpline (p, 0, x2);
776     p->color = &p->background_color;
777     p->paint_tmpline (p, x2, (w - x2));
778     videotestsrc_convert_tmpline (p, frame, j);
779   }
780 }
781
782 void
783 gst_video_test_src_snow (GstVideoTestSrc * v, GstVideoFrame * frame)
784 {
785   int i;
786   int j;
787   paintinfo pi = PAINT_INFO_INIT;
788   paintinfo *p = &pi;
789   struct format_list_struct *format;
790   struct vts_color_struct color;
791   int w = frame->info.width, h = frame->info.height;
792
793   videotestsrc_setup_paintinfo (v, p, w, h);
794   format = v->format;
795   if (format == NULL)
796     return;
797
798   format->paint_setup (p, frame);
799
800   color = p->colors[COLOR_BLACK];
801   p->color = &color;
802
803   for (j = 0; j < h; j++) {
804     for (i = 0; i < w; i++) {
805       int y = random_char ();
806       p->tmpline_u8[i] = y;
807     }
808     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
809         &p->foreground_color, &p->background_color, p->width);
810     videotestsrc_convert_tmpline (p, frame, j);
811   }
812 }
813
814 static void
815 gst_video_test_src_unicolor (GstVideoTestSrc * v, GstVideoFrame * frame,
816     int color_index)
817 {
818   int i;
819   paintinfo pi = PAINT_INFO_INIT;
820   paintinfo *p = &pi;
821   struct format_list_struct *format;
822   int w = frame->info.width, h = frame->info.height;
823
824   videotestsrc_setup_paintinfo (v, p, w, h);
825   format = v->format;
826   if (format == NULL)
827     return;
828
829   format->paint_setup (p, frame);
830
831   p->color = p->colors + color_index;
832   if (color_index == COLOR_BLACK) {
833     p->color = &p->background_color;
834   }
835   if (color_index == COLOR_WHITE) {
836     p->color = &p->foreground_color;
837   }
838
839   for (i = 0; i < h; i++) {
840     p->paint_tmpline (p, 0, w);
841     videotestsrc_convert_tmpline (p, frame, i);
842   }
843 }
844
845 void
846 gst_video_test_src_black (GstVideoTestSrc * v, GstVideoFrame * frame)
847 {
848   gst_video_test_src_unicolor (v, frame, COLOR_BLACK);
849 }
850
851 void
852 gst_video_test_src_white (GstVideoTestSrc * v, GstVideoFrame * frame)
853 {
854   gst_video_test_src_unicolor (v, frame, COLOR_WHITE);
855 }
856
857 void
858 gst_video_test_src_red (GstVideoTestSrc * v, GstVideoFrame * frame)
859 {
860   gst_video_test_src_unicolor (v, frame, COLOR_RED);
861 }
862
863 void
864 gst_video_test_src_green (GstVideoTestSrc * v, GstVideoFrame * frame)
865 {
866   gst_video_test_src_unicolor (v, frame, COLOR_GREEN);
867 }
868
869 void
870 gst_video_test_src_blue (GstVideoTestSrc * v, GstVideoFrame * frame)
871 {
872   gst_video_test_src_unicolor (v, frame, COLOR_BLUE);
873 }
874
875 void
876 gst_video_test_src_blink (GstVideoTestSrc * v, GstVideoFrame * frame)
877 {
878   int i;
879   paintinfo pi = PAINT_INFO_INIT;
880   paintinfo *p = &pi;
881   struct format_list_struct *format;
882   int w = frame->info.width, h = frame->info.height;
883
884   videotestsrc_setup_paintinfo (v, p, w, h);
885
886   format = v->format;
887   if (format == NULL)
888     return;
889
890   format->paint_setup (p, frame);
891
892   if (v->n_frames & 1) {
893     p->color = &p->foreground_color;
894   } else {
895     p->color = &p->background_color;
896   }
897
898   for (i = 0; i < h; i++) {
899     p->paint_tmpline (p, 0, w);
900     videotestsrc_convert_tmpline (p, frame, i);
901   }
902 }
903
904 void
905 gst_video_test_src_solid (GstVideoTestSrc * v, GstVideoFrame * frame)
906 {
907   int i;
908   paintinfo pi = PAINT_INFO_INIT;
909   paintinfo *p = &pi;
910   struct format_list_struct *format;
911   int w = frame->info.width, h = frame->info.height;
912
913   videotestsrc_setup_paintinfo (v, p, w, h);
914
915   format = v->format;
916   if (format == NULL)
917     return;
918
919   format->paint_setup (p, frame);
920
921   p->color = &p->foreground_color;
922
923   for (i = 0; i < h; i++) {
924     p->paint_tmpline (p, 0, w);
925     videotestsrc_convert_tmpline (p, frame, i);
926   }
927 }
928
929 void
930 gst_video_test_src_checkers1 (GstVideoTestSrc * v, GstVideoFrame * frame)
931 {
932   int x, y;
933   paintinfo pi = PAINT_INFO_INIT;
934   paintinfo *p = &pi;
935   struct format_list_struct *format;
936   int w = frame->info.width, h = frame->info.height;
937
938   videotestsrc_setup_paintinfo (v, p, w, h);
939
940   format = v->format;
941   if (format == NULL)
942     return;
943
944   format->paint_setup (p, frame);
945
946   for (y = 0; y < h; y++) {
947     for (x = 0; x < w; x++) {
948       if ((x ^ y) & 1) {
949         p->color = p->colors + COLOR_GREEN;
950       } else {
951         p->color = p->colors + COLOR_RED;
952       }
953       p->paint_tmpline (p, x, 1);
954     }
955     videotestsrc_convert_tmpline (p, frame, y);
956   }
957 }
958
959 void
960 gst_video_test_src_checkers2 (GstVideoTestSrc * v, GstVideoFrame * frame)
961 {
962   int x, y;
963   paintinfo pi = PAINT_INFO_INIT;
964   paintinfo *p = &pi;
965   struct format_list_struct *format;
966   int w = frame->info.width, h = frame->info.height;
967
968   videotestsrc_setup_paintinfo (v, p, w, h);
969   format = v->format;
970   if (format == NULL)
971     return;
972
973   format->paint_setup (p, frame);
974
975   for (y = 0; y < h; y++) {
976     for (x = 0; x < w; x += 2) {
977       guint len = MIN (2, w - x);
978
979       if ((x ^ y) & 2) {
980         p->color = p->colors + COLOR_GREEN;
981       } else {
982         p->color = p->colors + COLOR_RED;
983       }
984       p->paint_tmpline (p, x, len);
985     }
986     videotestsrc_convert_tmpline (p, frame, y);
987   }
988 }
989
990 void
991 gst_video_test_src_checkers4 (GstVideoTestSrc * v, GstVideoFrame * frame)
992 {
993   int x, y;
994   paintinfo pi = PAINT_INFO_INIT;
995   paintinfo *p = &pi;
996   struct format_list_struct *format;
997   int w = frame->info.width, h = frame->info.height;
998
999   videotestsrc_setup_paintinfo (v, p, w, h);
1000   format = v->format;
1001   if (format == NULL)
1002     return;
1003
1004   format->paint_setup (p, frame);
1005
1006   for (y = 0; y < h; y++) {
1007     for (x = 0; x < w; x += 4) {
1008       guint len = MIN (4, w - x);
1009
1010       if ((x ^ y) & 4) {
1011         p->color = p->colors + COLOR_GREEN;
1012       } else {
1013         p->color = p->colors + COLOR_RED;
1014       }
1015       p->paint_tmpline (p, x, len);
1016     }
1017     videotestsrc_convert_tmpline (p, frame, y);
1018   }
1019 }
1020
1021 void
1022 gst_video_test_src_checkers8 (GstVideoTestSrc * v, GstVideoFrame * frame)
1023 {
1024   int x, y;
1025   paintinfo pi = PAINT_INFO_INIT;
1026   paintinfo *p = &pi;
1027   struct format_list_struct *format;
1028   int w = frame->info.width, h = frame->info.height;
1029
1030   videotestsrc_setup_paintinfo (v, p, w, h);
1031   format = v->format;
1032   if (format == NULL)
1033     return;
1034
1035   format->paint_setup (p, frame);
1036
1037   for (y = 0; y < h; y++) {
1038     for (x = 0; x < w; x += 8) {
1039       guint len = MIN (8, w - x);
1040
1041       if ((x ^ y) & 8) {
1042         p->color = p->colors + COLOR_GREEN;
1043       } else {
1044         p->color = p->colors + COLOR_RED;
1045       }
1046       p->paint_tmpline (p, x, len);
1047     }
1048     videotestsrc_convert_tmpline (p, frame, y);
1049   }
1050 }
1051
1052 static const guint8 sine_table[256] = {
1053   128, 131, 134, 137, 140, 143, 146, 149,
1054   152, 156, 159, 162, 165, 168, 171, 174,
1055   176, 179, 182, 185, 188, 191, 193, 196,
1056   199, 201, 204, 206, 209, 211, 213, 216,
1057   218, 220, 222, 224, 226, 228, 230, 232,
1058   234, 236, 237, 239, 240, 242, 243, 245,
1059   246, 247, 248, 249, 250, 251, 252, 252,
1060   253, 254, 254, 255, 255, 255, 255, 255,
1061   255, 255, 255, 255, 255, 255, 254, 254,
1062   253, 252, 252, 251, 250, 249, 248, 247,
1063   246, 245, 243, 242, 240, 239, 237, 236,
1064   234, 232, 230, 228, 226, 224, 222, 220,
1065   218, 216, 213, 211, 209, 206, 204, 201,
1066   199, 196, 193, 191, 188, 185, 182, 179,
1067   176, 174, 171, 168, 165, 162, 159, 156,
1068   152, 149, 146, 143, 140, 137, 134, 131,
1069   128, 124, 121, 118, 115, 112, 109, 106,
1070   103, 99, 96, 93, 90, 87, 84, 81,
1071   79, 76, 73, 70, 67, 64, 62, 59,
1072   56, 54, 51, 49, 46, 44, 42, 39,
1073   37, 35, 33, 31, 29, 27, 25, 23,
1074   21, 19, 18, 16, 15, 13, 12, 10,
1075   9, 8, 7, 6, 5, 4, 3, 3,
1076   2, 1, 1, 0, 0, 0, 0, 0,
1077   0, 0, 0, 0, 0, 0, 1, 1,
1078   2, 3, 3, 4, 5, 6, 7, 8,
1079   9, 10, 12, 13, 15, 16, 18, 19,
1080   21, 23, 25, 27, 29, 31, 33, 35,
1081   37, 39, 42, 44, 46, 49, 51, 54,
1082   56, 59, 62, 64, 67, 70, 73, 76,
1083   79, 81, 84, 87, 90, 93, 96, 99,
1084   103, 106, 109, 112, 115, 118, 121, 124
1085 };
1086
1087
1088 void
1089 gst_video_test_src_zoneplate (GstVideoTestSrc * v, GstVideoFrame * frame)
1090 {
1091   int i;
1092   int j;
1093   paintinfo pi = PAINT_INFO_INIT;
1094   paintinfo *p = &pi;
1095   struct format_list_struct *format;
1096   struct vts_color_struct color;
1097   int t = v->n_frames;
1098   int w = frame->info.width, h = frame->info.height;
1099   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1100   int yreset = -(h / 2) - v->yoffset;
1101
1102   int x, y;
1103   int accum_kx;
1104   int accum_kxt;
1105   int accum_ky;
1106   int accum_kyt;
1107   int accum_kxy;
1108   int kt;
1109   int kt2;
1110   int ky2;
1111   int delta_kxt = v->kxt * t;
1112   int delta_kxy;
1113   int scale_kxy = 0xffff / (w / 2);
1114   int scale_kx2 = 0xffff / w;
1115
1116   videotestsrc_setup_paintinfo (v, p, w, h);
1117   format = v->format;
1118   if (format == NULL)
1119     return;
1120
1121   format->paint_setup (p, frame);
1122
1123   color = p->colors[COLOR_BLACK];
1124   p->color = &color;
1125
1126   /* Zoneplate equation:
1127    *
1128    * phase = k0 + kx*x + ky*y + kt*t
1129    *       + kxt*x*t + kyt*y*t + kxy*x*y
1130    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1131    */
1132
1133 #if 0
1134   for (j = 0, y = yreset; j < h; j++, y++) {
1135     for (i = 0, x = xreset; i < w; i++, x++) {
1136
1137       /* zero order */
1138       int phase = v->k0;
1139
1140       /* first order */
1141       phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
1142
1143       /* cross term */
1144       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1145       /* phase = phase + (v->kxy * x * y) / (w/2); */
1146
1147       /*second order */
1148       /*normalise x/y terms to rate of change of phase at the picture edge */
1149       phase =
1150           phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
1151           ((v->kt2 * t * t) >> 1);
1152
1153       color.Y = sine_table[phase & 0xff];
1154
1155       color.R = color.Y;
1156       color.G = color.Y;
1157       color.B = color.Y;
1158       p->paint_tmpline (p, i, 1);
1159     }
1160   }
1161 #endif
1162
1163   /* optimised version, with original code shown in comments */
1164   accum_ky = 0;
1165   accum_kyt = 0;
1166   kt = v->kt * t;
1167   kt2 = v->kt2 * t * t;
1168   for (j = 0, y = yreset; j < h; j++, y++) {
1169     accum_kx = 0;
1170     accum_kxt = 0;
1171     accum_ky += v->ky;
1172     accum_kyt += v->kyt * t;
1173     delta_kxy = v->kxy * y * scale_kxy;
1174     accum_kxy = delta_kxy * xreset;
1175     ky2 = (v->ky2 * y * y) / h;
1176     for (i = 0, x = xreset; i < w; i++, x++) {
1177
1178       /* zero order */
1179       int phase = v->k0;
1180
1181       /* first order */
1182       accum_kx += v->kx;
1183       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1184       phase = phase + accum_kx + accum_ky + kt;
1185
1186       /* cross term */
1187       accum_kxt += delta_kxt;
1188       accum_kxy += delta_kxy;
1189       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1190       phase = phase + accum_kxt + accum_kyt;
1191
1192       /* phase = phase + (v->kxy * x * y) / (w/2); */
1193       /* phase = phase + accum_kxy / (w/2); */
1194       phase = phase + (accum_kxy >> 16);
1195
1196       /*second order */
1197       /*normalise x/y terms to rate of change of phase at the picture edge */
1198       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1199       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1200
1201       p->tmpline_u8[i] = sine_table[phase & 0xff];
1202     }
1203     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1204         &p->foreground_color, &p->background_color, p->width);
1205     videotestsrc_convert_tmpline (p, frame, j);
1206   }
1207 }
1208
1209 void
1210 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, GstVideoFrame * frame)
1211 {
1212   int i;
1213   int j;
1214   paintinfo pi = PAINT_INFO_INIT;
1215   paintinfo *p = &pi;
1216   struct format_list_struct *format;
1217   struct vts_color_struct color;
1218   int t = v->n_frames;
1219   int w = frame->info.width, h = frame->info.height;
1220
1221   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1222   int yreset = -(h / 2) - v->yoffset;
1223
1224   int x, y;
1225   int accum_kx;
1226   int accum_kxt;
1227   int accum_ky;
1228   int accum_kyt;
1229   int accum_kxy;
1230   int kt;
1231   int kt2;
1232   int ky2;
1233   int delta_kxt = v->kxt * t;
1234   int delta_kxy;
1235   int scale_kxy = 0xffff / (w / 2);
1236   int scale_kx2 = 0xffff / w;
1237
1238   videotestsrc_setup_paintinfo (v, p, w, h);
1239   format = v->format;
1240   if (format == NULL)
1241     return;
1242
1243   format->paint_setup (p, frame);
1244
1245   color = p->colors[COLOR_BLACK];
1246   p->color = &color;
1247
1248   /* Zoneplate equation:
1249    *
1250    * phase = k0 + kx*x + ky*y + kt*t
1251    *       + kxt*x*t + kyt*y*t + kxy*x*y
1252    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1253    */
1254
1255   /* optimised version, with original code shown in comments */
1256   accum_ky = 0;
1257   accum_kyt = 0;
1258   kt = v->kt * t;
1259   kt2 = v->kt2 * t * t;
1260   for (j = 0, y = yreset; j < h; j++, y++) {
1261     accum_kx = 0;
1262     accum_kxt = 0;
1263     accum_ky += v->ky;
1264     accum_kyt += v->kyt * t;
1265     delta_kxy = v->kxy * y * scale_kxy;
1266     accum_kxy = delta_kxy * xreset;
1267     ky2 = (v->ky2 * y * y) / h;
1268     for (i = 0, x = xreset; i < w; i++, x++) {
1269
1270       /* zero order */
1271       int phase = v->k0;
1272
1273       /* first order */
1274       accum_kx += v->kx;
1275       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1276       phase = phase + accum_kx + accum_ky + kt;
1277
1278       /* cross term */
1279       accum_kxt += delta_kxt;
1280       accum_kxy += delta_kxy;
1281       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1282       phase = phase + accum_kxt + accum_kyt;
1283
1284       /* phase = phase + (v->kxy * x * y) / (w/2); */
1285       /* phase = phase + accum_kxy / (w/2); */
1286       phase = phase + (accum_kxy >> 16);
1287
1288       /*second order */
1289       /*normalise x/y terms to rate of change of phase at the picture edge */
1290       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1291       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1292
1293       color.Y = 128;
1294       color.U = sine_table[phase & 0xff];
1295       color.V = sine_table[phase & 0xff];
1296
1297       color.R = 128;
1298       color.G = 128;
1299       color.B = color.V;
1300
1301       color.gray = color.Y << 8;
1302       p->paint_tmpline (p, i, 1);
1303     }
1304     videotestsrc_convert_tmpline (p, frame, j);
1305   }
1306 }
1307
1308 #undef SCALE_AMPLITUDE
1309 void
1310 gst_video_test_src_circular (GstVideoTestSrc * v, GstVideoFrame * frame)
1311 {
1312   int i;
1313   int j;
1314   paintinfo pi = PAINT_INFO_INIT;
1315   paintinfo *p = &pi;
1316   struct format_list_struct *format;
1317   double freq[8];
1318   int w = frame->info.width, h = frame->info.height;
1319
1320   int d;
1321
1322   videotestsrc_setup_paintinfo (v, p, w, h);
1323   format = v->format;
1324   if (format == NULL)
1325     return;
1326
1327   format->paint_setup (p, frame);
1328
1329   for (i = 1; i < 8; i++) {
1330     freq[i] = 200 * pow (2.0, -(i - 1) / 4.0);
1331   }
1332
1333   for (j = 0; j < h; j++) {
1334     for (i = 0; i < w; i++) {
1335       double dist;
1336       int seg;
1337
1338       dist =
1339           sqrt ((2 * i - w) * (2 * i - w) + (2 * j - h) * (2 * j -
1340               h)) / (2 * w);
1341       seg = floor (dist * 16);
1342       if (seg == 0 || seg >= 8) {
1343         p->tmpline_u8[i] = 0;
1344       } else {
1345         d = floor (256 * dist * freq[seg] + 0.5);
1346         p->tmpline_u8[i] = sine_table[d & 0xff];
1347       }
1348     }
1349     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1350         &p->foreground_color, &p->background_color, p->width);
1351     videotestsrc_convert_tmpline (p, frame, j);
1352   }
1353 }
1354
1355 void
1356 gst_video_test_src_gamut (GstVideoTestSrc * v, GstVideoFrame * frame)
1357 {
1358   int x, y;
1359   paintinfo pi = PAINT_INFO_INIT;
1360   paintinfo *p = &pi;
1361   struct format_list_struct *format;
1362   struct vts_color_struct yuv_primary;
1363   struct vts_color_struct yuv_secondary;
1364   int w = frame->info.width, h = frame->info.height;
1365
1366   videotestsrc_setup_paintinfo (v, p, w, h);
1367   format = v->format;
1368   if (format == NULL)
1369     return;
1370
1371   format->paint_setup (p, frame);
1372
1373   for (y = 0; y < h; y++) {
1374     int region = (y * 4) / h;
1375
1376     switch (region) {
1377       case 0:                  /* black */
1378         yuv_primary = p->colors[COLOR_BLACK];
1379         yuv_secondary = p->colors[COLOR_BLACK];
1380         yuv_secondary.Y = 0;
1381         break;
1382       case 1:
1383         yuv_primary = p->colors[COLOR_WHITE];
1384         yuv_secondary = p->colors[COLOR_WHITE];
1385         yuv_secondary.Y = 255;
1386         break;
1387       case 2:
1388         yuv_primary = p->colors[COLOR_RED];
1389         yuv_secondary = p->colors[COLOR_RED];
1390         yuv_secondary.V = 255;
1391         break;
1392       case 3:
1393         yuv_primary = p->colors[COLOR_BLUE];
1394         yuv_secondary = p->colors[COLOR_BLUE];
1395         yuv_secondary.U = 255;
1396         break;
1397     }
1398
1399     for (x = 0; x < w; x += 8) {
1400       int len = MIN (8, w - x);
1401
1402       if ((x ^ y) & (1 << 4)) {
1403         p->color = &yuv_primary;
1404       } else {
1405         p->color = &yuv_secondary;
1406       }
1407       p->paint_tmpline (p, x, len);
1408     }
1409     videotestsrc_convert_tmpline (p, frame, y);
1410   }
1411 }
1412
1413 void
1414 gst_video_test_src_ball (GstVideoTestSrc * v, GstVideoFrame * frame)
1415 {
1416   int i;
1417   paintinfo pi = PAINT_INFO_INIT;
1418   paintinfo *p = &pi;
1419   struct format_list_struct *format;
1420   int t = v->n_frames;
1421   double x, y;
1422   int radius = 20;
1423   int w = frame->info.width, h = frame->info.height;
1424
1425   videotestsrc_setup_paintinfo (v, p, w, h);
1426   format = v->format;
1427   if (format == NULL)
1428     return;
1429
1430   format->paint_setup (p, frame);
1431
1432   x = radius + (0.5 + 0.5 * sin (2 * G_PI * t / 200)) * (w - 2 * radius);
1433   y = radius + (0.5 + 0.5 * sin (2 * G_PI * sqrt (2) * t / 200)) * (h -
1434       2 * radius);
1435
1436   for (i = 0; i < h; i++) {
1437     if (i < y - radius || i > y + radius) {
1438       memset (p->tmpline_u8, 0, w);
1439     } else {
1440       int r = rint (sqrt (radius * radius - (i - y) * (i - y)));
1441       int x1, x2;
1442       int j;
1443
1444       x1 = 0;
1445       x2 = MAX (0, x - r);
1446       for (j = x1; j < x2; j++) {
1447         p->tmpline_u8[j] = 0;
1448       }
1449
1450       x1 = MAX (0, x - r);
1451       x2 = MIN (w, x + r + 1);
1452       for (j = x1; j < x2; j++) {
1453         double rr = radius - sqrt ((j - x) * (j - x) + (i - y) * (i - y));
1454
1455         rr *= 0.5;
1456         p->tmpline_u8[j] = CLAMP ((int) floor (256 * rr), 0, 255);
1457       }
1458
1459       x1 = MIN (w, x + r + 1);
1460       x2 = w;
1461       for (j = x1; j < x2; j++) {
1462         p->tmpline_u8[j] = 0;
1463       }
1464     }
1465     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1466         &p->foreground_color, &p->background_color, p->width);
1467     videotestsrc_convert_tmpline (p, frame, i);
1468   }
1469 }
1470
1471 static void
1472 paint_tmpline_ARGB (paintinfo * p, int x, int w)
1473 {
1474   int offset;
1475   guint32 value;
1476
1477 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1478   value = (p->color->A << 0) | (p->color->R << 8) |
1479       (p->color->G << 16) | (p->color->B << 24);
1480 #else
1481   value = (p->color->A << 24) | (p->color->R << 16) |
1482       (p->color->G << 8) | (p->color->B << 0);
1483 #endif
1484
1485   offset = (x * 4);
1486   gst_orc_splat_u32 (p->tmpline + offset, value, w);
1487 }
1488
1489 static void
1490 paint_tmpline_AYUV (paintinfo * p, int x, int w)
1491 {
1492   int offset;
1493   guint32 value;
1494
1495 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1496   value = (p->color->A << 0) | (p->color->Y << 8) |
1497       (p->color->U << 16) | (p->color->V << 24);
1498 #else
1499   value = (p->color->A << 24) | (p->color->Y << 16) |
1500       (p->color->U << 8) | (p->color->V << 0);
1501 #endif
1502
1503   offset = (x * 4);
1504   gst_orc_splat_u32 (p->tmpline + offset, value, w);
1505 }
1506
1507 static void
1508 paint_setup_generic (paintinfo * p, GstVideoFrame * frame)
1509 {
1510   p->size = frame->info.size;
1511 }
1512
1513 static void
1514 convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y)
1515 {
1516   const GstVideoFormatInfo *finfo = frame->info.finfo;
1517   gint i, width = p->width;
1518   gpointer src;
1519
1520   if (finfo->unpack_format == GST_VIDEO_FORMAT_AYUV64 ||
1521       finfo->unpack_format == GST_VIDEO_FORMAT_ARGB64) {
1522     /* 16 bits */
1523     for (i = 0; i < width; i++) {
1524       p->tmpline_u16[i * 4 + 0] = TO_16 (p->tmpline[i * 4 + 0]);
1525       p->tmpline_u16[i * 4 + 1] = TO_16 (p->tmpline[i * 4 + 1]);
1526       p->tmpline_u16[i * 4 + 2] = TO_16 (p->tmpline[i * 4 + 2]);
1527       p->tmpline_u16[i * 4 + 3] = TO_16 (p->tmpline[i * 4 + 3]);
1528     }
1529     src = p->tmpline_u16;
1530   } else {
1531     src = p->tmpline;
1532   }
1533   finfo->pack_func (finfo, GST_VIDEO_PACK_FLAG_NONE,
1534       src, 0, frame->data, frame->info.stride,
1535       frame->info.chroma_site, y, width);
1536 }
1537
1538 static void
1539 paint_setup_bayer_bggr (paintinfo * p, GstVideoFrame * frame)
1540 {
1541   p->size = GST_ROUND_UP_4 (p->width) * p->height;
1542   p->bayer_x_invert = 0;
1543   p->bayer_y_invert = 0;
1544 }
1545
1546 static void
1547 paint_setup_bayer_rggb (paintinfo * p, GstVideoFrame * frame)
1548 {
1549   p->size = GST_ROUND_UP_4 (p->width) * p->height;
1550   p->bayer_x_invert = 1;
1551   p->bayer_y_invert = 1;
1552 }
1553
1554 static void
1555 paint_setup_bayer_grbg (paintinfo * p, GstVideoFrame * frame)
1556 {
1557   p->size = GST_ROUND_UP_4 (p->width) * p->height;
1558   p->bayer_x_invert = 0;
1559   p->bayer_y_invert = 1;
1560 }
1561
1562 static void
1563 paint_setup_bayer_gbrg (paintinfo * p, GstVideoFrame * frame)
1564 {
1565   p->size = GST_ROUND_UP_4 (p->width) * p->height;
1566   p->bayer_x_invert = 1;
1567   p->bayer_y_invert = 0;
1568 }
1569
1570 static void
1571 convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y)
1572 {
1573   int i;
1574   guint8 *data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
1575   guint8 *R = data + y * GST_ROUND_UP_4 (p->width);
1576   guint8 *argb = p->tmpline;
1577   int x_inv = p->bayer_x_invert;
1578   int y_inv = p->bayer_y_invert;
1579
1580   if ((y ^ y_inv) & 1) {
1581     for (i = 0; i < p->width; i++) {
1582       if ((i ^ x_inv) & 1) {
1583         R[i] = argb[4 * i + 1];
1584       } else {
1585         R[i] = argb[4 * i + 2];
1586       }
1587     }
1588   } else {
1589     for (i = 0; i < p->width; i++) {
1590       if ((i ^ x_inv) & 1) {
1591         R[i] = argb[4 * i + 2];
1592       } else {
1593         R[i] = argb[4 * i + 3];
1594       }
1595     }
1596   }
1597 }