video: add pack_lines variable
[platform/upstream/gstreamer.git] / gst-libs / gst / video / video-format.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Library       <2002> Ronald Bultje <rbultje@ronald.bitfreak.net>
4  * Copyright (C) 2007 David A. Schleef <ds@schleef.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28
29 #include "video-format.h"
30
31 /**
32  * SECTION:gstvideo
33  * @short_description: Support library for video operations
34  *
35  * <refsect2>
36  * <para>
37  * This library contains some helper functions and includes the
38  * videosink and videofilter base classes.
39  * </para>
40  * </refsect2>
41  */
42
43 #include "videoblendorc.h"
44
45 /* Line conversion to AYUV */
46
47 #define GET_PLANE_STRIDE(plane) (stride(plane))
48 #define GET_PLANE_LINE(plane, line) \
49   (gpointer)(((guint8*)(data[plane])) + stride[plane] * (line))
50
51 #define GET_COMP_STRIDE(comp) \
52   GST_VIDEO_FORMAT_INFO_STRIDE (info, stride, comp)
53 #define GET_COMP_DATA(comp) \
54   GST_VIDEO_FORMAT_INFO_DATA (info, data, comp)
55
56 #define GET_COMP_LINE(comp, line) \
57   (gpointer)(((guint8*)GET_COMP_DATA (comp)) + \
58       GET_COMP_STRIDE(comp) * (line))
59
60 #define GET_STRIDE()                 GET_PLANE_STRIDE (0)
61 #define GET_LINE(line)               GET_PLANE_LINE (0, line)
62
63 #define GET_Y_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_Y, line)
64 #define GET_U_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_U, line)
65 #define GET_V_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_V, line)
66 #define GET_A_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_A, line)
67
68 #define GET_Y_STRIDE()               GET_COMP_STRIDE(GST_VIDEO_COMP_Y)
69 #define GET_U_STRIDE()               GET_COMP_STRIDE(GST_VIDEO_COMP_U)
70 #define GET_V_STRIDE()               GET_COMP_STRIDE(GST_VIDEO_COMP_V)
71 #define GET_A_STRIDE()               GET_COMP_STRIDE(GST_VIDEO_COMP_A)
72
73 #define PACK_420 GST_VIDEO_FORMAT_AYUV, unpack_planar_420, 1, pack_planar_420
74 static void
75 unpack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
76     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
77     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
78 {
79   orc_unpack_I420 (dest,
80       GET_Y_LINE (y), GET_U_LINE (y >> 1), GET_V_LINE (y >> 1), width);
81 }
82
83 static void
84 pack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
85     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
86     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
87     gint y, gint width)
88 {
89   orc_pack_I420 (GET_Y_LINE (y),
90       GET_U_LINE (y >> 1), GET_V_LINE (y >> 1), src, width / 2);
91 }
92
93 #define PACK_YUY2 GST_VIDEO_FORMAT_AYUV, unpack_YUY2, 1, pack_YUY2
94 static void
95 unpack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
96     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
97     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
98 {
99   orc_unpack_YUY2 (dest, GET_LINE (y), width / 2);
100 }
101
102 static void
103 pack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
104     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
105     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
106     gint y, gint width)
107 {
108   orc_pack_YUY2 (GET_LINE (y), src, width / 2);
109 }
110
111 #define PACK_UYVY GST_VIDEO_FORMAT_AYUV, unpack_UYVY, 1, pack_UYVY
112 static void
113 unpack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
114     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
115     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
116 {
117   orc_unpack_UYVY (dest, GET_LINE (y), width / 2);
118 }
119
120 static void
121 pack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
122     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
123     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
124     gint y, gint width)
125 {
126   orc_pack_UYVY (GET_LINE (y), src, width / 2);
127 }
128
129 #define PACK_YVYU GST_VIDEO_FORMAT_AYUV, unpack_YVYU, 1, pack_YVYU
130 static void
131 unpack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
132     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
133     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
134 {
135   orc_unpack_YVYU (dest, GET_LINE (y), width / 2);
136 }
137
138 static void
139 pack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
140     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
141     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
142     gint y, gint width)
143 {
144   orc_pack_YVYU (GET_LINE (y), src, width / 2);
145 }
146
147 #define PACK_v308 GST_VIDEO_FORMAT_AYUV, unpack_v308, 1, pack_v308
148 static void
149 unpack_v308 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
150     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
151     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
152 {
153   int i;
154   const guint8 *s = GET_LINE (y);
155   guint8 *d = dest;
156
157   for (i = 0; i < width; i++) {
158     d[i * 4 + 0] = 0xff;
159     d[i * 4 + 1] = s[i * 3 + 0];
160     d[i * 4 + 2] = s[i * 3 + 1];
161     d[i * 4 + 3] = s[i * 3 + 2];
162   }
163 }
164
165 static void
166 pack_v308 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
167     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
168     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
169     gint y, gint width)
170 {
171   int i;
172   guint8 *d = GET_LINE (y);
173   const guint8 *s = src;
174
175   for (i = 0; i < width; i++) {
176     d[i * 3 + 0] = s[i * 4 + 1];
177     d[i * 3 + 1] = s[i * 4 + 2];
178     d[i * 3 + 2] = s[i * 4 + 3];
179   }
180 }
181
182 #define PACK_AYUV GST_VIDEO_FORMAT_AYUV, unpack_copy4, 1, pack_copy4
183 #define PACK_ARGB GST_VIDEO_FORMAT_ARGB, unpack_copy4, 1, pack_copy4
184 static void
185 unpack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
186     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
187     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
188 {
189   memcpy (dest, GET_LINE (y), width * 4);
190 }
191
192 static void
193 pack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
194     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
195     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
196     gint y, gint width)
197 {
198   memcpy (GET_LINE (y), src, width * 4);
199 }
200
201 #define PACK_v210 GST_VIDEO_FORMAT_AYUV64, unpack_v210, 1, pack_v210
202 static void
203 unpack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
204     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
205     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
206 {
207   int i;
208   const guint8 *s = GET_LINE (y);
209   guint16 *d = dest;
210
211   for (i = 0; i < width; i += 6) {
212     guint32 a0, a1, a2, a3;
213     guint16 y0, y1, y2, y3, y4, y5;
214     guint16 u0, u2, u4;
215     guint16 v0, v2, v4;
216
217     a0 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 0);
218     a1 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 4);
219     a2 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 8);
220     a3 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 12);
221
222     u0 = ((a0 >> 0) & 0x3ff) << 6;
223     y0 = ((a0 >> 10) & 0x3ff) << 6;
224     v0 = ((a0 >> 20) & 0x3ff) << 6;
225     y1 = ((a1 >> 0) & 0x3ff) << 6;
226
227     u2 = ((a1 >> 10) & 0x3ff) << 6;
228     y2 = ((a1 >> 20) & 0x3ff) << 6;
229     v2 = ((a2 >> 0) & 0x3ff) << 6;
230     y3 = ((a2 >> 10) & 0x3ff) << 6;
231
232     u4 = ((a2 >> 20) & 0x3ff) << 6;
233     y4 = ((a3 >> 0) & 0x3ff) << 6;
234     v4 = ((a3 >> 10) & 0x3ff) << 6;
235     y5 = ((a3 >> 20) & 0x3ff) << 6;
236
237     d[4 * (i + 0) + 0] = 0xffff;
238     d[4 * (i + 0) + 1] = y0;
239     d[4 * (i + 0) + 2] = u0;
240     d[4 * (i + 0) + 3] = v0;
241
242     d[4 * (i + 1) + 0] = 0xffff;
243     d[4 * (i + 1) + 1] = y1;
244     d[4 * (i + 1) + 2] = u0;
245     d[4 * (i + 1) + 3] = v0;
246
247     d[4 * (i + 2) + 0] = 0xffff;
248     d[4 * (i + 2) + 1] = y2;
249     d[4 * (i + 2) + 2] = u2;
250     d[4 * (i + 2) + 3] = v2;
251
252     d[4 * (i + 3) + 0] = 0xffff;
253     d[4 * (i + 3) + 1] = y3;
254     d[4 * (i + 3) + 2] = u2;
255     d[4 * (i + 3) + 3] = v2;
256
257     d[4 * (i + 4) + 0] = 0xffff;
258     d[4 * (i + 4) + 1] = y4;
259     d[4 * (i + 4) + 2] = u4;
260     d[4 * (i + 4) + 3] = v4;
261
262     d[4 * (i + 5) + 0] = 0xffff;
263     d[4 * (i + 5) + 1] = y5;
264     d[4 * (i + 5) + 2] = u4;
265     d[4 * (i + 5) + 3] = v4;
266   }
267 }
268
269 static void
270 pack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
271     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
272     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
273     gint y, gint width)
274 {
275   int i;
276   guint8 *d = GET_LINE (y);
277   const guint16 *s = src;
278
279   for (i = 0; i < width; i += 6) {
280     guint32 a0, a1, a2, a3;
281     guint16 y0, y1, y2, y3, y4, y5;
282     guint16 u0, u1, u2;
283     guint16 v0, v1, v2;
284
285     y0 = s[4 * (i + 0) + 1] >> 6;
286     y1 = s[4 * (i + 1) + 1] >> 6;
287     y2 = s[4 * (i + 2) + 1] >> 6;
288     y3 = s[4 * (i + 3) + 1] >> 6;
289     y4 = s[4 * (i + 4) + 1] >> 6;
290     y5 = s[4 * (i + 5) + 1] >> 6;
291
292     u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 7;
293     u1 = (s[4 * (i + 2) + 2] + s[4 * (i + 3) + 2] + 1) >> 7;
294     u2 = (s[4 * (i + 4) + 2] + s[4 * (i + 5) + 2] + 1) >> 7;
295
296     v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 7;
297     v1 = (s[4 * (i + 2) + 3] + s[4 * (i + 3) + 3] + 1) >> 7;
298     v2 = (s[4 * (i + 4) + 3] + s[4 * (i + 5) + 3] + 1) >> 7;
299
300     a0 = u0 | (y0 << 10) | (v0 << 20);
301     a1 = y1 | (u1 << 10) | (y2 << 20);
302     a2 = v1 | (y3 << 10) | (u2 << 20);
303     a3 = y4 | (v2 << 10) | (y5 << 20);
304
305     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 0, a0);
306     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 4, a1);
307     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 8, a2);
308     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 12, a3);
309   }
310 }
311
312 #define PACK_v216 GST_VIDEO_FORMAT_AYUV64, unpack_v216, 1, pack_v216
313 static void
314 unpack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
315     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
316     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
317 {
318   int i;
319   const guint8 *s = GET_LINE (y);
320   guint16 *d = dest;
321
322   for (i = 0; i < width; i++) {
323     d[i * 4 + 0] = 0xffff;
324     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i * 4 + 2);
325     d[i * 4 + 2] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 0);
326     d[i * 4 + 3] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 4);
327   }
328 }
329
330 static void
331 pack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
332     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
333     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
334     gint y, gint width)
335 {
336   int i;
337   guint8 *d = GET_LINE (y);
338   const guint16 *s = src;
339
340   for (i = 0; i < width / 2; i++) {
341     GST_WRITE_UINT16_LE (d + i * 8 + 0, s[(i * 2 + 0) * 4 + 2]);
342     GST_WRITE_UINT16_LE (d + i * 8 + 2, s[(i * 2 + 0) * 4 + 1]);
343     GST_WRITE_UINT16_LE (d + i * 8 + 4, s[(i * 2 + 0) * 4 + 3]);
344     GST_WRITE_UINT16_LE (d + i * 8 + 6, s[(i * 2 + 1) * 4 + 1]);
345   }
346 }
347
348 #define PACK_Y41B GST_VIDEO_FORMAT_AYUV, unpack_Y41B, 1, pack_Y41B
349 static void
350 unpack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
351     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
352     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
353 {
354   orc_unpack_YUV9 (dest,
355       GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), width / 2);
356 }
357
358 static void
359 pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
360     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
361     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
362     gint y, gint width)
363 {
364   int i;
365   guint8 *destY = GET_Y_LINE (y);
366   guint8 *destU = GET_U_LINE (y);
367   guint8 *destV = GET_V_LINE (y);
368   const guint8 *s = src;
369
370   for (i = 0; i < width - 3; i += 4) {
371     destY[i] = s[i * 4 + 1];
372     destY[i + 1] = s[i * 4 + 5];
373     destY[i + 2] = s[i * 4 + 9];
374     destY[i + 3] = s[i * 4 + 13];
375
376     destU[i >> 2] =
377         (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14] + 2) >> 2;
378     destV[i >> 2] =
379         (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15] + 2) >> 2;
380   }
381
382   if (i == width - 3) {
383     destY[i] = s[i * 4 + 1];
384     destY[i + 1] = s[i * 4 + 5];
385     destY[i + 2] = s[i * 4 + 9];
386
387     destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + 1) / 3;
388     destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + 1) / 3;
389   } else if (i == width - 2) {
390     destY[i] = s[i * 4 + 1];
391     destY[i + 1] = s[i * 4 + 5];
392
393     destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1;
394     destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1;
395   } else if (i == width - 1) {
396     destY[i + 1] = s[i * 4 + 5];
397
398     destU[i >> 2] = s[i * 4 + 2];
399     destV[i >> 2] = s[i * 4 + 3];
400   }
401 }
402
403 #define PACK_Y42B GST_VIDEO_FORMAT_AYUV, unpack_Y42B, 1, pack_Y42B
404 static void
405 unpack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
406     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
407     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
408 {
409   orc_unpack_Y42B (dest,
410       GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), width / 2);
411 }
412
413 static void
414 pack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
415     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
416     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
417     gint y, gint width)
418 {
419   orc_pack_Y42B (GET_Y_LINE (y),
420       GET_U_LINE (y), GET_V_LINE (y), src, width / 2);
421 }
422
423 #define PACK_Y444 GST_VIDEO_FORMAT_AYUV, unpack_Y444, 1, pack_Y444
424 static void
425 unpack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
426     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
427     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
428 {
429   orc_unpack_Y444 (dest, GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), width);
430 }
431
432 static void
433 pack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
434     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
435     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
436     gint y, gint width)
437 {
438   orc_pack_Y444 (GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), src, width);
439 }
440
441 #define PACK_GRAY8 GST_VIDEO_FORMAT_AYUV, unpack_GRAY8, 1, pack_GRAY8
442 static void
443 unpack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
444     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
445     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
446 {
447   orc_unpack_GRAY8 (dest, GET_LINE (y), width);
448 }
449
450 static void
451 pack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
452     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
453     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
454     gint y, gint width)
455 {
456   orc_pack_GRAY8 (GET_LINE (y), src, width);
457 }
458
459 #define PACK_GRAY16_BE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_BE, 1, pack_GRAY16_BE
460 static void
461 unpack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
462     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
463     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
464 {
465   int i;
466   const guint16 *s = GET_LINE (y);
467   guint16 *d = dest;
468
469   for (i = 0; i < width; i++) {
470     d[i * 4 + 0] = 0xffff;
471     d[i * 4 + 1] = GST_READ_UINT16_BE (s + i);
472     d[i * 4 + 2] = 0x8000;
473     d[i * 4 + 3] = 0x8000;
474   }
475 }
476
477 static void
478 pack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
479     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
480     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
481     gint y, gint width)
482 {
483   int i;
484   guint16 *d = GET_LINE (y);
485   const guint16 *s = src;
486
487   for (i = 0; i < width; i++) {
488     GST_WRITE_UINT16_BE (d + i, s[i * 4 + 1]);
489   }
490 }
491
492 #define PACK_GRAY16_LE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_LE, 1, pack_GRAY16_LE
493 static void
494 unpack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
495     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
496     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
497 {
498   int i;
499   const guint16 *s = GET_LINE (y);
500   guint16 *d = dest;
501
502   for (i = 0; i < width; i++) {
503     d[i * 4 + 0] = 0xffff;
504     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i);
505     d[i * 4 + 2] = 0x8000;
506     d[i * 4 + 3] = 0x8000;
507   }
508 }
509
510 static void
511 pack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
512     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
513     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
514     gint y, gint width)
515 {
516   int i;
517   guint16 *d = GET_LINE (y);
518   const guint16 *s = src;
519
520   for (i = 0; i < width; i++) {
521     GST_WRITE_UINT16_LE (d + i, s[i * 4 + 1]);
522   }
523 }
524
525 #define PACK_RGB16 GST_VIDEO_FORMAT_ARGB, unpack_RGB16, 1, pack_RGB16
526 static void
527 unpack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
528     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
529     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
530 {
531   int i;
532   const guint16 *s = GET_LINE (y);
533   guint8 *d = dest;
534
535   for (i = 0; i < width; i++) {
536     d[i * 4 + 0] = 0xff;
537     d[i * 4 + 1] = ((s[i] >> 11) & 0x1f) << 3;
538     d[i * 4 + 2] = ((s[i] >> 5) & 0x3f) << 2;
539     d[i * 4 + 3] = ((s[i]) & 0x1f) << 3;
540   }
541 }
542
543 static void
544 pack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
545     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
546     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
547     gint y, gint width)
548 {
549   int i;
550   guint16 *d = GET_LINE (y);
551   const guint8 *s = src;
552
553   for (i = 0; i < width; i++) {
554     d[i] = ((s[i * 4 + 1] >> 3) << 11) |
555         ((s[i * 4 + 2] >> 2) << 5) | (s[i * 4 + 3] >> 3);
556   }
557 }
558
559 #define PACK_BGR16 GST_VIDEO_FORMAT_ARGB, unpack_BGR16, 1, pack_BGR16
560 static void
561 unpack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
562     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
563     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
564 {
565   int i;
566   const guint16 *s = GET_LINE (y);
567   guint8 *d = dest;
568
569   for (i = 0; i < width; i++) {
570     d[i * 4 + 0] = 0xff;
571     d[i * 4 + 3] = ((s[i] >> 11) & 0x1f) << 3;
572     d[i * 4 + 2] = ((s[i] >> 5) & 0x3f) << 2;
573     d[i * 4 + 1] = ((s[i]) & 0x1f) << 3;
574   }
575 }
576
577 static void
578 pack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
579     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
580     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
581     gint y, gint width)
582 {
583   int i;
584   guint16 *d = GET_LINE (y);
585   const guint8 *s = src;
586
587   for (i = 0; i < width; i++) {
588     d[i] = ((s[i * 4 + 3] >> 3) << 11) |
589         ((s[i * 4 + 2] >> 2) << 5) | (s[i * 4 + 1] >> 3);
590   }
591 }
592
593 #define PACK_RGB15 GST_VIDEO_FORMAT_ARGB, unpack_RGB15, 1, pack_RGB15
594 static void
595 unpack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
596     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
597     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
598 {
599   int i;
600   const guint16 *s = GET_LINE (y);
601   guint8 *d = dest;
602
603   for (i = 0; i < width; i++) {
604     d[i * 4 + 0] = 0xff;
605     d[i * 4 + 1] = ((s[i] >> 10) & 0x1f) << 3;
606     d[i * 4 + 2] = ((s[i] >> 5) & 0x1f) << 3;
607     d[i * 4 + 3] = ((s[i]) & 0x1f) << 3;
608   }
609 }
610
611 static void
612 pack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
613     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
614     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
615     gint y, gint width)
616 {
617   int i;
618   guint16 *d = GET_LINE (y);
619   const guint8 *s = src;
620
621   for (i = 0; i < width; i++) {
622     d[i] = ((s[i * 4 + 1] >> 3) << 10) |
623         ((s[i * 4 + 2] >> 3) << 5) | (s[i * 4 + 3] >> 3);
624   }
625 }
626
627 #define PACK_BGR15 GST_VIDEO_FORMAT_ARGB, unpack_BGR15, 1, pack_BGR15
628 static void
629 unpack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
630     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
631     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
632 {
633   int i;
634   const guint16 *s = GET_LINE (y);
635   guint8 *d = dest;
636
637   for (i = 0; i < width; i++) {
638     d[i * 4 + 0] = 0xff;
639     d[i * 4 + 3] = ((s[i] >> 10) & 0x1f) << 3;
640     d[i * 4 + 2] = ((s[i] >> 5) & 0x1f) << 3;
641     d[i * 4 + 1] = ((s[i]) & 0x1f) << 3;
642   }
643 }
644
645 static void
646 pack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
647     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
648     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
649     gint y, gint width)
650 {
651   int i;
652   guint16 *d = GET_LINE (y);
653   const guint8 *s = src;
654
655   for (i = 0; i < width; i++) {
656     d[i] = ((s[i * 4 + 3] >> 3) << 10) |
657         ((s[i * 4 + 2] >> 3) << 5) | (s[i * 4 + 1] >> 3);
658   }
659 }
660
661 #define PACK_BGRA GST_VIDEO_FORMAT_ARGB, unpack_BGRA, 1, pack_BGRA
662 static void
663 unpack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
664     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
665     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
666 {
667   orc_unpack_BGRA (dest, GET_LINE (y), width);
668 }
669
670 static void
671 pack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
672     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
673     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
674     gint y, gint width)
675 {
676   orc_pack_BGRA (GET_LINE (y), src, width);
677 }
678
679 #define PACK_ABGR GST_VIDEO_FORMAT_ARGB, unpack_ABGR, 1, pack_ABGR
680 static void
681 unpack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
682     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
683     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
684 {
685   orc_unpack_ABGR (dest, GET_LINE (y), width);
686 }
687
688 static void
689 pack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
690     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
691     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
692     gint y, gint width)
693 {
694   orc_pack_ABGR (GET_LINE (y), src, width);
695 }
696
697 #define PACK_RGBA GST_VIDEO_FORMAT_ARGB, unpack_RGBA, 1, pack_RGBA
698 static void
699 unpack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
700     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
701     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
702 {
703   orc_unpack_RGBA (dest, GET_LINE (y), width);
704 }
705
706 static void
707 pack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
708     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
709     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
710     gint y, gint width)
711 {
712   orc_pack_RGBA (GET_LINE (y), src, width);
713 }
714
715 #define PACK_RGB GST_VIDEO_FORMAT_ARGB, unpack_RGB, 1, pack_RGB
716 static void
717 unpack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
718     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
719     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
720 {
721   int i;
722   const guint8 *s = GET_LINE (y);
723   guint8 *d = dest;
724
725   for (i = 0; i < width; i++) {
726     d[i * 4 + 0] = 0xff;
727     d[i * 4 + 1] = s[i * 3 + 0];
728     d[i * 4 + 2] = s[i * 3 + 1];
729     d[i * 4 + 3] = s[i * 3 + 2];
730   }
731 }
732
733 static void
734 pack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
735     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
736     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
737     gint y, gint width)
738 {
739   int i;
740   guint8 *d = GET_LINE (y);
741   const guint8 *s = src;
742
743   for (i = 0; i < width; i++) {
744     d[i * 3 + 0] = s[i * 4 + 1];
745     d[i * 3 + 1] = s[i * 4 + 2];
746     d[i * 3 + 2] = s[i * 4 + 3];
747   }
748 }
749
750 #define PACK_BGR GST_VIDEO_FORMAT_ARGB, unpack_BGR, 1, pack_BGR
751 static void
752 unpack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
753     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
754     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
755 {
756   int i;
757   const guint8 *s = GET_LINE (y);
758   guint8 *d = dest;
759
760   for (i = 0; i < width; i++) {
761     d[i * 4 + 0] = 0xff;
762     d[i * 4 + 1] = s[i * 3 + 2];
763     d[i * 4 + 2] = s[i * 3 + 1];
764     d[i * 4 + 3] = s[i * 3 + 0];
765   }
766 }
767
768 static void
769 pack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
770     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
771     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
772     gint y, gint width)
773 {
774   int i;
775   guint8 *d = GET_LINE (y);
776   const guint8 *s = src;
777
778   for (i = 0; i < width; i++) {
779     d[i * 3 + 0] = s[i * 4 + 3];
780     d[i * 3 + 1] = s[i * 4 + 2];
781     d[i * 3 + 2] = s[i * 4 + 1];
782   }
783 }
784
785 #define PACK_NV12 GST_VIDEO_FORMAT_AYUV, unpack_NV12, 1, pack_NV12
786 static void
787 unpack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
788     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
789     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
790 {
791   orc_unpack_NV12 (dest,
792       GET_PLANE_LINE (0, y), GET_PLANE_LINE (1, y >> 1), width / 2);
793 }
794
795 static void
796 pack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
797     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
798     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
799     gint y, gint width)
800 {
801   orc_pack_NV12 (GET_PLANE_LINE (0, y),
802       GET_PLANE_LINE (1, y >> 1), src, width / 2);
803 }
804
805 #define PACK_NV21 GST_VIDEO_FORMAT_AYUV, unpack_NV21, 1, pack_NV21
806 static void
807 unpack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
808     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
809     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
810 {
811   orc_unpack_NV21 (dest,
812       GET_PLANE_LINE (0, y), GET_PLANE_LINE (1, y >> 1), width / 2);
813 }
814
815 static void
816 pack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
817     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
818     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
819     gint y, gint width)
820 {
821   orc_pack_NV21 (GET_PLANE_LINE (0, y),
822       GET_PLANE_LINE (1, y >> 1), src, width / 2);
823 }
824
825 #define PACK_UYVP GST_VIDEO_FORMAT_AYUV64, unpack_UYVP, 1, pack_UYVP
826 static void
827 unpack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
828     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
829     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
830 {
831   int i;
832   const guint8 *s = GET_LINE (y);
833   guint16 *d = dest;
834
835   for (i = 0; i < width; i += 2) {
836     guint16 y0, y1;
837     guint16 u0;
838     guint16 v0;
839
840     u0 = (s[(i / 2) * 5 + 0] << 2) | (s[(i / 2) * 5 + 1] >> 6);
841     y0 = ((s[(i / 2) * 5 + 1] & 0x3f) << 4) | (s[(i / 2) * 5 + 2] >> 4);
842     v0 = ((s[(i / 2) * 5 + 2] & 0x0f) << 6) | (s[(i / 2) * 5 + 3] >> 2);
843     y1 = ((s[(i / 2) * 5 + 3] & 0x03) << 8) | s[(i / 2) * 5 + 4];
844
845     d[i * 4 + 0] = 0xffff;
846     d[i * 4 + 1] = y0 << 6;
847     d[i * 4 + 2] = u0 << 6;
848     d[i * 4 + 3] = v0 << 6;
849     d[i * 4 + 4] = 0xffff;
850     d[i * 4 + 5] = y1 << 6;
851     d[i * 4 + 6] = u0 << 6;
852     d[i * 4 + 7] = v0 << 6;
853   }
854 }
855
856 static void
857 pack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
858     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
859     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
860     gint y, gint width)
861 {
862   int i;
863   guint8 *d = GET_LINE (y);
864   const guint16 *s = src;
865
866   for (i = 0; i < width; i += 2) {
867     guint16 y0, y1;
868     guint16 u0;
869     guint16 v0;
870
871     y0 = s[4 * (i + 0) + 1];
872     y1 = s[4 * (i + 1) + 1];
873     u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 1;
874     v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 1;
875
876     d[(i / 2) * 5 + 0] = u0 >> 8;
877     d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10;
878     d[(i / 2) * 5 + 2] = ((y0 & 0x3c0) >> 2) | (v0 >> 12);
879     d[(i / 2) * 5 + 3] = ((v0 & 0xfc0) >> 4) | (y1 >> 14);
880     d[(i / 2) * 5 + 4] = (y1 >> 6);
881   }
882 }
883
884 #define PACK_A420 GST_VIDEO_FORMAT_AYUV, unpack_A420, 1, pack_A420
885 static void
886 unpack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
887     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
888     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
889 {
890   orc_unpack_A420 (dest,
891       GET_Y_LINE (y), GET_U_LINE (y >> 1), GET_V_LINE (y >> 1), GET_A_LINE (y),
892       width);
893 }
894
895 static void
896 pack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
897     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
898     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
899     gint y, gint width)
900 {
901   orc_pack_A420 (GET_Y_LINE (y),
902       GET_U_LINE (y >> 1), GET_V_LINE (y >> 1), GET_A_LINE (y), src, width / 2);
903 }
904
905 #define PACK_RGB8P GST_VIDEO_FORMAT_ARGB, unpack_RGB8P, 1, pack_RGB8P
906 static void
907 unpack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
908     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
909     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
910 {
911   int i;
912   const guint8 *s = GET_LINE (y);
913   const guint32 *p = data[1];
914   guint8 *d = dest;
915
916   for (i = 0; i < width; i++) {
917     guint32 v = p[s[i]];
918     d[i * 4 + 0] = (v >> 24) & 0xff;
919     d[i * 4 + 1] = (v >> 16) & 0xff;
920     d[i * 4 + 2] = (v >> 8) & 0xff;
921     d[i * 4 + 3] = (v) & 0xff;
922   }
923 }
924
925 static void
926 pack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
927     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
928     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
929     gint y, gint width)
930 {
931   int i;
932   guint8 *d = GET_LINE (y);
933   const guint8 *s = src;
934
935   /* Use our poor man's palette, taken from ffmpegcolorspace too */
936   for (i = 0; i < width; i++) {
937     /* crude approximation for alpha ! */
938     if (s[i * 4 + 0] < 0x80)
939       d[i] = 6 * 6 * 6;
940     else
941       d[i] =
942           ((((s[i * 4 + 1]) / 47) % 6) * 6 * 6 + (((s[i * 4 +
943                           2]) / 47) % 6) * 6 + (((s[i * 4 + 3]) / 47) % 6));
944   }
945 }
946
947 #define PACK_410 GST_VIDEO_FORMAT_AYUV, unpack_410, 1, pack_410
948 static void
949 unpack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
950     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
951     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
952 {
953   orc_unpack_YUV9 (dest,
954       GET_Y_LINE (y), GET_U_LINE (y >> 2), GET_V_LINE (y >> 2), width / 2);
955 }
956
957 static void
958 pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
959     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
960     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
961     gint y, gint width)
962 {
963   int i;
964   guint8 *destY = GET_Y_LINE (y);
965   guint8 *destU = GET_U_LINE (y >> 2);
966   guint8 *destV = GET_V_LINE (y >> 2);
967   const guint8 *s = src;
968
969   for (i = 0; i < width - 3; i += 4) {
970     destY[i] = s[i * 4 + 1];
971     destY[i + 1] = s[i * 4 + 5];
972     destY[i + 2] = s[i * 4 + 9];
973     destY[i + 3] = s[i * 4 + 13];
974     if (y % 4 == 0) {
975       destU[i >> 2] =
976           (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2;
977       destV[i >> 2] =
978           (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2;
979     }
980   }
981
982   if (i == width - 3) {
983     destY[i] = s[i * 4 + 1];
984     destY[i + 1] = s[i * 4 + 5];
985     destY[i + 2] = s[i * 4 + 9];
986     if (y % 4 == 0) {
987       destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3;
988       destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3;
989     }
990   } else if (i == width - 2) {
991     destY[i] = s[i * 4 + 1];
992     destY[i + 1] = s[i * 4 + 5];
993     if (y % 4 == 0) {
994       destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1;
995       destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1;
996     }
997   } else if (i == width - 1) {
998     destY[i] = s[i * 4 + 1];
999     destU[i >> 2] = s[i * 4 + 2];
1000     destV[i >> 2] = s[i * 4 + 3];
1001   }
1002 }
1003
1004 #define PACK_IYU1 GST_VIDEO_FORMAT_AYUV, unpack_IYU1, 1, pack_IYU1
1005 static void
1006 unpack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1007     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1008     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1009 {
1010   int i;
1011   const guint8 *s = GET_LINE (y);
1012   guint8 *d = dest;
1013
1014   for (i = 0; i < width - 3; i += 4) {
1015     d[i * 4 + 0] = 0xff;
1016     d[i * 4 + 4] = 0xff;
1017     d[i * 4 + 8] = 0xff;
1018     d[i * 4 + 12] = 0xff;
1019     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1020     d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
1021     d[i * 4 + 9] = s[(i >> 2) * 6 + 4];
1022     d[i * 4 + 13] = s[(i >> 2) * 6 + 5];
1023     d[i * 4 + 2] = d[i * 4 + 6] = d[i * 4 + 10] = d[i * 4 + 14] =
1024         s[(i >> 2) * 6 + 0];
1025     d[i * 4 + 3] = d[i * 4 + 7] = d[i * 4 + 11] = d[i * 4 + 15] =
1026         s[(i >> 2) * 6 + 3];
1027   }
1028
1029   if (i == width - 3) {
1030     d[i * 4 + 0] = 0xff;
1031     d[i * 4 + 4] = 0xff;
1032     d[i * 4 + 8] = 0xff;
1033     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1034     d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
1035     d[i * 4 + 9] = s[(i >> 2) * 6 + 4];
1036     d[i * 4 + 2] = d[i * 4 + 6] = d[i * 4 + 10] = s[(i >> 2) * 6 + 0];
1037     d[i * 4 + 3] = d[i * 4 + 7] = d[i * 4 + 11] = s[(i >> 2) * 6 + 3];
1038   } else if (i == width - 2) {
1039     d[i * 4 + 0] = 0xff;
1040     d[i * 4 + 4] = 0xff;
1041     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1042     d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
1043     d[i * 4 + 2] = d[i * 4 + 6] = s[(i >> 2) * 6 + 0];
1044     d[i * 4 + 3] = d[i * 4 + 7] = s[(i >> 2) * 6 + 3];
1045   } else if (i == width - 1) {
1046     d[i * 4 + 0] = 0xff;
1047     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1048     d[i * 4 + 2] = s[(i >> 2) * 6 + 0];
1049     d[i * 4 + 3] = s[(i >> 2) * 6 + 3];
1050   }
1051 }
1052
1053 static void
1054 pack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1055     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1056     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1057     gint y, gint width)
1058 {
1059   int i;
1060   guint8 *d = GET_LINE (y);
1061   const guint8 *s = src;
1062
1063   for (i = 0; i < width - 3; i += 4) {
1064     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1065     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
1066     d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
1067     d[(i >> 2) * 6 + 5] = s[i * 4 + 13];
1068     d[(i >> 2) * 6 + 0] =
1069         (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2;
1070     d[(i >> 2) * 6 + 3] =
1071         (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2;
1072   }
1073
1074   if (i == width - 3) {
1075     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1076     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
1077     d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
1078     d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3;
1079     d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3;
1080   } else if (i == width - 2) {
1081     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1082     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
1083     d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1;
1084     d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1;
1085   } else if (i == width - 1) {
1086     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1087     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
1088     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
1089   }
1090 }
1091
1092 #define PACK_ARGB64 GST_VIDEO_FORMAT_ARGB64, unpack_copy8, 1, pack_copy8
1093 #define PACK_AYUV64 GST_VIDEO_FORMAT_AYUV64, unpack_copy8, 1, pack_copy8
1094 static void
1095 unpack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1096     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1097     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1098 {
1099   memcpy (dest, GET_LINE (y), width * 8);
1100 }
1101
1102 static void
1103 pack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1104     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1105     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1106     gint y, gint width)
1107 {
1108   memcpy (GET_LINE (y), src, width * 8);
1109 }
1110
1111 #define PACK_r210 GST_VIDEO_FORMAT_AYUV64, unpack_r210, 1, pack_r210
1112 static void
1113 unpack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1114     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1115     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1116 {
1117   int i;
1118   const guint8 *s = GET_LINE (y);
1119   guint16 *d = dest;
1120
1121   for (i = 0; i < width; i++) {
1122     guint32 x;
1123     d[i * 4 + 0] = 0xffff;
1124     x = GST_READ_UINT32_BE (s + i * 4);
1125     d[i * 4 + 1] = ((x >> 14) & 0xffc0) | (x >> 24);
1126     d[i * 4 + 2] = ((x >> 4) & 0xffc0) | ((x >> 14) & 0x3f);
1127     d[i * 4 + 3] = ((x << 6) & 0xffc0) | ((x >> 4) & 0x3f);
1128   }
1129 }
1130
1131 static void
1132 pack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1133     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1134     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1135     gint y, gint width)
1136 {
1137   int i;
1138   guint8 *d = GET_LINE (y);
1139   const guint16 *s = src;
1140
1141   for (i = 0; i < width; i++) {
1142     guint32 x = 0;
1143     x |= (s[i * 4 + 1] & 0xffc0) << 14;
1144     x |= (s[i * 4 + 2] & 0xffc0) << 4;
1145     x |= (s[i * 4 + 3] & 0xffc0) >> 6;
1146     GST_WRITE_UINT32_BE (d + i * 4, x);
1147   }
1148 }
1149
1150 #define PACK_I420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10LE, 1, pack_I420_10LE
1151 static void
1152 unpack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1153     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1154     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1155 {
1156   int i;
1157   guint16 *srcY = GET_Y_LINE (y);
1158   guint16 *srcU = GET_U_LINE (y >> 1);
1159   guint16 *srcV = GET_V_LINE (y >> 1);
1160   guint16 *d = dest;
1161
1162   for (i = 0; i < width; i++) {
1163     d[i * 4 + 0] = 0xffff;
1164     d[i * 4 + 1] = GST_READ_UINT16_LE (srcY + i) << 6;
1165     d[i * 4 + 2] = GST_READ_UINT16_LE (srcU + (i >> 1)) << 6;
1166     d[i * 4 + 3] = GST_READ_UINT16_LE (srcV + (i >> 1)) << 6;
1167   }
1168 }
1169
1170 static void
1171 pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1172     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1173     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1174     gint y, gint width)
1175 {
1176   int i;
1177   guint16 *destY = GET_Y_LINE (y);
1178   guint16 *destU = GET_U_LINE (y >> 1);
1179   guint16 *destV = GET_V_LINE (y >> 1);
1180   guint16 Y0, Y1, U, V;
1181   const guint16 *s = src;
1182
1183   for (i = 0; i < width - 1; i += 2) {
1184     Y0 = (s[i * 4 + 1]) >> 6;
1185     Y1 = (s[i * 4 + 5]) >> 6;
1186     U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6;
1187     V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6;
1188
1189     GST_WRITE_UINT16_LE (destY + i + 0, Y0);
1190     GST_WRITE_UINT16_LE (destY + i + 1, Y1);
1191     GST_WRITE_UINT16_LE (destU + (i >> 1), U);
1192     GST_WRITE_UINT16_LE (destV + (i >> 1), V);
1193   }
1194   if (i == width - 1) {
1195     Y0 = s[i * 4 + 1] >> 6;
1196     U = s[i * 4 + 2] >> 6;
1197     V = s[i * 4 + 3] >> 6;
1198
1199     GST_WRITE_UINT16_LE (destY + i, Y0);
1200     GST_WRITE_UINT16_LE (destU + (i >> 1), U);
1201     GST_WRITE_UINT16_LE (destV + (i >> 1), V);
1202   }
1203 }
1204
1205 #define PACK_I420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10BE, 1, pack_I420_10BE
1206 static void
1207 unpack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1208     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1209     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1210 {
1211   int i;
1212   guint16 *srcY = GET_Y_LINE (y);
1213   guint16 *srcU = GET_U_LINE (y >> 1);
1214   guint16 *srcV = GET_V_LINE (y >> 1);
1215   guint16 *d = dest;
1216
1217   for (i = 0; i < width; i++) {
1218     d[i * 4 + 0] = 0xffff;
1219     d[i * 4 + 1] = GST_READ_UINT16_BE (srcY + i) << 6;
1220     d[i * 4 + 2] = GST_READ_UINT16_BE (srcU + (i >> 1)) << 6;
1221     d[i * 4 + 3] = GST_READ_UINT16_BE (srcV + (i >> 1)) << 6;
1222   }
1223 }
1224
1225 static void
1226 pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1227     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1228     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1229     gint y, gint width)
1230 {
1231   int i;
1232   guint16 *destY = GET_Y_LINE (y);
1233   guint16 *destU = GET_U_LINE (y >> 1);
1234   guint16 *destV = GET_V_LINE (y >> 1);
1235   guint16 Y0, Y1, U, V;
1236   const guint16 *s = src;
1237
1238   for (i = 0; i < width - 1; i += 2) {
1239     Y0 = s[i * 4 + 1] >> 6;
1240     Y1 = s[i * 4 + 5] >> 6;
1241     U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6;
1242     V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6;
1243
1244     GST_WRITE_UINT16_BE (destY + i + 0, Y0);
1245     GST_WRITE_UINT16_BE (destY + i + 1, Y1);
1246     GST_WRITE_UINT16_BE (destU + (i >> 1), U);
1247     GST_WRITE_UINT16_BE (destV + (i >> 1), V);
1248   }
1249   if (i == width - 1) {
1250     Y0 = s[i * 4 + 1] >> 6;
1251     U = s[i * 4 + 2] >> 6;
1252     V = s[i * 4 + 3] >> 6;
1253
1254     GST_WRITE_UINT16_BE (destY + i, Y0);
1255     GST_WRITE_UINT16_BE (destU + (i >> 1), U);
1256     GST_WRITE_UINT16_BE (destV + (i >> 1), V);
1257   }
1258 }
1259
1260 typedef struct
1261 {
1262   guint32 fourcc;
1263   GstVideoFormatInfo info;
1264 } VideoFormat;
1265
1266 /* depths: bits, n_components, shift, depth */
1267 #define DPTH0            0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1268 #define DPTH8            8, 1, { 0, 0, 0, 0 }, { 8, 0, 0, 0 }
1269 #define DPTH8_32         8, 2, { 0, 0, 0, 0 }, { 8, 32, 0, 0 }
1270 #define DPTH888          8, 3, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
1271 #define DPTH8888         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 8 }
1272 #define DPTH10_10_10     10, 3, { 0, 0, 0, 0 }, { 10, 10, 10, 0 }
1273 #define DPTH16           16, 1, { 0, 0, 0, 0 }, { 16, 0, 0, 0 }
1274 #define DPTH16_16_16     16, 3, { 0, 0, 0, 0 }, { 16, 16, 16, 0 }
1275 #define DPTH16_16_16_16  16, 4, { 0, 0, 0, 0 }, { 16, 16, 16, 16 }
1276 #define DPTH555          16, 3, { 10, 5, 0, 0 }, { 5, 5, 5, 0 }
1277 #define DPTH565          16, 3, { 11, 5, 0, 0 }, { 5, 6, 5, 0 }
1278
1279 /* pixel strides */
1280 #define PSTR0             { 0, 0, 0, 0 }
1281 #define PSTR1             { 1, 0, 0, 0 }
1282 #define PSTR14            { 1, 4, 0, 0 }
1283 #define PSTR111           { 1, 1, 1, 0 }
1284 #define PSTR1111          { 1, 1, 1, 1 }
1285 #define PSTR122           { 1, 2, 2, 0 }
1286 #define PSTR2             { 2, 0, 0, 0 }
1287 #define PSTR222           { 2, 2, 2, 0 }
1288 #define PSTR244           { 2, 4, 4, 0 }
1289 #define PSTR444           { 4, 4, 4, 0 }
1290 #define PSTR4444          { 4, 4, 4, 4 }
1291 #define PSTR333           { 3, 3, 3, 0 }
1292 #define PSTR488           { 4, 8, 8, 0 }
1293 #define PSTR8888          { 8, 8, 8, 8 }
1294
1295 /* planes */
1296 #define PLANE_NA          0, { 0, 0, 0, 0 }
1297 #define PLANE0            1, { 0, 0, 0, 0 }
1298 #define PLANE01           2, { 0, 1, 0, 0 }
1299 #define PLANE011          2, { 0, 1, 1, 0 }
1300 #define PLANE012          3, { 0, 1, 2, 0 }
1301 #define PLANE0123         4, { 0, 1, 2, 3 }
1302 #define PLANE021          3, { 0, 2, 1, 0 }
1303
1304 /* offsets */
1305 #define OFFS0             { 0, 0, 0, 0 }
1306 #define OFFS013           { 0, 1, 3, 0 }
1307 #define OFFS102           { 1, 0, 2, 0 }
1308 #define OFFS1230          { 1, 2, 3, 0 }
1309 #define OFFS012           { 0, 1, 2, 0 }
1310 #define OFFS210           { 2, 1, 0, 0 }
1311 #define OFFS123           { 1, 2, 3, 0 }
1312 #define OFFS321           { 3, 2, 1, 0 }
1313 #define OFFS0123          { 0, 1, 2, 3 }
1314 #define OFFS2103          { 2, 1, 0, 3 }
1315 #define OFFS3210          { 3, 2, 1, 0 }
1316 #define OFFS031           { 0, 3, 1, 0 }
1317 #define OFFS204           { 2, 0, 4, 0 }
1318 #define OFFS001           { 0, 0, 1, 0 }
1319 #define OFFS010           { 0, 1, 0, 0 }
1320 #define OFFS104           { 1, 0, 4, 0 }
1321 #define OFFS2460          { 2, 4, 6, 0 }
1322
1323 /* subsampling */
1324 #define SUB410            { 0, 2, 2, 0 }, { 0, 2, 2, 0 }
1325 #define SUB411            { 0, 2, 2, 0 }, { 0, 0, 0, 0 }
1326 #define SUB420            { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
1327 #define SUB422            { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
1328 #define SUB4              { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1329 #define SUB44             { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1330 #define SUB444            { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1331 #define SUB4444           { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1332 #define SUB4204           { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
1333
1334 #define MAKE_YUV_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
1335  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV, depth, pstride, plane, offs, sub, pack } }
1336 #define MAKE_YUV_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
1337  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
1338 #define MAKE_YUVA_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
1339  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_ALPHA, depth, pstride, plane, offs, sub, pack } }
1340 #define MAKE_YUV_C_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
1341  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_COMPLEX, depth, pstride, plane, offs, sub, pack } }
1342
1343 #define MAKE_RGB_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1344  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB, depth, pstride, plane, offs, sub, pack } }
1345 #define MAKE_RGB_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1346  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
1347 #define MAKE_RGBA_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1348  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_ALPHA, depth, pstride, plane, offs, sub, pack } }
1349 #define MAKE_RGBAP_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1350  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_PALETTE, depth, pstride, plane, offs, sub, pack } }
1351
1352 #define MAKE_GRAY_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1353  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY, depth, pstride, plane, offs, sub, pack } }
1354 #define MAKE_GRAY_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1355  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
1356
1357 static VideoFormat formats[] = {
1358   {0x00000000, {GST_VIDEO_FORMAT_UNKNOWN, "UNKNOWN", "unknown video", 0, DPTH0,
1359               PSTR0, PLANE_NA,
1360           OFFS0}},
1361   {0x00000000, {GST_VIDEO_FORMAT_ENCODED, "ENCODED", "encoded video",
1362           GST_VIDEO_FORMAT_FLAG_COMPLEX, DPTH0, PSTR0, PLANE_NA, OFFS0}},
1363
1364   MAKE_YUV_FORMAT (I420, "raw video", GST_MAKE_FOURCC ('I', '4', '2', '0'),
1365       DPTH888, PSTR111,
1366       PLANE012, OFFS0, SUB420, PACK_420),
1367   MAKE_YUV_FORMAT (YV12, "raw video", GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
1368       DPTH888, PSTR111,
1369       PLANE021, OFFS0, SUB420, PACK_420),
1370   MAKE_YUV_FORMAT (YUY2, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
1371       DPTH888, PSTR244,
1372       PLANE0, OFFS013, SUB422, PACK_YUY2),
1373   MAKE_YUV_FORMAT (UYVY, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
1374       DPTH888, PSTR244,
1375       PLANE0, OFFS102, SUB422, PACK_UYVY),
1376   MAKE_YUVA_FORMAT (AYUV, "raw video", GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'),
1377       DPTH8888,
1378       PSTR4444, PLANE0, OFFS1230, SUB4444, PACK_AYUV),
1379   MAKE_RGB_FORMAT (RGBx, "raw video", DPTH888, PSTR444, PLANE0, OFFS012,
1380       SUB444, PACK_RGBA),
1381   MAKE_RGB_FORMAT (BGRx, "raw video", DPTH888, PSTR444, PLANE0, OFFS210,
1382       SUB444, PACK_BGRA),
1383   MAKE_RGB_FORMAT (xRGB, "raw video", DPTH888, PSTR444, PLANE0, OFFS123,
1384       SUB444, PACK_ARGB),
1385   MAKE_RGB_FORMAT (xBGR, "raw video", DPTH888, PSTR444, PLANE0, OFFS321,
1386       SUB444, PACK_ABGR),
1387   MAKE_RGBA_FORMAT (RGBA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS0123,
1388       SUB4444, PACK_RGBA),
1389   MAKE_RGBA_FORMAT (BGRA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS2103,
1390       SUB4444, PACK_BGRA),
1391   MAKE_RGBA_FORMAT (ARGB, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS1230,
1392       SUB4444, PACK_ARGB),
1393   MAKE_RGBA_FORMAT (ABGR, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS3210,
1394       SUB4444, PACK_ABGR),
1395   MAKE_RGB_FORMAT (RGB, "raw video", DPTH888, PSTR333, PLANE0, OFFS012, SUB444,
1396       PACK_RGB),
1397   MAKE_RGB_FORMAT (BGR, "raw video", DPTH888, PSTR333, PLANE0, OFFS210, SUB444,
1398       PACK_BGR),
1399
1400   MAKE_YUV_FORMAT (Y41B, "raw video", GST_MAKE_FOURCC ('Y', '4', '1', 'B'),
1401       DPTH888, PSTR111,
1402       PLANE012, OFFS0, SUB411, PACK_Y41B),
1403   MAKE_YUV_FORMAT (Y42B, "raw video", GST_MAKE_FOURCC ('Y', '4', '2', 'B'),
1404       DPTH888, PSTR111,
1405       PLANE012, OFFS0, SUB422, PACK_Y42B),
1406   MAKE_YUV_FORMAT (YVYU, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'),
1407       DPTH888, PSTR244,
1408       PLANE0, OFFS031, SUB422, PACK_YVYU),
1409   MAKE_YUV_FORMAT (Y444, "raw video", GST_MAKE_FOURCC ('Y', '4', '4', '4'),
1410       DPTH888, PSTR111,
1411       PLANE012, OFFS0, SUB444, PACK_Y444),
1412   MAKE_YUV_C_FORMAT (v210, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '0'),
1413       DPTH10_10_10,
1414       PSTR0, PLANE0, OFFS0, SUB422, PACK_v210),
1415   MAKE_YUV_FORMAT (v216, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '6'),
1416       DPTH16_16_16,
1417       PSTR488, PLANE0, OFFS204, SUB422, PACK_v216),
1418   MAKE_YUV_FORMAT (NV12, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '2'),
1419       DPTH888, PSTR122,
1420       PLANE011, OFFS001, SUB420, PACK_NV12),
1421   MAKE_YUV_FORMAT (NV21, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '1'),
1422       DPTH888, PSTR122,
1423       PLANE011, OFFS010, SUB420, PACK_NV21),
1424
1425   MAKE_GRAY_FORMAT (GRAY8, "raw video", DPTH8, PSTR1, PLANE0, OFFS0, SUB4,
1426       PACK_GRAY8),
1427   MAKE_GRAY_FORMAT (GRAY16_BE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0, SUB4,
1428       PACK_GRAY16_BE),
1429   MAKE_GRAY_LE_FORMAT (GRAY16_LE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0,
1430       SUB4, PACK_GRAY16_LE),
1431
1432   MAKE_YUV_FORMAT (v308, "raw video", GST_MAKE_FOURCC ('v', '3', '0', '8'),
1433       DPTH888, PSTR333,
1434       PLANE0, OFFS012, SUB444, PACK_v308),
1435
1436 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1437   MAKE_RGB_LE_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
1438       SUB444, PACK_RGB16),
1439   MAKE_RGB_LE_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
1440       SUB444, PACK_BGR16),
1441   MAKE_RGB_LE_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
1442       SUB444, PACK_RGB15),
1443   MAKE_RGB_LE_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
1444       SUB444, PACK_BGR15),
1445 #else
1446   MAKE_RGB_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
1447       PACK_RGB16),
1448   MAKE_RGB_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
1449       PACK_BGR16),
1450   MAKE_RGB_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
1451       PACK_RGB15),
1452   MAKE_RGB_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
1453       PACK_BGR15),
1454 #endif
1455
1456   MAKE_YUV_C_FORMAT (UYVP, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'),
1457       DPTH10_10_10,
1458       PSTR0, PLANE0, OFFS0, SUB422, PACK_UYVP),
1459   MAKE_YUVA_FORMAT (A420, "raw video", GST_MAKE_FOURCC ('A', '4', '2', '0'),
1460       DPTH8888,
1461       PSTR1111, PLANE0123, OFFS0, SUB4204, PACK_A420),
1462   MAKE_RGBAP_FORMAT (RGB8P, "raw video", DPTH8_32, PSTR14, PLANE01,
1463       OFFS0, SUB44, PACK_RGB8P),
1464   MAKE_YUV_FORMAT (YUV9, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'V', '9'),
1465       DPTH888, PSTR111,
1466       PLANE012, OFFS0, SUB410, PACK_410),
1467   MAKE_YUV_FORMAT (YVU9, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'U', '9'),
1468       DPTH888, PSTR111,
1469       PLANE021, OFFS0, SUB410, PACK_410),
1470   MAKE_YUV_FORMAT (IYU1, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '1'),
1471       DPTH888, PSTR0,
1472       PLANE0, OFFS104, SUB411, PACK_IYU1),
1473   MAKE_RGBA_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
1474       OFFS2460,
1475       SUB444, PACK_ARGB64),
1476   MAKE_YUVA_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16, PSTR8888,
1477       PLANE0,
1478       OFFS2460, SUB444, PACK_AYUV64),
1479   MAKE_YUV_FORMAT (r210, "raw video", GST_MAKE_FOURCC ('r', '2', '1', '0'),
1480       DPTH10_10_10,
1481       PSTR444, PLANE0, OFFS0, SUB444, PACK_r210),
1482   MAKE_YUV_FORMAT (I420_10BE, "raw video", 0x00000000, DPTH10_10_10,
1483       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10BE),
1484   MAKE_YUV_LE_FORMAT (I420_10LE, "raw video", 0x00000000, DPTH10_10_10,
1485       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10LE),
1486 };
1487
1488 static GstVideoFormat
1489 gst_video_format_from_rgb32_masks (int red_mask, int green_mask, int blue_mask)
1490 {
1491   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
1492       blue_mask == 0x0000ff00) {
1493     return GST_VIDEO_FORMAT_RGBx;
1494   }
1495   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
1496       blue_mask == 0xff000000) {
1497     return GST_VIDEO_FORMAT_BGRx;
1498   }
1499   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
1500       blue_mask == 0x000000ff) {
1501     return GST_VIDEO_FORMAT_xRGB;
1502   }
1503   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
1504       blue_mask == 0x00ff0000) {
1505     return GST_VIDEO_FORMAT_xBGR;
1506   }
1507
1508   return GST_VIDEO_FORMAT_UNKNOWN;
1509 }
1510
1511 static GstVideoFormat
1512 gst_video_format_from_rgba32_masks (int red_mask, int green_mask,
1513     int blue_mask, int alpha_mask)
1514 {
1515   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
1516       blue_mask == 0x0000ff00 && alpha_mask == 0x000000ff) {
1517     return GST_VIDEO_FORMAT_RGBA;
1518   }
1519   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
1520       blue_mask == 0xff000000 && alpha_mask == 0x000000ff) {
1521     return GST_VIDEO_FORMAT_BGRA;
1522   }
1523   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
1524       blue_mask == 0x000000ff && alpha_mask == 0xff000000) {
1525     return GST_VIDEO_FORMAT_ARGB;
1526   }
1527   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
1528       blue_mask == 0x00ff0000 && alpha_mask == 0xff000000) {
1529     return GST_VIDEO_FORMAT_ABGR;
1530   }
1531   return GST_VIDEO_FORMAT_UNKNOWN;
1532 }
1533
1534 static GstVideoFormat
1535 gst_video_format_from_rgb24_masks (int red_mask, int green_mask, int blue_mask)
1536 {
1537   if (red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff) {
1538     return GST_VIDEO_FORMAT_RGB;
1539   }
1540   if (red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000) {
1541     return GST_VIDEO_FORMAT_BGR;
1542   }
1543
1544   return GST_VIDEO_FORMAT_UNKNOWN;
1545 }
1546
1547 #define GST_VIDEO_COMP1_MASK_16_INT 0xf800
1548 #define GST_VIDEO_COMP2_MASK_16_INT 0x07e0
1549 #define GST_VIDEO_COMP3_MASK_16_INT 0x001f
1550
1551 #define GST_VIDEO_COMP1_MASK_15_INT 0x7c00
1552 #define GST_VIDEO_COMP2_MASK_15_INT 0x03e0
1553 #define GST_VIDEO_COMP3_MASK_15_INT 0x001f
1554
1555 static GstVideoFormat
1556 gst_video_format_from_rgb16_masks (int red_mask, int green_mask, int blue_mask)
1557 {
1558   if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
1559       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
1560       && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
1561     return GST_VIDEO_FORMAT_RGB16;
1562   }
1563   if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
1564       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
1565       && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
1566     return GST_VIDEO_FORMAT_BGR16;
1567   }
1568   if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
1569       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
1570       && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
1571     return GST_VIDEO_FORMAT_RGB15;
1572   }
1573   if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
1574       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
1575       && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
1576     return GST_VIDEO_FORMAT_BGR15;
1577   }
1578   return GST_VIDEO_FORMAT_UNKNOWN;
1579 }
1580
1581 /**
1582  * gst_video_format_from_masks:
1583  * @depth: the amount of bits used for a pixel
1584  * @bpp: the amount of bits used to store a pixel. This value is bigger than
1585  *   @depth
1586  * @endianness: the endianness of the masks
1587  * @red_mask: the red mask
1588  * @green_mask: the green mask
1589  * @blue_mask: the blue mask
1590  * @alpha_mask: the optional alpha mask
1591  *
1592  * Find the #GstVideoFormat for the given parameters.
1593  *
1594  * Returns: a #GstVideoFormat or GST_VIDEO_FORMAT_UNKNOWN when the parameters to
1595  * not specify a known format.
1596  */
1597 GstVideoFormat
1598 gst_video_format_from_masks (gint depth, gint bpp, gint endianness,
1599     gint red_mask, gint green_mask, gint blue_mask, gint alpha_mask)
1600 {
1601   GstVideoFormat format;
1602
1603   /* our caps system handles 24/32bpp RGB as big-endian. */
1604   if ((bpp == 24 || bpp == 32) && endianness == G_LITTLE_ENDIAN) {
1605     red_mask = GUINT32_TO_BE (red_mask);
1606     green_mask = GUINT32_TO_BE (green_mask);
1607     blue_mask = GUINT32_TO_BE (blue_mask);
1608     endianness = G_BIG_ENDIAN;
1609     if (bpp == 24) {
1610       red_mask >>= 8;
1611       green_mask >>= 8;
1612       blue_mask >>= 8;
1613     }
1614   }
1615
1616   if (depth == 30 && bpp == 32) {
1617     format = GST_VIDEO_FORMAT_r210;
1618   } else if (depth == 24 && bpp == 32) {
1619     format = gst_video_format_from_rgb32_masks (red_mask, green_mask,
1620         blue_mask);
1621   } else if (depth == 32 && bpp == 32 && alpha_mask) {
1622     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
1623         blue_mask, alpha_mask);
1624   } else if (depth == 24 && bpp == 24) {
1625     format = gst_video_format_from_rgb24_masks (red_mask, green_mask,
1626         blue_mask);
1627   } else if ((depth == 15 || depth == 16) && bpp == 16 &&
1628       endianness == G_BYTE_ORDER) {
1629     format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
1630         blue_mask);
1631   } else if (depth == 8 && bpp == 8) {
1632     format = GST_VIDEO_FORMAT_RGB8P;
1633   } else if (depth == 64 && bpp == 64) {
1634     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
1635         blue_mask, alpha_mask);
1636     if (format == GST_VIDEO_FORMAT_ARGB) {
1637       format = GST_VIDEO_FORMAT_ARGB64;
1638     } else {
1639       format = GST_VIDEO_FORMAT_UNKNOWN;
1640     }
1641   } else {
1642     format = GST_VIDEO_FORMAT_UNKNOWN;
1643   }
1644   return format;
1645 }
1646
1647 /**
1648  * gst_video_format_from_fourcc:
1649  * @fourcc: a FOURCC value representing raw YUV video
1650  *
1651  * Converts a FOURCC value into the corresponding #GstVideoFormat.
1652  * If the FOURCC cannot be represented by #GstVideoFormat,
1653  * #GST_VIDEO_FORMAT_UNKNOWN is returned.
1654  *
1655  * Since: 0.10.16
1656  *
1657  * Returns: the #GstVideoFormat describing the FOURCC value
1658  */
1659 GstVideoFormat
1660 gst_video_format_from_fourcc (guint32 fourcc)
1661 {
1662   switch (fourcc) {
1663     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
1664       return GST_VIDEO_FORMAT_I420;
1665     case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
1666       return GST_VIDEO_FORMAT_YV12;
1667     case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
1668       return GST_VIDEO_FORMAT_YUY2;
1669     case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
1670       return GST_VIDEO_FORMAT_YVYU;
1671     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
1672       return GST_VIDEO_FORMAT_UYVY;
1673     case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
1674       return GST_VIDEO_FORMAT_AYUV;
1675     case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
1676       return GST_VIDEO_FORMAT_Y41B;
1677     case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
1678       return GST_VIDEO_FORMAT_Y42B;
1679     case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
1680       return GST_VIDEO_FORMAT_Y444;
1681     case GST_MAKE_FOURCC ('v', '2', '1', '0'):
1682       return GST_VIDEO_FORMAT_v210;
1683     case GST_MAKE_FOURCC ('v', '2', '1', '6'):
1684       return GST_VIDEO_FORMAT_v216;
1685     case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
1686       return GST_VIDEO_FORMAT_NV12;
1687     case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
1688       return GST_VIDEO_FORMAT_NV21;
1689     case GST_MAKE_FOURCC ('v', '3', '0', '8'):
1690       return GST_VIDEO_FORMAT_v308;
1691     case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
1692     case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
1693     case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
1694       return GST_VIDEO_FORMAT_GRAY8;
1695     case GST_MAKE_FOURCC ('Y', '1', '6', ' '):
1696       return GST_VIDEO_FORMAT_GRAY16_LE;
1697     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'):
1698       return GST_VIDEO_FORMAT_UYVP;
1699     case GST_MAKE_FOURCC ('A', '4', '2', '0'):
1700       return GST_VIDEO_FORMAT_A420;
1701     case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
1702       return GST_VIDEO_FORMAT_YUV9;
1703     case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
1704       return GST_VIDEO_FORMAT_YVU9;
1705     case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
1706       return GST_VIDEO_FORMAT_IYU1;
1707     case GST_MAKE_FOURCC ('A', 'Y', '6', '4'):
1708       return GST_VIDEO_FORMAT_AYUV64;
1709     default:
1710       return GST_VIDEO_FORMAT_UNKNOWN;
1711   }
1712 }
1713
1714 /**
1715  * gst_video_format_from_string:
1716  * @format: a format string
1717  *
1718  * Convert the @format string to its #GstVideoFormat.
1719  *
1720  * Returns: the #GstVideoFormat for @format or GST_VIDEO_FORMAT_UNKNOWN when the
1721  * string is not a known format.
1722  */
1723 GstVideoFormat
1724 gst_video_format_from_string (const gchar * format)
1725 {
1726   guint i;
1727
1728   g_return_val_if_fail (format != NULL, GST_VIDEO_FORMAT_UNKNOWN);
1729
1730   for (i = 0; i < G_N_ELEMENTS (formats); i++) {
1731     if (strcmp (GST_VIDEO_FORMAT_INFO_NAME (&formats[i].info), format) == 0)
1732       return GST_VIDEO_FORMAT_INFO_FORMAT (&formats[i].info);
1733   }
1734   return GST_VIDEO_FORMAT_UNKNOWN;
1735 }
1736
1737
1738 /**
1739  * gst_video_format_to_fourcc:
1740  * @format: a #GstVideoFormat video format
1741  *
1742  * Converts a #GstVideoFormat value into the corresponding FOURCC.  Only
1743  * a few YUV formats have corresponding FOURCC values.  If @format has
1744  * no corresponding FOURCC value, 0 is returned.
1745  *
1746  * Since: 0.10.16
1747  *
1748  * Returns: the FOURCC corresponding to @format
1749  */
1750 guint32
1751 gst_video_format_to_fourcc (GstVideoFormat format)
1752 {
1753   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
1754
1755   if (format >= G_N_ELEMENTS (formats))
1756     return 0;
1757
1758   return formats[format].fourcc;
1759 }
1760
1761 const gchar *
1762 gst_video_format_to_string (GstVideoFormat format)
1763 {
1764   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
1765
1766   if (format >= G_N_ELEMENTS (formats))
1767     return NULL;
1768
1769   return GST_VIDEO_FORMAT_INFO_NAME (&formats[format].info);
1770 }
1771
1772 /**
1773  * gst_video_format_get_info:
1774  * @format: a #GstVideoFormat
1775  *
1776  * Get the #GstVideoFormatInfo for @format
1777  *
1778  * Returns: The #GstVideoFormatInfo for @format.
1779  */
1780 const GstVideoFormatInfo *
1781 gst_video_format_get_info (GstVideoFormat format)
1782 {
1783   g_return_val_if_fail (format < G_N_ELEMENTS (formats), NULL);
1784
1785   return &formats[format].info;
1786 }
1787
1788 typedef struct
1789 {
1790   const gchar *name;
1791   GstVideoChromaSite site;
1792 } ChromaSiteInfo;
1793
1794 static const ChromaSiteInfo chromasite[] = {
1795   {"jpeg", GST_VIDEO_CHROMA_SITE_JPEG},
1796   {"mpeg2", GST_VIDEO_CHROMA_SITE_MPEG2},
1797   {"dv", GST_VIDEO_CHROMA_SITE_DV}
1798 };
1799
1800 /**
1801  * gst_video_chroma_from_string:
1802  * @s: a chromasite string
1803  *
1804  * Convert @s to a #GstVideoChromaSite
1805  *
1806  * Returns: a #GstVideoChromaSite or %GST_VIDEO_CHROMA_SITE_UNKNOWN when @s does
1807  * not contain a valid chroma description.
1808  */
1809 GstVideoChromaSite
1810 gst_video_chroma_from_string (const gchar * s)
1811 {
1812   gint i;
1813   for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
1814     if (g_str_equal (chromasite[i].name, s))
1815       return chromasite[i].site;
1816   }
1817   return GST_VIDEO_CHROMA_SITE_UNKNOWN;
1818 }
1819
1820 /**
1821  * gst_video_chroma_to_string:
1822  * @site: a #GstVideoChromaSite
1823  *
1824  * Converts @site to its string representation.
1825  *
1826  * Returns: a string describing @site.
1827  */
1828 const gchar *
1829 gst_video_chroma_to_string (GstVideoChromaSite site)
1830 {
1831   gint i;
1832   for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
1833     if (chromasite[i].site == site)
1834       return chromasite[i].name;
1835   }
1836   return NULL;
1837 }