videotestsrc: port to video helpers
[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 #define TO_10(x) (((x)<<2) | ((x)>>6))
37
38 static void paint_tmpline_ARGB (paintinfo * p, int x, int w);
39 static void paint_tmpline_AYUV (paintinfo * p, int x, int w);
40
41 static unsigned char
42 random_char (void)
43 {
44   static unsigned int state;
45
46   state *= 1103515245;
47   state += 12345;
48   return (state >> 16) & 0xff;
49 }
50
51 enum
52 {
53   COLOR_WHITE = 0,
54   COLOR_YELLOW,
55   COLOR_CYAN,
56   COLOR_GREEN,
57   COLOR_MAGENTA,
58   COLOR_RED,
59   COLOR_BLUE,
60   COLOR_BLACK,
61   COLOR_NEG_I,
62   COLOR_POS_Q,
63   COLOR_SUPER_BLACK,
64   COLOR_DARK_GREY
65 };
66
67 static const struct vts_color_struct vts_colors_bt709_ycbcr_100[] = {
68   {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
69   {219, 16, 138, 255, 255, 255, 0, (219 << 8)},
70   {188, 154, 16, 255, 0, 255, 255, (188 < 8)},
71   {173, 42, 26, 255, 0, 255, 0, (173 << 8)},
72   {78, 214, 230, 255, 255, 0, 255, (78 << 8)},
73   {63, 102, 240, 255, 255, 0, 0, (64 << 8)},
74   {32, 240, 118, 255, 0, 0, 255, (32 << 8)},
75   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
76   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
77   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
78   {0, 128, 128, 255, 0, 0, 0, 0},
79   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
80 };
81
82 static const struct vts_color_struct vts_colors_bt709_ycbcr_75[] = {
83   {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
84   {168, 44, 136, 255, 191, 191, 0, (168 << 8)},
85   {145, 147, 44, 255, 0, 191, 191, (145 << 8)},
86   {133, 63, 52, 255, 0, 191, 0, (133 << 8)},
87   {63, 193, 204, 255, 191, 0, 191, (63 << 8)},
88   {51, 109, 212, 255, 191, 0, 0, (51 << 8)},
89   {28, 212, 120, 255, 0, 0, 191, (28 << 8)},
90   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
91   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
92   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
93   {0, 128, 128, 255, 0, 0, 0, 0},
94   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
95 };
96
97 static const struct vts_color_struct vts_colors_bt601_ycbcr_100[] = {
98   {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
99   {210, 16, 146, 255, 255, 255, 0, (219 << 8)},
100   {170, 166, 16, 255, 0, 255, 255, (188 < 8)},
101   {145, 54, 34, 255, 0, 255, 0, (173 << 8)},
102   {106, 202, 222, 255, 255, 0, 255, (78 << 8)},
103   {81, 90, 240, 255, 255, 0, 0, (64 << 8)},
104   {41, 240, 110, 255, 0, 0, 255, (32 << 8)},
105   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
106   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
107   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
108   {-0, 128, 128, 255, 0, 0, 0, 0},
109   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
110 };
111
112 static const struct vts_color_struct vts_colors_bt601_ycbcr_75[] = {
113   {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
114   {162, 44, 142, 255, 191, 191, 0, (168 << 8)},
115   {131, 156, 44, 255, 0, 191, 191, (145 << 8)},
116   {112, 72, 58, 255, 0, 191, 0, (133 << 8)},
117   {84, 184, 198, 255, 191, 0, 191, (63 << 8)},
118   {65, 100, 212, 255, 191, 0, 0, (51 << 8)},
119   {35, 212, 114, 255, 0, 0, 191, (28 << 8)},
120   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
121   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
122   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
123   {-0, 128, 128, 255, 0, 0, 0, 0},
124   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
125 };
126
127
128 static void paint_setup_I420 (paintinfo * p, GstVideoFrame * frame);
129 static void paint_setup_YV12 (paintinfo * p, GstVideoFrame * frame);
130 static void paint_setup_YUY2 (paintinfo * p, GstVideoFrame * frame);
131 static void paint_setup_UYVY (paintinfo * p, GstVideoFrame * frame);
132 static void paint_setup_YVYU (paintinfo * p, GstVideoFrame * frame);
133 #ifdef disabled
134 static void paint_setup_IYU2 (paintinfo * p, GstVideoFrame * frame);
135 #endif
136 static void paint_setup_Y41B (paintinfo * p, GstVideoFrame * frame);
137 static void paint_setup_Y42B (paintinfo * p, GstVideoFrame * frame);
138 static void paint_setup_Y444 (paintinfo * p, GstVideoFrame * frame);
139 static void paint_setup_Y800 (paintinfo * p, GstVideoFrame * frame);
140 static void paint_setup_AYUV (paintinfo * p, GstVideoFrame * frame);
141 static void paint_setup_v308 (paintinfo * p, GstVideoFrame * frame);
142 static void paint_setup_NV12 (paintinfo * p, GstVideoFrame * frame);
143 static void paint_setup_NV21 (paintinfo * p, GstVideoFrame * frame);
144 #ifdef disabled
145 static void paint_setup_v410 (paintinfo * p, GstVideoFrame * frame);
146 #endif
147 static void paint_setup_v216 (paintinfo * p, GstVideoFrame * frame);
148 static void paint_setup_v210 (paintinfo * p, GstVideoFrame * frame);
149 static void paint_setup_UYVP (paintinfo * p, GstVideoFrame * frame);
150 static void paint_setup_AY64 (paintinfo * p, GstVideoFrame * frame);
151
152 static void paint_setup_YUV9 (paintinfo * p, GstVideoFrame * frame);
153 static void paint_setup_YVU9 (paintinfo * p, GstVideoFrame * frame);
154 static void paint_setup_ARGB8888 (paintinfo * p, GstVideoFrame * frame);
155 static void paint_setup_ABGR8888 (paintinfo * p, GstVideoFrame * frame);
156 static void paint_setup_RGBA8888 (paintinfo * p, GstVideoFrame * frame);
157 static void paint_setup_BGRA8888 (paintinfo * p, GstVideoFrame * frame);
158 static void paint_setup_xRGB8888 (paintinfo * p, GstVideoFrame * frame);
159 static void paint_setup_xBGR8888 (paintinfo * p, GstVideoFrame * frame);
160 static void paint_setup_RGBx8888 (paintinfo * p, GstVideoFrame * frame);
161 static void paint_setup_BGRx8888 (paintinfo * p, GstVideoFrame * frame);
162 static void paint_setup_RGB888 (paintinfo * p, GstVideoFrame * frame);
163 static void paint_setup_BGR888 (paintinfo * p, GstVideoFrame * frame);
164 static void paint_setup_RGB565 (paintinfo * p, GstVideoFrame * frame);
165 static void paint_setup_xRGB1555 (paintinfo * p, GstVideoFrame * frame);
166 static void paint_setup_ARGB64 (paintinfo * p, GstVideoFrame * frame);
167
168 static void paint_setup_bayer_bggr (paintinfo * p, GstVideoFrame * frame);
169 static void paint_setup_bayer_rggb (paintinfo * p, GstVideoFrame * frame);
170 static void paint_setup_bayer_gbrg (paintinfo * p, GstVideoFrame * frame);
171 static void paint_setup_bayer_grbg (paintinfo * p, GstVideoFrame * frame);
172
173 static void convert_hline_I420 (paintinfo * p, int y);
174 static void convert_hline_NV12 (paintinfo * p, int y);
175 static void convert_hline_NV21 (paintinfo * p, int y);
176 static void convert_hline_YUY2 (paintinfo * p, int y);
177 #ifdef disabled
178 static void convert_hline_IYU2 (paintinfo * p, int y);
179 #endif
180 static void convert_hline_Y41B (paintinfo * p, int y);
181 static void convert_hline_Y42B (paintinfo * p, int y);
182 static void convert_hline_Y444 (paintinfo * p, int y);
183 static void convert_hline_Y800 (paintinfo * p, int y);
184 static void convert_hline_v308 (paintinfo * p, int y);
185 static void convert_hline_AYUV (paintinfo * p, int y);
186 #ifdef disabled
187 static void convert_hline_v410 (paintinfo * p, int y);
188 #endif
189 static void convert_hline_v216 (paintinfo * p, int y);
190 static void convert_hline_v210 (paintinfo * p, int y);
191 static void convert_hline_UYVP (paintinfo * p, int y);
192 static void convert_hline_AY64 (paintinfo * p, int y);
193
194 static void convert_hline_YUV9 (paintinfo * p, int y);
195 static void convert_hline_astr4 (paintinfo * p, int y);
196 static void convert_hline_astr8 (paintinfo * p, int y);
197 static void convert_hline_str4 (paintinfo * p, int y);
198 static void convert_hline_str3 (paintinfo * p, int y);
199 static void convert_hline_RGB565 (paintinfo * p, int y);
200 static void convert_hline_xRGB1555 (paintinfo * p, int y);
201
202 static void convert_hline_bayer (paintinfo * p, int y);
203
204 static void paint_setup_GRAY8 (paintinfo * p, GstVideoFrame * frame);
205 static void paint_setup_GRAY16 (paintinfo * p, GstVideoFrame * frame);
206 static void convert_hline_GRAY8 (paintinfo * p, int y);
207 static void convert_hline_GRAY16 (paintinfo * p, int y);
208
209 struct format_list_struct format_list[] = {
210 /* packed */
211   {VTS_YUV, "YUY2", "YUY2", 16, paint_setup_YUY2, convert_hline_YUY2},
212   {VTS_YUV, "UYVY", "UYVY", 16, paint_setup_UYVY, convert_hline_YUY2},
213 #ifdef disabled
214   {VTS_YUV, "Y422", "Y422", 16, paint_setup_UYVY, convert_hline_YUY2},
215   {VTS_YUV, "UYNV", "UYNV", 16, paint_setup_UYVY, convert_hline_YUY2},  /* FIXME: UYNV? */
216 #endif
217   {VTS_YUV, "YVYU", "YVYU", 16, paint_setup_YVYU, convert_hline_YUY2},
218   {VTS_YUV, "v308", "v308", 24, paint_setup_v308, convert_hline_v308},
219   {VTS_YUV, "AYUV", "AYUV", 32, paint_setup_AYUV, convert_hline_AYUV},
220 #ifdef disabled
221   {VTS_YUV, "v410", "v410", 32, paint_setup_v410, convert_hline_v410},
222 #endif
223   {VTS_YUV, "v210", "v210", 21, paint_setup_v210, convert_hline_v210},
224   {VTS_YUV, "v216", "v216", 32, paint_setup_v216, convert_hline_v216},
225   {VTS_YUV, "UYVP", "UYVP", 20, paint_setup_UYVP, convert_hline_UYVP},
226   {VTS_YUV, "AY64", "AY64", 64, paint_setup_AY64, convert_hline_AY64},
227
228 #ifdef disabled
229   {VTS_YUV, "IYU2", "IYU2", 24, paint_setup_IYU2, convert_hline_IYU2},
230 #endif
231
232 /* planar */
233   /* YVU9 */
234   {VTS_YUV, "YVU9", "YVU9", 9, paint_setup_YVU9, convert_hline_YUV9},
235   /* YUV9 */
236   {VTS_YUV, "YUV9", "YUV9", 9, paint_setup_YUV9, convert_hline_YUV9},
237   /* IF09 */
238   /* YV12 */
239   {VTS_YUV, "YV12", "YV12", 12, paint_setup_YV12, convert_hline_I420},
240   /* I420 */
241   {VTS_YUV, "I420", "I420", 12, paint_setup_I420, convert_hline_I420},
242   /* NV12 */
243   {VTS_YUV, "NV12", "NV12", 12, paint_setup_NV12, convert_hline_NV12},
244   /* NV21 */
245   {VTS_YUV, "NV21", "NV21", 12, paint_setup_NV21, convert_hline_NV21},
246   /* CLPL */
247   /* Y41B */
248   {VTS_YUV, "Y41B", "Y41B", 12, paint_setup_Y41B, convert_hline_Y41B},
249   /* Y42B */
250   {VTS_YUV, "Y42B", "Y42B", 16, paint_setup_Y42B, convert_hline_Y42B},
251   /* Y444 */
252   {VTS_YUV, "Y444", "Y444", 24, paint_setup_Y444, convert_hline_Y444},
253   /* Y800 grayscale */
254   {VTS_YUV, "Y800", "Y800", 8, paint_setup_Y800, convert_hline_Y800},
255
256   /* Not exactly YUV but it's the same as above */
257   {VTS_GRAY, "GRAY8", "GRAY8", 8, paint_setup_GRAY8, convert_hline_GRAY8},
258 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
259   {VTS_GRAY, "GRAY16_LE", "GRAY16", 16, paint_setup_GRAY16,
260       convert_hline_GRAY16},
261 #else
262   {VTS_GRAY, "GRAY16_BE", "GRAY16", 16, paint_setup_GRAY16,
263       convert_hline_GRAY16},
264 #endif
265
266   {VTS_RGB, "xRGB", "xRGB8888", 32, paint_setup_xRGB8888, convert_hline_str4,
267         24,
268       0x00ff0000, 0x0000ff00, 0x000000ff},
269   {VTS_RGB, "xBGR", "xBGR8888", 32, paint_setup_xBGR8888, convert_hline_str4,
270         24,
271       0x000000ff, 0x0000ff00, 0x00ff0000},
272   {VTS_RGB, "RGBx", "RGBx8888", 32, paint_setup_RGBx8888, convert_hline_str4,
273         24,
274       0xff000000, 0x00ff0000, 0x0000ff00},
275   {VTS_RGB, "BGRx", "BGRx8888", 32, paint_setup_BGRx8888, convert_hline_str4,
276         24,
277       0x0000ff00, 0x00ff0000, 0xff000000},
278   {VTS_RGB, "ARGB", "ARGB8888", 32, paint_setup_ARGB8888, convert_hline_astr4,
279         32,
280       0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},
281   {VTS_RGB, "ABGR", "ABGR8888", 32, paint_setup_ABGR8888, convert_hline_astr4,
282         32,
283       0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000},
284   {VTS_RGB, "RGBA", "RGBA8888", 32, paint_setup_RGBA8888, convert_hline_astr4,
285         32,
286       0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff},
287   {VTS_RGB, "BGRA", "BGRA8888", 32, paint_setup_BGRA8888, convert_hline_astr4,
288         32,
289       0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff},
290   {VTS_RGB, "RGB", "RGB888", 24, paint_setup_RGB888, convert_hline_str3, 24,
291       0x00ff0000, 0x0000ff00, 0x000000ff},
292   {VTS_RGB, "BGR", "BGR888", 24, paint_setup_BGR888, convert_hline_str3, 24,
293       0x000000ff, 0x0000ff00, 0x00ff0000},
294   {VTS_RGB, "RGB16", "RGB565", 16, paint_setup_RGB565, convert_hline_RGB565, 16,
295       0x0000f800, 0x000007e0, 0x0000001f},
296   {VTS_RGB, "RGB15", "xRGB1555", 16, paint_setup_xRGB1555,
297         convert_hline_xRGB1555,
298         15,
299       0x00007c00, 0x000003e0, 0x0000001f},
300   {VTS_RGB, "ARGB64", "ARGB8888", 64, paint_setup_ARGB64, convert_hline_astr8,
301         64,
302       0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},
303
304   {VTS_BAYER, "bggr", "Bayer", 8, paint_setup_bayer_bggr, convert_hline_bayer},
305   {VTS_BAYER, "rggb", "Bayer", 8, paint_setup_bayer_rggb, convert_hline_bayer},
306   {VTS_BAYER, "grbg", "Bayer", 8, paint_setup_bayer_grbg, convert_hline_bayer},
307   {VTS_BAYER, "gbrg", "Bayer", 8, paint_setup_bayer_gbrg, convert_hline_bayer}
308 };
309
310 int n_formats = G_N_ELEMENTS (format_list);
311
312 struct format_list_struct *
313 paintinfo_find_by_structure (const GstStructure * structure)
314 {
315   int i;
316   const char *media_type = gst_structure_get_name (structure);
317
318   g_return_val_if_fail (structure, NULL);
319
320   if (strcmp (media_type, "video/x-raw") == 0) {
321     const gchar *format;
322
323     format = gst_structure_get_string (structure, "format");
324     if (!format) {
325       GST_WARNING ("incomplete caps structure: %" GST_PTR_FORMAT, structure);
326       return NULL;
327     }
328
329     for (i = 0; i < n_formats; i++) {
330       if (g_str_equal (format, format_list[i].format)) {
331         return format_list + i;
332       }
333     }
334     return NULL;
335   } else if (strcmp (media_type, "video/x-raw-bayer") == 0) {
336     const gchar *format;
337
338     format = gst_structure_get_string (structure, "format");
339     if (!format) {
340       GST_WARNING ("incomplete caps structure: %" GST_PTR_FORMAT, structure);
341       return NULL;
342     }
343
344     for (i = 0; i < n_formats; i++) {
345       if (format_list[i].type == VTS_BAYER &&
346           g_str_equal (format, format_list[i].format)) {
347         return format_list + i;
348       }
349     }
350     return NULL;
351   }
352
353   g_critical ("format not found for media type %s", media_type);
354
355   return NULL;
356 }
357
358 struct format_list_struct *
359 paintrect_find_format (const gchar * find_format)
360 {
361   int i;
362
363   for (i = 0; i < n_formats; i++) {
364     if (g_str_equal (find_format, format_list[i].format)) {
365       return format_list + i;
366     }
367   }
368   return NULL;
369 }
370
371 struct format_list_struct *
372 paintrect_find_name (const char *name)
373 {
374   int i;
375
376   for (i = 0; i < n_formats; i++) {
377     if (g_str_equal (name, format_list[i].name)) {
378       return format_list + i;
379     }
380   }
381   return NULL;
382 }
383
384
385 GstStructure *
386 paint_get_structure (struct format_list_struct * format)
387 {
388   GstStructure *structure = NULL;
389
390   g_return_val_if_fail (format, NULL);
391
392   switch (format->type) {
393     case VTS_RGB:
394     case VTS_GRAY:
395       structure = gst_structure_new ("video/x-raw",
396           "format", G_TYPE_STRING, format->format, NULL);
397       break;
398     case VTS_YUV:
399     {
400       GValue value_list = { 0 };
401       GValue value = { 0 };
402
403       structure = gst_structure_new ("video/x-raw",
404           "format", G_TYPE_STRING, format->format, NULL);
405
406       if (strcmp (format->format, "Y800") != 0) {
407         g_value_init (&value_list, GST_TYPE_LIST);
408
409         g_value_init (&value, G_TYPE_STRING);
410         g_value_set_static_string (&value, "sdtv");
411         gst_value_list_append_value (&value_list, &value);
412
413         g_value_set_static_string (&value, "hdtv");
414         gst_value_list_append_value (&value_list, &value);
415
416         gst_structure_set_value (structure, "color-matrix", &value_list);
417         g_value_reset (&value_list);
418
419         if (strcmp (format->format, "AYUV") &&
420             strcmp (format->format, "v308") &&
421             strcmp (format->format, "v410") &&
422             strcmp (format->format, "Y444")) {
423           g_value_set_static_string (&value, "mpeg2");
424           gst_value_list_append_value (&value_list, &value);
425
426           g_value_set_static_string (&value, "jpeg");
427           gst_value_list_append_value (&value_list, &value);
428
429           gst_structure_set_value (structure, "chroma-site", &value_list);
430         }
431         g_value_unset (&value_list);
432       }
433     }
434       break;
435     case VTS_BAYER:
436       structure = gst_structure_new ("video/x-raw-bayer",
437           "format", G_TYPE_STRING, format->format, NULL);
438       break;
439     default:
440       g_assert_not_reached ();
441       break;
442   }
443   return structure;
444 }
445
446 /* returns the size in bytes for one video frame of the given dimensions
447  * given the format in GstVideoTestSrc */
448 int
449 gst_video_test_src_get_size (GstVideoTestSrc * v, int w, int h)
450 {
451   paintinfo pi = { NULL, };
452   paintinfo *p = &pi;
453   struct format_list_struct *format;
454
455   p->width = w;
456   p->height = h;
457   format = v->format;
458   if (format == NULL)
459     return 0;
460
461   format->paint_setup (p, NULL);
462
463   return p->size;
464 }
465
466 #define SCALEBITS 10
467 #define ONE_HALF  (1 << (SCALEBITS - 1))
468 #define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
469
470 #define RGB_TO_Y(r, g, b) \
471 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
472   FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
473
474 #define RGB_TO_U(r1, g1, b1, shift)\
475 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
476      FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
477
478 #define RGB_TO_V(r1, g1, b1, shift)\
479 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
480    FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
481
482 #define RGB_TO_Y_CCIR(r, g, b) \
483 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
484   FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
485
486 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
487 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
488      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
489
490 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
491 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
492    FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
493
494 #define RGB_TO_Y_CCIR_709(r, g, b) \
495 ((FIX(0.212600*219.0/255.0) * (r) + FIX(0.715200*219.0/255.0) * (g) + \
496   FIX(0.072200*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
497
498 #define RGB_TO_U_CCIR_709(r1, g1, b1, shift)\
499 (((- FIX(0.114572*224.0/255.0) * r1 - FIX(0.385427*224.0/255.0) * g1 +         \
500      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
501
502 #define RGB_TO_V_CCIR_709(r1, g1, b1, shift)\
503 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.454153*224.0/255.0) * g1 -           \
504    FIX(0.045847*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
505
506 static void
507 videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
508 {
509   int a, r, g, b;
510
511   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
512     p->colors = vts_colors_bt601_ycbcr_100;
513   } else {
514     p->colors = vts_colors_bt709_ycbcr_100;
515   }
516   p->width = w;
517   p->height = h;
518
519   p->convert_tmpline = v->format->convert_hline;
520   if (v->format->type == VTS_RGB || v->format->type == VTS_BAYER) {
521     p->paint_tmpline = paint_tmpline_ARGB;
522   } else {
523     p->paint_tmpline = paint_tmpline_AYUV;
524   }
525   p->tmpline = v->tmpline;
526   p->tmpline2 = v->tmpline2;
527   p->tmpline_u8 = v->tmpline_u8;
528   p->x_offset = (v->horizontal_speed * v->n_frames) % p->width;
529   if (p->x_offset < 0)
530     p->x_offset += p->width;
531
532   a = (v->foreground_color >> 24) & 0xff;
533   r = (v->foreground_color >> 16) & 0xff;
534   g = (v->foreground_color >> 8) & 0xff;
535   b = (v->foreground_color >> 0) & 0xff;
536   p->foreground_color.A = a;
537   p->foreground_color.R = r;
538   p->foreground_color.G = g;
539   p->foreground_color.B = b;
540   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
541     p->foreground_color.Y = RGB_TO_Y_CCIR (r, g, b);
542     p->foreground_color.U = RGB_TO_U_CCIR (r, g, b, 0);
543     p->foreground_color.V = RGB_TO_V_CCIR (r, g, b, 0);
544   } else {
545     p->foreground_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
546     p->foreground_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
547     p->foreground_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
548   }
549   p->foreground_color.gray = RGB_TO_Y (r, g, b);
550
551   a = (v->background_color >> 24) & 0xff;
552   r = (v->background_color >> 16) & 0xff;
553   g = (v->background_color >> 8) & 0xff;
554   b = (v->background_color >> 0) & 0xff;
555   p->background_color.A = a;
556   p->background_color.R = r;
557   p->background_color.G = g;
558   p->background_color.B = b;
559   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
560     p->background_color.Y = RGB_TO_Y_CCIR (r, g, b);
561     p->background_color.U = RGB_TO_U_CCIR (r, g, b, 0);
562     p->background_color.V = RGB_TO_V_CCIR (r, g, b, 0);
563   } else {
564     p->background_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
565     p->background_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
566     p->background_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
567   }
568   p->background_color.gray = RGB_TO_Y (r, g, b);
569
570 }
571
572 static void
573 videotestsrc_convert_tmpline (paintinfo * p, int j)
574 {
575   int x = p->x_offset;
576   int i;
577
578   if (x != 0) {
579     memcpy (p->tmpline2, p->tmpline, p->width * 4);
580     memcpy (p->tmpline, p->tmpline2 + x * 4, (p->width - x) * 4);
581     memcpy (p->tmpline + (p->width - x) * 4, p->tmpline2, x * 4);
582   }
583
584   for (i = p->width; i < p->width + 5; i++) {
585     p->tmpline[4 * i + 0] = p->tmpline[4 * (p->width - 1) + 0];
586     p->tmpline[4 * i + 1] = p->tmpline[4 * (p->width - 1) + 1];
587     p->tmpline[4 * i + 2] = p->tmpline[4 * (p->width - 1) + 2];
588     p->tmpline[4 * i + 3] = p->tmpline[4 * (p->width - 1) + 3];
589   }
590
591   p->convert_tmpline (p, j);
592 }
593
594 #define BLEND1(a,b,x) ((a)*(x) + (b)*(255-(x)))
595 #define DIV255(x) (((x) + (((x)+128)>>8) + 128)>>8)
596 #define BLEND(a,b,x) DIV255(BLEND1(a,b,x))
597
598 #ifdef unused
599 static void
600 videotestsrc_blend_color (struct vts_color_struct *dest,
601     struct vts_color_struct *a, struct vts_color_struct *b, int x)
602 {
603   dest->Y = BLEND (a->Y, b->Y, x);
604   dest->U = BLEND (a->U, b->U, x);
605   dest->V = BLEND (a->V, b->V, x);
606   dest->R = BLEND (a->R, b->R, x);
607   dest->G = BLEND (a->G, b->G, x);
608   dest->B = BLEND (a->B, b->B, x);
609   dest->gray = BLEND (a->gray, b->gray, x);
610
611 }
612 #endif
613
614 static void
615 videotestsrc_blend_line (GstVideoTestSrc * v, guint8 * dest, guint8 * src,
616     struct vts_color_struct *a, struct vts_color_struct *b, int n)
617 {
618   int i;
619   if (v->format->type == VTS_RGB || v->format->type == VTS_BAYER) {
620     for (i = 0; i < n; i++) {
621       dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
622       dest[i * 4 + 1] = BLEND (a->R, b->R, src[i]);
623       dest[i * 4 + 2] = BLEND (a->G, b->G, src[i]);
624       dest[i * 4 + 3] = BLEND (a->B, b->B, src[i]);
625     }
626   } else {
627     for (i = 0; i < n; i++) {
628       dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
629       dest[i * 4 + 1] = BLEND (a->Y, b->Y, src[i]);
630       dest[i * 4 + 2] = BLEND (a->U, b->U, src[i]);
631       dest[i * 4 + 3] = BLEND (a->V, b->V, src[i]);
632     }
633   }
634 #undef BLEND
635 }
636
637 void
638 gst_video_test_src_smpte (GstVideoTestSrc * v, GstVideoFrame * frame)
639 {
640   int i;
641   int y1, y2;
642   int j;
643   paintinfo pi = { NULL, };
644   paintinfo *p = &pi;
645   struct format_list_struct *format;
646   int w = frame->info.width, h = frame->info.height;
647
648   videotestsrc_setup_paintinfo (v, p, frame->info.width, frame->info.height);
649   format = v->format;
650   if (format == NULL)
651     return;
652
653   format->paint_setup (p, frame);
654
655   y1 = 2 * h / 3;
656   y2 = h * 0.75;
657
658   /* color bars */
659   for (j = 0; j < y1; j++) {
660     for (i = 0; i < 7; i++) {
661       int x1 = i * w / 7;
662       int x2 = (i + 1) * w / 7;
663
664       p->color = p->colors + i;
665       p->paint_tmpline (p, x1, (x2 - x1));
666     }
667     videotestsrc_convert_tmpline (p, j);
668   }
669
670   /* inverse blue bars */
671   for (j = y1; j < y2; j++) {
672     for (i = 0; i < 7; i++) {
673       int x1 = i * w / 7;
674       int x2 = (i + 1) * w / 7;
675       int k;
676
677       if (i & 1) {
678         k = 7;
679       } else {
680         k = 6 - i;
681       }
682       p->color = p->colors + k;
683       p->paint_tmpline (p, x1, (x2 - x1));
684     }
685     videotestsrc_convert_tmpline (p, j);
686   }
687
688   for (j = y2; j < h; j++) {
689     /* -I, white, Q regions */
690     for (i = 0; i < 3; i++) {
691       int x1 = i * w / 6;
692       int x2 = (i + 1) * w / 6;
693       int k;
694
695       if (i == 0) {
696         k = 8;
697       } else if (i == 1) {
698         k = 0;
699       } else
700         k = 9;
701
702       p->color = p->colors + k;
703       p->paint_tmpline (p, x1, (x2 - x1));
704     }
705
706     /* superblack, black, dark grey */
707     for (i = 0; i < 3; i++) {
708       int x1 = w / 2 + i * w / 12;
709       int x2 = w / 2 + (i + 1) * w / 12;
710       int k;
711
712       if (i == 0) {
713         k = COLOR_SUPER_BLACK;
714       } else if (i == 1) {
715         k = COLOR_BLACK;
716       } else
717         k = COLOR_DARK_GREY;
718
719       p->color = p->colors + k;
720       p->paint_tmpline (p, x1, (x2 - x1));
721     }
722
723     {
724       int x1 = w * 3 / 4;
725       struct vts_color_struct color;
726
727       color = p->colors[COLOR_BLACK];
728       p->color = &color;
729
730       for (i = x1; i < w; i++) {
731         int y = random_char ();
732         p->tmpline_u8[i] = y;
733       }
734       videotestsrc_blend_line (v, p->tmpline + x1 * 4, p->tmpline_u8 + x1,
735           &p->foreground_color, &p->background_color, w - x1);
736
737     }
738     videotestsrc_convert_tmpline (p, j);
739
740   }
741 }
742
743 void
744 gst_video_test_src_smpte75 (GstVideoTestSrc * v, GstVideoFrame * frame)
745 {
746   int i;
747   int j;
748   paintinfo pi = { NULL, };
749   paintinfo *p = &pi;
750   struct format_list_struct *format;
751   int w = frame->info.width, h = frame->info.height;
752
753   videotestsrc_setup_paintinfo (v, p, w, h);
754   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
755     p->colors = vts_colors_bt601_ycbcr_75;
756   } else {
757     p->colors = vts_colors_bt709_ycbcr_75;
758   }
759   format = v->format;
760   if (format == NULL)
761     return;
762
763   format->paint_setup (p, frame);
764
765   /* color bars */
766   for (j = 0; j < h; j++) {
767     for (i = 0; i < 7; i++) {
768       int x1 = i * w / 7;
769       int x2 = (i + 1) * w / 7;
770
771       p->color = p->colors + i;
772       p->paint_tmpline (p, x1, (x2 - x1));
773     }
774     videotestsrc_convert_tmpline (p, j);
775   }
776 }
777
778 void
779 gst_video_test_src_smpte100 (GstVideoTestSrc * v, GstVideoFrame * frame)
780 {
781   int i;
782   int j;
783   paintinfo pi = { NULL, };
784   paintinfo *p = &pi;
785   struct format_list_struct *format;
786   int w = frame->info.width, h = frame->info.height;
787
788   videotestsrc_setup_paintinfo (v, p, w, h);
789   format = v->format;
790   if (format == NULL)
791     return;
792
793   format->paint_setup (p, frame);
794
795   /* color bars */
796   for (j = 0; j < h; j++) {
797     for (i = 0; i < 7; i++) {
798       int x1 = i * w / 7;
799       int x2 = (i + 1) * w / 7;
800
801       p->color = p->colors + i;
802       p->paint_tmpline (p, x1, (x2 - x1));
803     }
804     videotestsrc_convert_tmpline (p, j);
805   }
806 }
807
808 void
809 gst_video_test_src_bar (GstVideoTestSrc * v, GstVideoFrame * frame)
810 {
811   int j;
812   paintinfo pi = { NULL, };
813   paintinfo *p = &pi;
814   struct format_list_struct *format;
815   int w = frame->info.width, h = frame->info.height;
816
817   videotestsrc_setup_paintinfo (v, p, w, h);
818   format = v->format;
819   if (format == NULL)
820     return;
821
822   format->paint_setup (p, frame);
823
824   for (j = 0; j < h; j++) {
825     /* use fixed size for now */
826     int x2 = w / 7;
827
828     p->color = &p->foreground_color;
829     p->paint_tmpline (p, 0, x2);
830     p->color = &p->background_color;
831     p->paint_tmpline (p, x2, (w - x2));
832     videotestsrc_convert_tmpline (p, j);
833   }
834 }
835
836 void
837 gst_video_test_src_snow (GstVideoTestSrc * v, GstVideoFrame * frame)
838 {
839   int i;
840   int j;
841   paintinfo pi = { NULL, };
842   paintinfo *p = &pi;
843   struct format_list_struct *format;
844   struct vts_color_struct color;
845   int w = frame->info.width, h = frame->info.height;
846
847   videotestsrc_setup_paintinfo (v, p, w, h);
848   format = v->format;
849   if (format == NULL)
850     return;
851
852   format->paint_setup (p, frame);
853
854   color = p->colors[COLOR_BLACK];
855   p->color = &color;
856
857   for (j = 0; j < h; j++) {
858     for (i = 0; i < w; i++) {
859       int y = random_char ();
860       p->tmpline_u8[i] = y;
861     }
862     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
863         &p->foreground_color, &p->background_color, p->width);
864     videotestsrc_convert_tmpline (p, j);
865   }
866 }
867
868 static void
869 gst_video_test_src_unicolor (GstVideoTestSrc * v, GstVideoFrame * frame,
870     int color_index)
871 {
872   int i;
873   paintinfo pi = { NULL, };
874   paintinfo *p = &pi;
875   struct format_list_struct *format;
876   int w = frame->info.width, h = frame->info.height;
877
878   videotestsrc_setup_paintinfo (v, p, w, h);
879   format = v->format;
880   if (format == NULL)
881     return;
882
883   format->paint_setup (p, frame);
884
885   p->color = p->colors + color_index;
886   if (color_index == COLOR_BLACK) {
887     p->color = &p->background_color;
888   }
889   if (color_index == COLOR_WHITE) {
890     p->color = &p->foreground_color;
891   }
892
893   for (i = 0; i < h; i++) {
894     p->paint_tmpline (p, 0, w);
895     videotestsrc_convert_tmpline (p, i);
896   }
897 }
898
899 void
900 gst_video_test_src_black (GstVideoTestSrc * v, GstVideoFrame * frame)
901 {
902   gst_video_test_src_unicolor (v, frame, COLOR_BLACK);
903 }
904
905 void
906 gst_video_test_src_white (GstVideoTestSrc * v, GstVideoFrame * frame)
907 {
908   gst_video_test_src_unicolor (v, frame, COLOR_WHITE);
909 }
910
911 void
912 gst_video_test_src_red (GstVideoTestSrc * v, GstVideoFrame * frame)
913 {
914   gst_video_test_src_unicolor (v, frame, COLOR_RED);
915 }
916
917 void
918 gst_video_test_src_green (GstVideoTestSrc * v, GstVideoFrame * frame)
919 {
920   gst_video_test_src_unicolor (v, frame, COLOR_GREEN);
921 }
922
923 void
924 gst_video_test_src_blue (GstVideoTestSrc * v, GstVideoFrame * frame)
925 {
926   gst_video_test_src_unicolor (v, frame, COLOR_BLUE);
927 }
928
929 void
930 gst_video_test_src_blink (GstVideoTestSrc * v, GstVideoFrame * frame)
931 {
932   int i;
933   paintinfo pi = { NULL, };
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   if (v->n_frames & 1) {
947     p->color = &p->foreground_color;
948   } else {
949     p->color = &p->background_color;
950   }
951
952   for (i = 0; i < h; i++) {
953     p->paint_tmpline (p, 0, w);
954     videotestsrc_convert_tmpline (p, i);
955   }
956 }
957
958 void
959 gst_video_test_src_solid (GstVideoTestSrc * v, GstVideoFrame * frame)
960 {
961   int i;
962   paintinfo pi = { NULL, };
963   paintinfo *p = &pi;
964   struct format_list_struct *format;
965   int w = frame->info.width, h = frame->info.height;
966
967   videotestsrc_setup_paintinfo (v, p, w, h);
968
969   format = v->format;
970   if (format == NULL)
971     return;
972
973   format->paint_setup (p, frame);
974
975   p->color = &p->foreground_color;
976
977   for (i = 0; i < h; i++) {
978     p->paint_tmpline (p, 0, w);
979     videotestsrc_convert_tmpline (p, i);
980   }
981 }
982
983 void
984 gst_video_test_src_checkers1 (GstVideoTestSrc * v, GstVideoFrame * frame)
985 {
986   int x, y;
987   paintinfo pi = { NULL, };
988   paintinfo *p = &pi;
989   struct format_list_struct *format;
990   int w = frame->info.width, h = frame->info.height;
991
992   videotestsrc_setup_paintinfo (v, p, w, h);
993
994   format = v->format;
995   if (format == NULL)
996     return;
997
998   format->paint_setup (p, frame);
999
1000   for (y = 0; y < h; y++) {
1001     for (x = 0; x < w; x++) {
1002       if ((x ^ y) & 1) {
1003         p->color = p->colors + COLOR_GREEN;
1004       } else {
1005         p->color = p->colors + COLOR_RED;
1006       }
1007       p->paint_tmpline (p, x, 1);
1008     }
1009     videotestsrc_convert_tmpline (p, y);
1010   }
1011 }
1012
1013 void
1014 gst_video_test_src_checkers2 (GstVideoTestSrc * v, GstVideoFrame * frame)
1015 {
1016   int x, y;
1017   paintinfo pi = { NULL, };
1018   paintinfo *p = &pi;
1019   struct format_list_struct *format;
1020   int w = frame->info.width, h = frame->info.height;
1021
1022   videotestsrc_setup_paintinfo (v, p, w, h);
1023   format = v->format;
1024   if (format == NULL)
1025     return;
1026
1027   format->paint_setup (p, frame);
1028
1029   for (y = 0; y < h; y++) {
1030     for (x = 0; x < w; x += 2) {
1031       guint len = MIN (2, w - x);
1032
1033       if ((x ^ y) & 2) {
1034         p->color = p->colors + COLOR_GREEN;
1035       } else {
1036         p->color = p->colors + COLOR_RED;
1037       }
1038       p->paint_tmpline (p, x, len);
1039     }
1040     videotestsrc_convert_tmpline (p, y);
1041   }
1042 }
1043
1044 void
1045 gst_video_test_src_checkers4 (GstVideoTestSrc * v, GstVideoFrame * frame)
1046 {
1047   int x, y;
1048   paintinfo pi = { NULL, };
1049   paintinfo *p = &pi;
1050   struct format_list_struct *format;
1051   int w = frame->info.width, h = frame->info.height;
1052
1053   videotestsrc_setup_paintinfo (v, p, w, h);
1054   format = v->format;
1055   if (format == NULL)
1056     return;
1057
1058   format->paint_setup (p, frame);
1059
1060   for (y = 0; y < h; y++) {
1061     for (x = 0; x < w; x += 4) {
1062       guint len = MIN (4, w - x);
1063
1064       if ((x ^ y) & 4) {
1065         p->color = p->colors + COLOR_GREEN;
1066       } else {
1067         p->color = p->colors + COLOR_RED;
1068       }
1069       p->paint_tmpline (p, x, len);
1070     }
1071     videotestsrc_convert_tmpline (p, y);
1072   }
1073 }
1074
1075 void
1076 gst_video_test_src_checkers8 (GstVideoTestSrc * v, GstVideoFrame * frame)
1077 {
1078   int x, y;
1079   paintinfo pi = { NULL, };
1080   paintinfo *p = &pi;
1081   struct format_list_struct *format;
1082   int w = frame->info.width, h = frame->info.height;
1083
1084   videotestsrc_setup_paintinfo (v, p, w, h);
1085   format = v->format;
1086   if (format == NULL)
1087     return;
1088
1089   format->paint_setup (p, frame);
1090
1091   for (y = 0; y < h; y++) {
1092     for (x = 0; x < w; x += 8) {
1093       guint len = MIN (8, w - x);
1094
1095       if ((x ^ y) & 8) {
1096         p->color = p->colors + COLOR_GREEN;
1097       } else {
1098         p->color = p->colors + COLOR_RED;
1099       }
1100       p->paint_tmpline (p, x, len);
1101     }
1102     videotestsrc_convert_tmpline (p, y);
1103   }
1104 }
1105
1106 static const guint8 sine_table[256] = {
1107   128, 131, 134, 137, 140, 143, 146, 149,
1108   152, 156, 159, 162, 165, 168, 171, 174,
1109   176, 179, 182, 185, 188, 191, 193, 196,
1110   199, 201, 204, 206, 209, 211, 213, 216,
1111   218, 220, 222, 224, 226, 228, 230, 232,
1112   234, 236, 237, 239, 240, 242, 243, 245,
1113   246, 247, 248, 249, 250, 251, 252, 252,
1114   253, 254, 254, 255, 255, 255, 255, 255,
1115   255, 255, 255, 255, 255, 255, 254, 254,
1116   253, 252, 252, 251, 250, 249, 248, 247,
1117   246, 245, 243, 242, 240, 239, 237, 236,
1118   234, 232, 230, 228, 226, 224, 222, 220,
1119   218, 216, 213, 211, 209, 206, 204, 201,
1120   199, 196, 193, 191, 188, 185, 182, 179,
1121   176, 174, 171, 168, 165, 162, 159, 156,
1122   152, 149, 146, 143, 140, 137, 134, 131,
1123   128, 124, 121, 118, 115, 112, 109, 106,
1124   103, 99, 96, 93, 90, 87, 84, 81,
1125   79, 76, 73, 70, 67, 64, 62, 59,
1126   56, 54, 51, 49, 46, 44, 42, 39,
1127   37, 35, 33, 31, 29, 27, 25, 23,
1128   21, 19, 18, 16, 15, 13, 12, 10,
1129   9, 8, 7, 6, 5, 4, 3, 3,
1130   2, 1, 1, 0, 0, 0, 0, 0,
1131   0, 0, 0, 0, 0, 0, 1, 1,
1132   2, 3, 3, 4, 5, 6, 7, 8,
1133   9, 10, 12, 13, 15, 16, 18, 19,
1134   21, 23, 25, 27, 29, 31, 33, 35,
1135   37, 39, 42, 44, 46, 49, 51, 54,
1136   56, 59, 62, 64, 67, 70, 73, 76,
1137   79, 81, 84, 87, 90, 93, 96, 99,
1138   103, 106, 109, 112, 115, 118, 121, 124
1139 };
1140
1141
1142 void
1143 gst_video_test_src_zoneplate (GstVideoTestSrc * v, GstVideoFrame * frame)
1144 {
1145   int i;
1146   int j;
1147   paintinfo pi = { NULL, };
1148   paintinfo *p = &pi;
1149   struct format_list_struct *format;
1150   struct vts_color_struct color;
1151   int t = v->n_frames;
1152   int w = frame->info.width, h = frame->info.height;
1153   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1154   int yreset = -(h / 2) - v->yoffset;
1155
1156   int x, y;
1157   int accum_kx;
1158   int accum_kxt;
1159   int accum_ky;
1160   int accum_kyt;
1161   int accum_kxy;
1162   int kt;
1163   int kt2;
1164   int ky2;
1165   int delta_kxt = v->kxt * t;
1166   int delta_kxy;
1167   int scale_kxy = 0xffff / (w / 2);
1168   int scale_kx2 = 0xffff / w;
1169
1170   videotestsrc_setup_paintinfo (v, p, w, h);
1171   format = v->format;
1172   if (format == NULL)
1173     return;
1174
1175   format->paint_setup (p, frame);
1176
1177   color = p->colors[COLOR_BLACK];
1178   p->color = &color;
1179
1180   /* Zoneplate equation:
1181    *
1182    * phase = k0 + kx*x + ky*y + kt*t
1183    *       + kxt*x*t + kyt*y*t + kxy*x*y
1184    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1185    */
1186
1187 #if 0
1188   for (j = 0, y = yreset; j < h; j++, y++) {
1189     for (i = 0, x = xreset; i < w; i++, x++) {
1190
1191       /* zero order */
1192       int phase = v->k0;
1193
1194       /* first order */
1195       phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
1196
1197       /* cross term */
1198       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1199       /* phase = phase + (v->kxy * x * y) / (w/2); */
1200
1201       /*second order */
1202       /*normalise x/y terms to rate of change of phase at the picture edge */
1203       phase =
1204           phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
1205           ((v->kt2 * t * t) >> 1);
1206
1207       color.Y = sine_table[phase & 0xff];
1208
1209       color.R = color.Y;
1210       color.G = color.Y;
1211       color.B = color.Y;
1212       p->paint_tmpline (p, i, 1);
1213     }
1214   }
1215 #endif
1216
1217   /* optimised version, with original code shown in comments */
1218   accum_ky = 0;
1219   accum_kyt = 0;
1220   kt = v->kt * t;
1221   kt2 = v->kt2 * t * t;
1222   for (j = 0, y = yreset; j < h; j++, y++) {
1223     accum_kx = 0;
1224     accum_kxt = 0;
1225     accum_ky += v->ky;
1226     accum_kyt += v->kyt * t;
1227     delta_kxy = v->kxy * y * scale_kxy;
1228     accum_kxy = delta_kxy * xreset;
1229     ky2 = (v->ky2 * y * y) / h;
1230     for (i = 0, x = xreset; i < w; i++, x++) {
1231
1232       /* zero order */
1233       int phase = v->k0;
1234
1235       /* first order */
1236       accum_kx += v->kx;
1237       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1238       phase = phase + accum_kx + accum_ky + kt;
1239
1240       /* cross term */
1241       accum_kxt += delta_kxt;
1242       accum_kxy += delta_kxy;
1243       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1244       phase = phase + accum_kxt + accum_kyt;
1245
1246       /* phase = phase + (v->kxy * x * y) / (w/2); */
1247       /* phase = phase + accum_kxy / (w/2); */
1248       phase = phase + (accum_kxy >> 16);
1249
1250       /*second order */
1251       /*normalise x/y terms to rate of change of phase at the picture edge */
1252       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1253       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1254
1255       p->tmpline_u8[i] = sine_table[phase & 0xff];
1256     }
1257     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1258         &p->foreground_color, &p->background_color, p->width);
1259     videotestsrc_convert_tmpline (p, j);
1260   }
1261 }
1262
1263 void
1264 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, GstVideoFrame * frame)
1265 {
1266   int i;
1267   int j;
1268   paintinfo pi = { NULL, };
1269   paintinfo *p = &pi;
1270   struct format_list_struct *format;
1271   struct vts_color_struct color;
1272   int t = v->n_frames;
1273   int w = frame->info.width, h = frame->info.height;
1274
1275   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1276   int yreset = -(h / 2) - v->yoffset;
1277
1278   int x, y;
1279   int accum_kx;
1280   int accum_kxt;
1281   int accum_ky;
1282   int accum_kyt;
1283   int accum_kxy;
1284   int kt;
1285   int kt2;
1286   int ky2;
1287   int delta_kxt = v->kxt * t;
1288   int delta_kxy;
1289   int scale_kxy = 0xffff / (w / 2);
1290   int scale_kx2 = 0xffff / w;
1291
1292   videotestsrc_setup_paintinfo (v, p, w, h);
1293   format = v->format;
1294   if (format == NULL)
1295     return;
1296
1297   format->paint_setup (p, frame);
1298
1299   color = p->colors[COLOR_BLACK];
1300   p->color = &color;
1301
1302   /* Zoneplate equation:
1303    *
1304    * phase = k0 + kx*x + ky*y + kt*t
1305    *       + kxt*x*t + kyt*y*t + kxy*x*y
1306    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1307    */
1308
1309   /* optimised version, with original code shown in comments */
1310   accum_ky = 0;
1311   accum_kyt = 0;
1312   kt = v->kt * t;
1313   kt2 = v->kt2 * t * t;
1314   for (j = 0, y = yreset; j < h; j++, y++) {
1315     accum_kx = 0;
1316     accum_kxt = 0;
1317     accum_ky += v->ky;
1318     accum_kyt += v->kyt * t;
1319     delta_kxy = v->kxy * y * scale_kxy;
1320     accum_kxy = delta_kxy * xreset;
1321     ky2 = (v->ky2 * y * y) / h;
1322     for (i = 0, x = xreset; i < w; i++, x++) {
1323
1324       /* zero order */
1325       int phase = v->k0;
1326
1327       /* first order */
1328       accum_kx += v->kx;
1329       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1330       phase = phase + accum_kx + accum_ky + kt;
1331
1332       /* cross term */
1333       accum_kxt += delta_kxt;
1334       accum_kxy += delta_kxy;
1335       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1336       phase = phase + accum_kxt + accum_kyt;
1337
1338       /* phase = phase + (v->kxy * x * y) / (w/2); */
1339       /* phase = phase + accum_kxy / (w/2); */
1340       phase = phase + (accum_kxy >> 16);
1341
1342       /*second order */
1343       /*normalise x/y terms to rate of change of phase at the picture edge */
1344       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1345       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1346
1347       color.Y = 128;
1348       color.U = sine_table[phase & 0xff];
1349       color.V = sine_table[phase & 0xff];
1350
1351       color.R = 128;
1352       color.G = 128;
1353       color.B = color.V;
1354
1355       color.gray = color.Y << 8;
1356       p->paint_tmpline (p, i, 1);
1357     }
1358     videotestsrc_convert_tmpline (p, j);
1359   }
1360 }
1361
1362 #undef SCALE_AMPLITUDE
1363 void
1364 gst_video_test_src_circular (GstVideoTestSrc * v, GstVideoFrame * frame)
1365 {
1366   int i;
1367   int j;
1368   paintinfo pi = { NULL, };
1369   paintinfo *p = &pi;
1370   struct format_list_struct *format;
1371   double freq[8];
1372   int w = frame->info.width, h = frame->info.height;
1373
1374   int d;
1375
1376   videotestsrc_setup_paintinfo (v, p, w, h);
1377   format = v->format;
1378   if (format == NULL)
1379     return;
1380
1381   format->paint_setup (p, frame);
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, p->width);
1405     videotestsrc_convert_tmpline (p, j);
1406   }
1407 }
1408
1409 void
1410 gst_video_test_src_gamut (GstVideoTestSrc * v, GstVideoFrame * frame)
1411 {
1412   int x, y;
1413   paintinfo pi = { NULL, };
1414   paintinfo *p = &pi;
1415   struct format_list_struct *format;
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   format = v->format;
1422   if (format == NULL)
1423     return;
1424
1425   format->paint_setup (p, frame);
1426
1427   for (y = 0; y < h; y++) {
1428     int region = (y * 4) / h;
1429
1430     switch (region) {
1431       case 0:                  /* black */
1432         yuv_primary = p->colors[COLOR_BLACK];
1433         yuv_secondary = p->colors[COLOR_BLACK];
1434         yuv_secondary.Y = 0;
1435         break;
1436       case 1:
1437         yuv_primary = p->colors[COLOR_WHITE];
1438         yuv_secondary = p->colors[COLOR_WHITE];
1439         yuv_secondary.Y = 255;
1440         break;
1441       case 2:
1442         yuv_primary = p->colors[COLOR_RED];
1443         yuv_secondary = p->colors[COLOR_RED];
1444         yuv_secondary.V = 255;
1445         break;
1446       case 3:
1447         yuv_primary = p->colors[COLOR_BLUE];
1448         yuv_secondary = p->colors[COLOR_BLUE];
1449         yuv_secondary.U = 255;
1450         break;
1451     }
1452
1453     for (x = 0; x < w; x += 8) {
1454       int len = MIN (8, w - x);
1455
1456       if ((x ^ y) & (1 << 4)) {
1457         p->color = &yuv_primary;
1458       } else {
1459         p->color = &yuv_secondary;
1460       }
1461       p->paint_tmpline (p, x, len);
1462     }
1463     videotestsrc_convert_tmpline (p, y);
1464   }
1465 }
1466
1467 void
1468 gst_video_test_src_ball (GstVideoTestSrc * v, GstVideoFrame * frame)
1469 {
1470   int i;
1471   paintinfo pi = { NULL, };
1472   paintinfo *p = &pi;
1473   struct format_list_struct *format;
1474   int t = v->n_frames;
1475   double x, y;
1476   int radius = 20;
1477   int w = frame->info.width, h = frame->info.height;
1478
1479   videotestsrc_setup_paintinfo (v, p, w, h);
1480   format = v->format;
1481   if (format == NULL)
1482     return;
1483
1484   format->paint_setup (p, frame);
1485
1486   x = radius + (0.5 + 0.5 * sin (2 * G_PI * t / 200)) * (w - 2 * radius);
1487   y = radius + (0.5 + 0.5 * sin (2 * G_PI * sqrt (2) * t / 200)) * (h -
1488       2 * radius);
1489
1490   for (i = 0; i < h; i++) {
1491     if (i < y - radius || i > y + radius) {
1492       memset (p->tmpline_u8, 0, w);
1493     } else {
1494       int r = rint (sqrt (radius * radius - (i - y) * (i - y)));
1495       int x1, x2;
1496       int j;
1497
1498       x1 = 0;
1499       x2 = MAX (0, x - r);
1500       for (j = x1; j < x2; j++) {
1501         p->tmpline_u8[j] = 0;
1502       }
1503
1504       x1 = MAX (0, x - r);
1505       x2 = MIN (w, x + r + 1);
1506       for (j = x1; j < x2; j++) {
1507         double rr = radius - sqrt ((j - x) * (j - x) + (i - y) * (i - y));
1508
1509         rr *= 0.5;
1510         p->tmpline_u8[j] = CLAMP ((int) floor (256 * rr), 0, 255);
1511       }
1512
1513       x1 = MIN (w, x + r + 1);
1514       x2 = w;
1515       for (j = x1; j < x2; j++) {
1516         p->tmpline_u8[j] = 0;
1517       }
1518     }
1519     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1520         &p->foreground_color, &p->background_color, p->width);
1521     videotestsrc_convert_tmpline (p, i);
1522   }
1523 }
1524
1525 static void
1526 paint_tmpline_ARGB (paintinfo * p, int x, int w)
1527 {
1528   int offset;
1529   guint32 value;
1530
1531 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1532   value = (p->color->A << 0) | (p->color->R << 8) |
1533       (p->color->G << 16) | (p->color->B << 24);
1534 #else
1535   value = (p->color->A << 24) | (p->color->R << 16) |
1536       (p->color->G << 8) | (p->color->B << 0);
1537 #endif
1538
1539   offset = (x * 4);
1540   gst_orc_splat_u32 (p->tmpline + offset, value, w);
1541 }
1542
1543 static void
1544 paint_tmpline_AYUV (paintinfo * p, int x, int w)
1545 {
1546   int offset;
1547   guint32 value;
1548
1549 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1550   value = (p->color->A << 0) | (p->color->Y << 8) |
1551       (p->color->U << 16) | (p->color->V << 24);
1552 #else
1553   value = (p->color->A << 24) | (p->color->Y << 16) |
1554       (p->color->U << 8) | (p->color->V << 0);
1555 #endif
1556
1557   offset = (x * 4);
1558   gst_orc_splat_u32 (p->tmpline + offset, value, w);
1559 }
1560
1561
1562 static void
1563 paint_setup_I420 (paintinfo * p, GstVideoFrame * frame)
1564 {
1565   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
1566   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1567   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
1568   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
1569   p->vp = GST_VIDEO_FRAME_DATA (frame, 2);
1570   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 2);
1571   p->size = frame->info.size;
1572 }
1573
1574 static void
1575 paint_setup_NV12 (paintinfo * p, GstVideoFrame * frame)
1576 {
1577   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
1578   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1579   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
1580   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
1581   p->vp = p->up + 1;
1582   p->vstride = p->ustride;
1583   p->size = frame->info.size;
1584 }
1585
1586 static void
1587 paint_setup_NV21 (paintinfo * p, GstVideoFrame * frame)
1588 {
1589   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
1590   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1591   p->vp = GST_VIDEO_FRAME_DATA (frame, 1);
1592   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 1);
1593   p->up = p->vp + 1;
1594   p->ustride = p->vstride;
1595   p->size = frame->info.size;
1596 }
1597
1598 static void
1599 convert_hline_I420 (paintinfo * p, int y)
1600 {
1601   int i;
1602   guint8 *Y = p->yp + y * p->ystride;
1603   guint8 *U = p->up + (y / 2) * p->ustride;
1604   guint8 *V = p->vp + (y / 2) * p->vstride;
1605   guint8 *ayuv = p->tmpline;
1606
1607   for (i = 0; i < p->width; i++) {
1608     Y[i] = ayuv[4 * i + 1];
1609   }
1610   for (i = 0; i < (p->width + 1) / 2; i++) {
1611     U[i] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
1612     V[i] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
1613   }
1614 }
1615
1616 static void
1617 convert_hline_NV12 (paintinfo * p, int y)
1618 {
1619   int i;
1620   guint8 *Y = p->yp + y * p->ystride;
1621   guint8 *U = p->up + (y / 2) * p->ustride;
1622   guint8 *V = p->vp + (y / 2) * p->vstride;
1623   guint8 *ayuv = p->tmpline;
1624
1625   for (i = 0; i < p->width; i++) {
1626     Y[i] = ayuv[4 * i + 1];
1627   }
1628   for (i = 0; i < (p->width + 1) / 2; i++) {
1629     U[i * 2] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
1630     V[i * 2] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
1631   }
1632 }
1633
1634 static void
1635 convert_hline_NV21 (paintinfo * p, int y)
1636 {
1637   int i;
1638   guint8 *Y = p->yp + y * p->ystride;
1639   guint8 *U = p->up + (y / 2) * p->ustride;
1640   guint8 *V = p->vp + (y / 2) * p->vstride;
1641   guint8 *ayuv = p->tmpline;
1642
1643   for (i = 0; i < p->width; i++) {
1644     Y[i] = ayuv[4 * i + 1];
1645   }
1646   for (i = 0; i < (p->width + 1) / 2; i++) {
1647     U[i * 2] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
1648     V[i * 2] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
1649   }
1650 }
1651
1652
1653 static void
1654 paint_setup_YV12 (paintinfo * p, GstVideoFrame * frame)
1655 {
1656   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
1657   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1658   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
1659   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
1660   p->vp = GST_VIDEO_FRAME_DATA (frame, 2);
1661   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 2);
1662   p->size = frame->info.size;
1663 }
1664
1665 static void
1666 paint_setup_v308 (paintinfo * p, GstVideoFrame * frame)
1667 {
1668   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
1669   p->up = p->yp + 1;
1670   p->vp = p->yp + 2;
1671   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1672   p->ustride = p->ystride;
1673   p->vstride = p->ystride;
1674   p->size = frame->info.size;
1675 }
1676
1677 static void
1678 paint_setup_AYUV (paintinfo * p, GstVideoFrame * frame)
1679 {
1680   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
1681   p->yp = p->ap + 1;
1682   p->up = p->ap + 2;
1683   p->vp = p->ap + 3;
1684   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1685   p->ystride = p->astride;;
1686   p->ustride = p->astride;
1687   p->vstride = p->astride;
1688   p->size = frame->info.size;
1689 }
1690
1691 #ifdef disabled
1692 static void
1693 paint_setup_v410 (paintinfo * p, GstVideoFrame * frame)
1694 {
1695   p->yp = dest + 0;
1696   p->up = dest + 0;
1697   p->vp = dest + 0;
1698   p->ystride = p->width * 4;
1699   p->endptr = dest + p->ystride * p->height;
1700   p->size = frame->info.size;
1701 }
1702 #endif
1703
1704 static void
1705 paint_setup_v216 (paintinfo * p, GstVideoFrame * frame)
1706 {
1707   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
1708   p->yp = p->ap + 2;
1709   p->up = p->ap + 0;
1710   p->vp = p->ap + 4;
1711   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1712   p->ystride = p->astride;;
1713   p->ustride = p->astride;
1714   p->vstride = p->astride;
1715   p->size = frame->info.size;
1716 }
1717
1718 static void
1719 paint_setup_v210 (paintinfo * p, GstVideoFrame * frame)
1720 {
1721   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
1722   p->yp = p->ap;
1723   p->up = p->ap;
1724   p->vp = p->ap;
1725   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1726   p->ystride = p->astride;;
1727   p->ustride = p->astride;
1728   p->vstride = p->astride;
1729   p->size = frame->info.size;
1730 }
1731
1732 static void
1733 paint_setup_UYVP (paintinfo * p, GstVideoFrame * frame)
1734 {
1735   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
1736   p->yp = p->ap;
1737   p->up = p->ap;
1738   p->vp = p->ap;
1739   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1740   p->ystride = p->astride;;
1741   p->ustride = p->astride;
1742   p->vstride = p->astride;
1743   p->size = frame->info.size;
1744 }
1745
1746 static void
1747 paint_setup_YUY2 (paintinfo * p, GstVideoFrame * frame)
1748 {
1749   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
1750   p->up = p->yp + 1;
1751   p->vp = p->yp + 3;
1752   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1753   p->ustride = p->ystride;
1754   p->vstride = p->ystride;
1755   p->size = frame->info.size;
1756 }
1757
1758 static void
1759 paint_setup_UYVY (paintinfo * p, GstVideoFrame * frame)
1760 {
1761   p->up = GST_VIDEO_FRAME_DATA (frame, 0);
1762   p->yp = p->up + 1;
1763   p->vp = p->up + 2;
1764   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1765   p->ustride = p->ystride;
1766   p->vstride = p->ystride;
1767   p->size = frame->info.size;
1768 }
1769
1770 static void
1771 paint_setup_YVYU (paintinfo * p, GstVideoFrame * frame)
1772 {
1773   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
1774   p->up = p->yp + 3;
1775   p->vp = p->yp + 1;
1776   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1777   p->ustride = p->ystride;
1778   p->vstride = p->ystride;
1779   p->size = frame->info.size;
1780 }
1781
1782 static void
1783 paint_setup_AY64 (paintinfo * p, GstVideoFrame * frame)
1784 {
1785   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
1786   p->yp = p->ap + 2;
1787   p->up = p->ap + 4;
1788   p->vp = p->ap + 6;
1789   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1790   p->ystride = p->astride;
1791   p->ustride = p->astride;
1792   p->vstride = p->astride;
1793   p->size = frame->info.size;
1794 }
1795
1796 static void
1797 convert_hline_v308 (paintinfo * p, int y)
1798 {
1799   int i;
1800   guint8 *Y = p->yp + y * p->ystride;
1801   guint8 *U = p->up + y * p->ustride;
1802   guint8 *V = p->vp + y * p->vstride;
1803   guint8 *ayuv = p->tmpline;
1804
1805   for (i = 0; i < p->width; i++) {
1806     Y[i * 3] = ayuv[4 * i + 1];
1807     U[i * 3] = ayuv[4 * i + 2];
1808     V[i * 3] = ayuv[4 * i + 3];
1809   }
1810 }
1811
1812 static void
1813 convert_hline_AYUV (paintinfo * p, int y)
1814 {
1815   int i;
1816   guint8 *Y = p->yp + y * p->ystride;
1817   guint8 *U = p->up + y * p->ustride;
1818   guint8 *V = p->vp + y * p->vstride;
1819   guint8 *A = p->ap + y * p->ystride;
1820   guint8 *ayuv = p->tmpline;
1821
1822   for (i = 0; i < p->width; i++) {
1823     A[i * 4] = ayuv[4 * i + 0];
1824     Y[i * 4] = ayuv[4 * i + 1];
1825     U[i * 4] = ayuv[4 * i + 2];
1826     V[i * 4] = ayuv[4 * i + 3];
1827   }
1828 }
1829
1830 static void
1831 convert_hline_v216 (paintinfo * p, int y)
1832 {
1833   int i;
1834   guint8 *Y = p->yp + y * p->ystride;
1835   guint8 *U = p->up + y * p->ustride;
1836   guint8 *V = p->vp + y * p->vstride;
1837   guint8 *ayuv = p->tmpline;
1838
1839   for (i = 0; i < p->width; i++) {
1840     GST_WRITE_UINT16_LE (Y + i * 4, TO_16 (ayuv[4 * i + 1]));
1841   }
1842   for (i = 0; i < (p->width + 1) / 2; i++) {
1843     GST_WRITE_UINT16_LE (U + i * 8, TO_16 (ayuv[4 * (i * 2) + 2]));
1844     GST_WRITE_UINT16_LE (V + i * 8, TO_16 (ayuv[4 * (i * 2) + 3]));
1845   }
1846 }
1847
1848 #ifdef disabled
1849 static void
1850 convert_hline_v410 (paintinfo * p, int y)
1851 {
1852   int i;
1853   guint8 *Y = p->yp + y * p->ystride;
1854   guint8 *ayuv = p->tmpline;
1855
1856   for (i = 0; i < p->width; i++) {
1857     guint32 a;
1858
1859     a = (TO_10 (ayuv[4 * i + 2]) << 22) |
1860         (TO_10 (ayuv[4 * i + 1]) << 12) | (TO_10 (ayuv[4 * i + 3]) << 2);
1861     GST_WRITE_UINT32_LE (Y + i * 4, a);
1862   }
1863 }
1864 #endif
1865
1866 static void
1867 convert_hline_v210 (paintinfo * p, int y)
1868 {
1869   int i;
1870   guint8 *Y = p->yp + y * p->ystride;
1871   guint8 *ayuv = p->tmpline;
1872
1873   for (i = 0; i < p->width + 5; i += 6) {
1874     guint32 a0, a1, a2, a3;
1875     guint16 y0, y1, y2, y3, y4, y5;
1876     guint16 u0, u1, u2;
1877     guint16 v0, v1, v2;
1878
1879     y0 = ayuv[4 * (i + 0) + 1];
1880     y1 = ayuv[4 * (i + 1) + 1];
1881     y2 = ayuv[4 * (i + 2) + 1];
1882     y3 = ayuv[4 * (i + 3) + 1];
1883     y4 = ayuv[4 * (i + 4) + 1];
1884     y5 = ayuv[4 * (i + 5) + 1];
1885
1886     u0 = (ayuv[4 * (i + 0) + 2] + ayuv[4 * (i + 1) + 2] + 1) >> 1;
1887     u1 = (ayuv[4 * (i + 2) + 2] + ayuv[4 * (i + 3) + 2] + 1) >> 1;
1888     u2 = (ayuv[4 * (i + 4) + 2] + ayuv[4 * (i + 5) + 2] + 1) >> 1;
1889
1890     v0 = (ayuv[4 * (i + 0) + 3] + ayuv[4 * (i + 1) + 3] + 1) >> 1;
1891     v1 = (ayuv[4 * (i + 2) + 3] + ayuv[4 * (i + 3) + 3] + 1) >> 1;
1892     v2 = (ayuv[4 * (i + 4) + 3] + ayuv[4 * (i + 5) + 3] + 1) >> 1;
1893
1894 #if 0
1895     a0 = TO_10 (ayuv[4 * (i + 0) + 2]) | (TO_10 (ayuv[4 * (i + 0) + 1]) << 10)
1896         | (TO_10 (ayuv[4 * (i + 0) + 3]) << 20);
1897     a1 = TO_10 (ayuv[4 * (i + 1) + 1]) | (TO_10 (ayuv[4 * (i + 2) + 2]) << 10)
1898         | (TO_10 (ayuv[4 * (i + 2) + 1]) << 20);
1899     a2 = TO_10 (ayuv[4 * (i + 2) + 3]) | (TO_10 (ayuv[4 * (i + 3) + 1]) << 10)
1900         | (TO_10 (ayuv[4 * (i + 4) + 2]) << 20);
1901     a3 = TO_10 (ayuv[4 * (i + 4) + 1]) | (TO_10 (ayuv[4 * (i + 4) + 3]) << 10)
1902         | (TO_10 (ayuv[4 * (i + 5) + 1]) << 20);
1903 #endif
1904
1905     a0 = TO_10 (u0) | (TO_10 (y0) << 10) | (TO_10 (v0) << 20);
1906     a1 = TO_10 (y1) | (TO_10 (u1) << 10) | (TO_10 (y2) << 20);
1907     a2 = TO_10 (v1) | (TO_10 (y3) << 10) | (TO_10 (u2) << 20);
1908     a3 = TO_10 (y4) | (TO_10 (v2) << 10) | (TO_10 (y5) << 20);
1909
1910     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 0, a0);
1911     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 4, a1);
1912     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 8, a2);
1913     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 12, a3);
1914   }
1915 }
1916
1917 static void
1918 convert_hline_UYVP (paintinfo * p, int y)
1919 {
1920   int i;
1921   guint8 *Y = p->yp + y * p->ystride;
1922   guint8 *ayuv = p->tmpline;
1923
1924   for (i = 0; i < p->width; i += 2) {
1925     guint16 y0, y1;
1926     guint16 u0;
1927     guint16 v0;
1928
1929     y0 = ayuv[4 * (i + 0) + 1];
1930     y1 = ayuv[4 * (i + 1) + 1];
1931     u0 = (ayuv[4 * (i + 0) + 2] + ayuv[4 * (i + 1) + 2] + 1) >> 1;
1932     v0 = (ayuv[4 * (i + 0) + 3] + ayuv[4 * (i + 1) + 3] + 1) >> 1;
1933
1934     Y[(i / 2) * 5 + 0] = u0;
1935     Y[(i / 2) * 5 + 1] = y0 >> 2;
1936     Y[(i / 2) * 5 + 2] = (y0 << 6) | (v0 >> 4);
1937     Y[(i / 2) * 5 + 3] = (v0 << 4) | (y1 >> 2);
1938     Y[(i / 2) * 5 + 4] = (y1 << 2);
1939   }
1940 }
1941
1942 static void
1943 convert_hline_YUY2 (paintinfo * p, int y)
1944 {
1945   int i;
1946   guint8 *Y = p->yp + y * p->ystride;
1947   guint8 *U = p->up + y * p->ustride;
1948   guint8 *V = p->vp + y * p->vstride;
1949   guint8 *ayuv = p->tmpline;
1950
1951   for (i = 0; i < p->width; i++) {
1952     Y[i * 2] = ayuv[4 * i + 1];
1953   }
1954   for (i = 0; i < (p->width + 1) / 2; i++) {
1955     U[4 * i] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
1956     V[4 * i] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
1957   }
1958 }
1959
1960 static void
1961 convert_hline_AY64 (paintinfo * p, int y)
1962 {
1963   int i;
1964   guint16 *ayuv16 = (guint16 *) (p->ap + y * p->ystride);
1965   guint8 *ayuv = p->tmpline;
1966
1967   for (i = 0; i < p->width; i++) {
1968     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 0, TO_16 (ayuv[4 * i + 0]));
1969     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 1, TO_16 (ayuv[4 * i + 1]));
1970     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 2, TO_16 (ayuv[4 * i + 2]));
1971     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 3, TO_16 (ayuv[4 * i + 3]));
1972   }
1973 }
1974
1975 #ifdef disabled
1976 static void
1977 paint_setup_IYU2 (paintinfo * p, GstVideoFrame * frame)
1978 {
1979   /* untested */
1980   p->up = GST_VIDEO_FRAME_DATA (frame, 0);
1981   p->yp = p->up + 1;
1982   p->vp = p->up + 2;
1983   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
1984   p->ustride = p->ystride;
1985   p->vstride = p->ystride;
1986   p->size = frame->info.size;
1987 }
1988
1989 static void
1990 convert_hline_IYU2 (paintinfo * p, int y)
1991 {
1992   int i;
1993   guint8 *Y = p->yp + y * p->ystride;
1994   guint8 *U = p->up + y * p->ustride;
1995   guint8 *V = p->vp + y * p->vstride;
1996   guint8 *ayuv = p->tmpline;
1997
1998   for (i = 0; i < p->width; i++) {
1999     Y[i * 3] = ayuv[4 * i + 1];
2000     U[i * 3] = ayuv[4 * i + 2];
2001     V[i * 3] = ayuv[4 * i + 3];
2002   }
2003 }
2004 #endif
2005
2006 static void
2007 paint_setup_Y41B (paintinfo * p, GstVideoFrame * frame)
2008 {
2009   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2010   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
2011   p->vp = GST_VIDEO_FRAME_DATA (frame, 2);
2012   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2013   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
2014   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 2);
2015   p->size = frame->info.size;
2016 }
2017
2018 static void
2019 convert_hline_Y41B (paintinfo * p, int y)
2020 {
2021   int i;
2022   guint8 *Y = p->yp + y * p->ystride;
2023   guint8 *U = p->up + y * p->ustride;
2024   guint8 *V = p->vp + y * p->vstride;
2025   guint8 *ayuv = p->tmpline;
2026
2027   for (i = 0; i < p->width; i++) {
2028     Y[i] = ayuv[4 * i + 1];
2029   }
2030   for (i = 0; i < (p->width + 3) / 4; i++) {
2031     U[i] = (ayuv[4 * (i * 4) + 2] + ayuv[4 * (i * 4 + 1) + 2] +
2032         ayuv[4 * (i * 4 + 2) + 2] + ayuv[4 * (i * 4 + 3) + 2] + 2) >> 2;
2033     V[i] = (ayuv[4 * (i * 4) + 3] + ayuv[4 * (i * 4 + 1) + 3] +
2034         ayuv[4 * (i * 4 + 2) + 3] + ayuv[4 * (i * 4 + 3) + 3] + 2) >> 2;
2035   }
2036 }
2037
2038 static void
2039 paint_setup_Y42B (paintinfo * p, GstVideoFrame * frame)
2040 {
2041   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2042   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
2043   p->vp = GST_VIDEO_FRAME_DATA (frame, 2);
2044   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2045   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
2046   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 2);
2047   p->size = frame->info.size;
2048 }
2049
2050 static void
2051 convert_hline_Y42B (paintinfo * p, int y)
2052 {
2053   int i;
2054   guint8 *Y = p->yp + y * p->ystride;
2055   guint8 *U = p->up + y * p->ustride;
2056   guint8 *V = p->vp + y * p->vstride;
2057   guint8 *ayuv = p->tmpline;
2058
2059   for (i = 0; i < p->width; i++) {
2060     Y[i] = ayuv[4 * i + 1];
2061   }
2062   for (i = 0; i < (p->width + 1) / 2; i++) {
2063     U[i] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
2064     V[i] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
2065   }
2066 }
2067
2068 static void
2069 paint_setup_Y444 (paintinfo * p, GstVideoFrame * frame)
2070 {
2071   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2072   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
2073   p->vp = GST_VIDEO_FRAME_DATA (frame, 2);
2074   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2075   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
2076   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 2);
2077   p->size = frame->info.size;
2078 }
2079
2080 static void
2081 convert_hline_Y444 (paintinfo * p, int y)
2082 {
2083   int i;
2084   guint8 *Y = p->yp + y * p->ystride;
2085   guint8 *U = p->up + y * p->ustride;
2086   guint8 *V = p->vp + y * p->vstride;
2087   guint8 *ayuv = p->tmpline;
2088
2089   for (i = 0; i < p->width; i++) {
2090     Y[i] = ayuv[4 * i + 1];
2091     U[i] = ayuv[4 * i + 2];
2092     V[i] = ayuv[4 * i + 3];
2093   }
2094 }
2095
2096 static void
2097 paint_setup_Y800 (paintinfo * p, GstVideoFrame * frame)
2098 {
2099   /* untested */
2100   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2101   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2102   p->size = frame->info.size;
2103 }
2104
2105 static void
2106 convert_hline_Y800 (paintinfo * p, int y)
2107 {
2108   int i;
2109   guint8 *Y = p->yp + y * p->ystride;
2110   guint8 *ayuv = p->tmpline;
2111
2112   for (i = 0; i < p->width; i++) {
2113     Y[i] = ayuv[4 * i + 1];
2114   }
2115 }
2116
2117 static void
2118 paint_setup_YVU9 (paintinfo * p, GstVideoFrame * frame)
2119 {
2120   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2121   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
2122   p->vp = GST_VIDEO_FRAME_DATA (frame, 2);
2123   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2124   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
2125   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 2);
2126   p->size = frame->info.size;
2127 }
2128
2129 static void
2130 paint_setup_YUV9 (paintinfo * p, GstVideoFrame * frame)
2131 {
2132   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2133   p->up = GST_VIDEO_FRAME_DATA (frame, 1);
2134   p->vp = GST_VIDEO_FRAME_DATA (frame, 2);
2135   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2136   p->ustride = GST_VIDEO_FRAME_STRIDE (frame, 1);
2137   p->vstride = GST_VIDEO_FRAME_STRIDE (frame, 2);
2138   p->size = frame->info.size;
2139 }
2140
2141 static void
2142 convert_hline_YUV9 (paintinfo * p, int y)
2143 {
2144   int i;
2145   guint8 *Y = p->yp + y * p->ystride;
2146   guint8 *U = p->up + (y / 4) * p->ustride;
2147   guint8 *V = p->vp + (y / 4) * p->vstride;
2148   guint8 *ayuv = p->tmpline;
2149
2150   for (i = 0; i < p->width; i++) {
2151     Y[i] = ayuv[4 * i + 1];
2152   }
2153   for (i = 0; i < (p->width + 3) / 4; i++) {
2154     U[i] = (ayuv[4 * (i * 4) + 2] + ayuv[4 * (i * 4 + 1) + 2] +
2155         ayuv[4 * (i * 4 + 2) + 2] + ayuv[4 * (i * 4 + 3) + 2] + 2) >> 2;
2156     V[i] = (ayuv[4 * (i * 4) + 3] + ayuv[4 * (i * 4 + 1) + 3] +
2157         ayuv[4 * (i * 4 + 2) + 3] + ayuv[4 * (i * 4 + 3) + 3] + 2) >> 2;
2158   }
2159 }
2160
2161 static void
2162 paint_setup_ARGB8888 (paintinfo * p, GstVideoFrame * frame)
2163 {
2164   paint_setup_xRGB8888 (p, frame);
2165 }
2166
2167 static void
2168 paint_setup_ABGR8888 (paintinfo * p, GstVideoFrame * frame)
2169 {
2170   paint_setup_xBGR8888 (p, frame);
2171 }
2172
2173 static void
2174 paint_setup_RGBA8888 (paintinfo * p, GstVideoFrame * frame)
2175 {
2176   paint_setup_RGBx8888 (p, frame);
2177 }
2178
2179 static void
2180 paint_setup_BGRA8888 (paintinfo * p, GstVideoFrame * frame)
2181 {
2182   paint_setup_BGRx8888 (p, frame);
2183 }
2184
2185 static void
2186 paint_setup_xRGB8888 (paintinfo * p, GstVideoFrame * frame)
2187 {
2188   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
2189   p->yp = p->ap + 1;
2190   p->up = p->ap + 2;
2191   p->vp = p->ap + 3;
2192   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2193   p->ystride = p->astride;
2194   p->ustride = p->astride;
2195   p->vstride = p->astride;
2196   p->size = frame->info.size;
2197 }
2198
2199 static void
2200 paint_setup_xBGR8888 (paintinfo * p, GstVideoFrame * frame)
2201 {
2202   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
2203   p->yp = p->ap + 3;
2204   p->up = p->ap + 2;
2205   p->vp = p->ap + 1;
2206   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2207   p->ystride = p->astride;
2208   p->ustride = p->astride;
2209   p->vstride = p->astride;
2210   p->size = frame->info.size;
2211 }
2212
2213 static void
2214 paint_setup_RGBx8888 (paintinfo * p, GstVideoFrame * frame)
2215 {
2216   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2217   p->up = p->yp + 1;
2218   p->vp = p->yp + 2;
2219   p->ap = p->yp + 3;
2220   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2221   p->ystride = p->astride;
2222   p->ustride = p->astride;
2223   p->vstride = p->astride;
2224   p->size = frame->info.size;
2225 }
2226
2227 static void
2228 paint_setup_BGRx8888 (paintinfo * p, GstVideoFrame * frame)
2229 {
2230   p->vp = GST_VIDEO_FRAME_DATA (frame, 0);
2231   p->up = p->vp + 1;
2232   p->yp = p->vp + 2;
2233   p->ap = p->vp + 3;
2234   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2235   p->ystride = p->astride;
2236   p->ustride = p->astride;
2237   p->vstride = p->astride;
2238   p->size = frame->info.size;
2239 }
2240
2241 static void
2242 paint_setup_RGB888 (paintinfo * p, GstVideoFrame * frame)
2243 {
2244   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2245   p->up = p->yp + 1;
2246   p->vp = p->yp + 2;
2247   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2248   p->ustride = p->ystride;
2249   p->vstride = p->ystride;
2250   p->size = frame->info.size;
2251 }
2252
2253 static void
2254 paint_setup_BGR888 (paintinfo * p, GstVideoFrame * frame)
2255 {
2256   p->vp = GST_VIDEO_FRAME_DATA (frame, 0);
2257   p->up = p->vp + 1;
2258   p->yp = p->vp + 2;
2259   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2260   p->ustride = p->ystride;
2261   p->vstride = p->ystride;
2262   p->size = frame->info.size;
2263 }
2264
2265 static void
2266 paint_setup_ARGB64 (paintinfo * p, GstVideoFrame * frame)
2267 {
2268   p->ap = GST_VIDEO_FRAME_DATA (frame, 0);
2269   p->yp = p->ap + 2;
2270   p->up = p->ap + 4;
2271   p->yp = p->ap + 6;
2272   p->astride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2273   p->ystride = p->astride;
2274   p->ustride = p->astride;
2275   p->vstride = p->astride;
2276   p->size = frame->info.size;
2277 }
2278
2279 static void
2280 convert_hline_str4 (paintinfo * p, int y)
2281 {
2282   int i;
2283   guint8 *A = p->ap + y * p->ystride;
2284   guint8 *R = p->yp + y * p->ystride;
2285   guint8 *G = p->up + y * p->ustride;
2286   guint8 *B = p->vp + y * p->vstride;
2287   guint8 *argb = p->tmpline;
2288
2289   for (i = 0; i < p->width; i++) {
2290     A[4 * i] = 0xff;
2291     R[4 * i] = argb[4 * i + 1];
2292     G[4 * i] = argb[4 * i + 2];
2293     B[4 * i] = argb[4 * i + 3];
2294   }
2295 }
2296
2297 static void
2298 convert_hline_astr4 (paintinfo * p, int y)
2299 {
2300   int i;
2301   guint8 *A = p->ap + y * p->ystride;
2302   guint8 *R = p->yp + y * p->ystride;
2303   guint8 *G = p->up + y * p->ustride;
2304   guint8 *B = p->vp + y * p->vstride;
2305   guint8 *argb = p->tmpline;
2306
2307   for (i = 0; i < p->width; i++) {
2308     A[4 * i] = argb[4 * i + 0];
2309     R[4 * i] = argb[4 * i + 1];
2310     G[4 * i] = argb[4 * i + 2];
2311     B[4 * i] = argb[4 * i + 3];
2312   }
2313 }
2314
2315 static void
2316 convert_hline_astr8 (paintinfo * p, int y)
2317 {
2318   int i;
2319   guint16 *A = (guint16 *) (p->ap + y * p->ystride);
2320   guint16 *R = (guint16 *) (p->yp + y * p->ystride);
2321   guint16 *G = (guint16 *) (p->up + y * p->ustride);
2322   guint16 *B = (guint16 *) (p->vp + y * p->vstride);
2323   guint8 *argb = p->tmpline;
2324
2325   for (i = 0; i < p->width; i++) {
2326     A[4 * i] = TO_16 (argb[4 * i + 0]);
2327     R[4 * i] = TO_16 (argb[4 * i + 1]);
2328     G[4 * i] = TO_16 (argb[4 * i + 2]);
2329     B[4 * i] = TO_16 (argb[4 * i + 3]);
2330   }
2331 }
2332
2333 static void
2334 convert_hline_str3 (paintinfo * p, int y)
2335 {
2336   int i;
2337   guint8 *R = p->yp + y * p->ystride;
2338   guint8 *G = p->up + y * p->ustride;
2339   guint8 *B = p->vp + y * p->vstride;
2340   guint8 *argb = p->tmpline;
2341
2342   for (i = 0; i < p->width; i++) {
2343     R[3 * i] = argb[4 * i + 1];
2344     G[3 * i] = argb[4 * i + 2];
2345     B[3 * i] = argb[4 * i + 3];
2346   }
2347 }
2348
2349 static void
2350 paint_setup_RGB565 (paintinfo * p, GstVideoFrame * frame)
2351 {
2352   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2353   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2354   p->ustride = p->ystride;
2355   p->vstride = p->ystride;
2356   p->size = frame->info.size;
2357 }
2358
2359 static void
2360 convert_hline_RGB565 (paintinfo * p, int y)
2361 {
2362   int i;
2363   guint8 *R = p->yp + y * p->ystride;
2364   guint8 *argb = p->tmpline;
2365
2366   for (i = 0; i < p->width; i++) {
2367     guint16 value = ((argb[4 * i + 1] & 0xf8) << 8) |
2368         ((argb[4 * i + 2] & 0xfc) << 3) | ((argb[4 * i + 3] & 0xf8) >> 3);
2369 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2370     GST_WRITE_UINT16_LE (R + 2 * i, value);
2371 #else
2372     GST_WRITE_UINT16_BE (R + 2 * i, value);
2373 #endif
2374   }
2375 }
2376
2377 static void
2378 convert_hline_xRGB1555 (paintinfo * p, int y)
2379 {
2380   int i;
2381   guint8 *R = p->yp + y * p->ystride;
2382   guint8 *argb = p->tmpline;
2383
2384   for (i = 0; i < p->width; i++) {
2385     guint16 value = ((argb[4 * i + 1] & 0xf8) << 7) |
2386         ((argb[4 * i + 2] & 0xf8) << 2) | ((argb[4 * i + 3] & 0xf8) >> 3);
2387 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2388     GST_WRITE_UINT16_LE (R + 2 * i, value);
2389 #else
2390     GST_WRITE_UINT16_BE (R + 2 * i, value);
2391 #endif
2392   }
2393 }
2394
2395 static void
2396 paint_setup_xRGB1555 (paintinfo * p, GstVideoFrame * frame)
2397 {
2398   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2399   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2400   p->ustride = p->ystride;
2401   p->vstride = p->ystride;
2402   p->size = frame->info.size;
2403 }
2404
2405
2406 static void
2407 paint_setup_bayer_bggr (paintinfo * p, GstVideoFrame * frame)
2408 {
2409   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2410   p->ystride = GST_ROUND_UP_4 (p->width);
2411   p->ustride = GST_ROUND_UP_4 (p->width);
2412   p->vstride = GST_ROUND_UP_4 (p->width);
2413   p->size = p->ystride * p->height;
2414   p->bayer_x_invert = 0;
2415   p->bayer_y_invert = 0;
2416 }
2417
2418 static void
2419 paint_setup_bayer_rggb (paintinfo * p, GstVideoFrame * frame)
2420 {
2421   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2422   p->ystride = GST_ROUND_UP_4 (p->width);
2423   p->ustride = GST_ROUND_UP_4 (p->width);
2424   p->vstride = GST_ROUND_UP_4 (p->width);
2425   p->size = p->ystride * p->height;
2426   p->bayer_x_invert = 1;
2427   p->bayer_y_invert = 1;
2428 }
2429
2430 static void
2431 paint_setup_bayer_grbg (paintinfo * p, GstVideoFrame * frame)
2432 {
2433   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2434   p->ystride = GST_ROUND_UP_4 (p->width);
2435   p->ustride = GST_ROUND_UP_4 (p->width);
2436   p->vstride = GST_ROUND_UP_4 (p->width);
2437   p->size = p->ystride * p->height;
2438   p->bayer_x_invert = 0;
2439   p->bayer_y_invert = 1;
2440 }
2441
2442 static void
2443 paint_setup_bayer_gbrg (paintinfo * p, GstVideoFrame * frame)
2444 {
2445   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2446   p->ystride = GST_ROUND_UP_4 (p->width);
2447   p->ustride = GST_ROUND_UP_4 (p->width);
2448   p->vstride = GST_ROUND_UP_4 (p->width);
2449   p->size = p->ystride * p->height;
2450   p->bayer_x_invert = 1;
2451   p->bayer_y_invert = 0;
2452 }
2453
2454 static void
2455 convert_hline_bayer (paintinfo * p, int y)
2456 {
2457   int i;
2458   guint8 *R = p->yp + y * p->ystride;
2459   guint8 *argb = p->tmpline;
2460   int x_inv = p->bayer_x_invert;
2461   int y_inv = p->bayer_y_invert;
2462
2463   if ((y ^ y_inv) & 1) {
2464     for (i = 0; i < p->width; i++) {
2465       if ((i ^ x_inv) & 1) {
2466         R[i] = argb[4 * i + 1];
2467       } else {
2468         R[i] = argb[4 * i + 2];
2469       }
2470     }
2471   } else {
2472     for (i = 0; i < p->width; i++) {
2473       if ((i ^ x_inv) & 1) {
2474         R[i] = argb[4 * i + 2];
2475       } else {
2476         R[i] = argb[4 * i + 3];
2477       }
2478     }
2479   }
2480 }
2481
2482 static void
2483 paint_setup_GRAY8 (paintinfo * p, GstVideoFrame * frame)
2484 {
2485   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2486   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2487   p->size = frame->info.size;
2488 }
2489
2490 static void
2491 convert_hline_GRAY8 (paintinfo * p, int y)
2492 {
2493   int i;
2494   guint8 *Y = p->yp + y * p->ystride;
2495   guint8 *ayuv = p->tmpline;
2496
2497   /* FIXME this should use gray, not YUV */
2498   for (i = 0; i < p->width; i++) {
2499     Y[i] = ayuv[4 * i + 1];
2500   }
2501 }
2502
2503 static void
2504 paint_setup_GRAY16 (paintinfo * p, GstVideoFrame * frame)
2505 {
2506   p->yp = GST_VIDEO_FRAME_DATA (frame, 0);
2507   p->ystride = GST_VIDEO_FRAME_STRIDE (frame, 0);
2508   p->size = frame->info.size;
2509 }
2510
2511 static void
2512 convert_hline_GRAY16 (paintinfo * p, int y)
2513 {
2514   int i;
2515   guint8 *Y = p->yp + y * p->ystride;
2516   guint8 *ayuv = p->tmpline;
2517
2518   /* FIXME this should use gray, not YUV */
2519   for (i = 0; i < p->width; i++) {
2520 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2521     GST_WRITE_UINT16_LE (Y + i * 2, ayuv[4 * i + 1] << 8);
2522 #else
2523     GST_WRITE_UINT16_BE (Y + i * 2, ayuv[4 * i + 1] << 8);
2524 #endif
2525   }
2526 }