video: fix return type of _get_palette() and add since markers to docs
[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., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, 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 "video-orc.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_LINE(line)               GET_PLANE_LINE (0, line)
61
62 #define GET_Y_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_Y, line)
63 #define GET_U_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_U, line)
64 #define GET_V_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_V, line)
65
66 #define GET_R_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_R, line)
67 #define GET_G_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_G, line)
68 #define GET_B_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_B, line)
69
70 #define GET_A_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_A, line)
71
72 #define GET_UV_420(line, flags)                 \
73   (flags & GST_VIDEO_PACK_FLAG_INTERLACED ?     \
74    ((line & ~3) >> 1) + (line & 1) :            \
75    line >> 1)
76 #define GET_UV_410(line, flags)                 \
77   (flags & GST_VIDEO_PACK_FLAG_INTERLACED ?     \
78    ((line & ~7) >> 2) + (line & 1) :            \
79    line >> 2)
80
81 #define PACK_420 GST_VIDEO_FORMAT_AYUV, unpack_planar_420, 1, pack_planar_420
82 static void
83 unpack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
84     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
85     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
86 {
87   gint uv = GET_UV_420 (y, flags);
88
89   video_orc_unpack_I420 (dest, GET_Y_LINE (y), GET_U_LINE (uv),
90       GET_V_LINE (uv), width);
91 }
92
93 static void
94 pack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
95     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
96     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
97     gint y, gint width)
98 {
99   gint uv = GET_UV_420 (y, flags);
100
101   video_orc_pack_I420 (GET_Y_LINE (y), GET_U_LINE (uv), GET_V_LINE (uv),
102       src, width / 2);
103 }
104
105 #define PACK_YUY2 GST_VIDEO_FORMAT_AYUV, unpack_YUY2, 1, pack_YUY2
106 static void
107 unpack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
108     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
109     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
110 {
111   video_orc_unpack_YUY2 (dest, GET_LINE (y), width / 2);
112 }
113
114 static void
115 pack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
116     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
117     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
118     gint y, gint width)
119 {
120   video_orc_pack_YUY2 (GET_LINE (y), src, width / 2);
121 }
122
123 #define PACK_UYVY GST_VIDEO_FORMAT_AYUV, unpack_UYVY, 1, pack_UYVY
124 static void
125 unpack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
126     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
127     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
128 {
129   video_orc_unpack_UYVY (dest, GET_LINE (y), width / 2);
130 }
131
132 static void
133 pack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
134     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
135     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
136     gint y, gint width)
137 {
138   video_orc_pack_UYVY (GET_LINE (y), src, width / 2);
139 }
140
141 #define PACK_YVYU GST_VIDEO_FORMAT_AYUV, unpack_YVYU, 1, pack_YVYU
142 static void
143 unpack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
144     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
145     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
146 {
147   video_orc_unpack_YVYU (dest, GET_LINE (y), width / 2);
148 }
149
150 static void
151 pack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
152     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
153     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
154     gint y, gint width)
155 {
156   video_orc_pack_YVYU (GET_LINE (y), src, width / 2);
157 }
158
159 #define PACK_v308 GST_VIDEO_FORMAT_AYUV, unpack_v308, 1, pack_v308
160 static void
161 unpack_v308 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
162     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
163     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
164 {
165   int i;
166   const guint8 *s = GET_LINE (y);
167   guint8 *d = dest;
168
169   for (i = 0; i < width; i++) {
170     d[i * 4 + 0] = 0xff;
171     d[i * 4 + 1] = s[i * 3 + 0];
172     d[i * 4 + 2] = s[i * 3 + 1];
173     d[i * 4 + 3] = s[i * 3 + 2];
174   }
175 }
176
177 static void
178 pack_v308 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
179     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
180     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
181     gint y, gint width)
182 {
183   int i;
184   guint8 *d = GET_LINE (y);
185   const guint8 *s = src;
186
187   for (i = 0; i < width; i++) {
188     d[i * 3 + 0] = s[i * 4 + 1];
189     d[i * 3 + 1] = s[i * 4 + 2];
190     d[i * 3 + 2] = s[i * 4 + 3];
191   }
192 }
193
194 #define PACK_AYUV GST_VIDEO_FORMAT_AYUV, unpack_copy4, 1, pack_copy4
195 #define PACK_ARGB GST_VIDEO_FORMAT_ARGB, unpack_copy4, 1, pack_copy4
196 static void
197 unpack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
198     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
199     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
200 {
201   memcpy (dest, GET_LINE (y), width * 4);
202 }
203
204 static void
205 pack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
206     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
207     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
208     gint y, gint width)
209 {
210   memcpy (GET_LINE (y), src, width * 4);
211 }
212
213 #define PACK_v210 GST_VIDEO_FORMAT_AYUV64, unpack_v210, 1, pack_v210
214 static void
215 unpack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
216     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
217     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
218 {
219   int i;
220   const guint8 *s = GET_LINE (y);
221   guint16 *d = dest;
222
223   for (i = 0; i < width; i += 6) {
224     guint32 a0, a1, a2, a3;
225     guint16 y0, y1, y2, y3, y4, y5;
226     guint16 u0, u2, u4;
227     guint16 v0, v2, v4;
228
229     a0 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 0);
230     a1 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 4);
231     a2 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 8);
232     a3 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 12);
233
234     u0 = ((a0 >> 0) & 0x3ff) << 6;
235     y0 = ((a0 >> 10) & 0x3ff) << 6;
236     v0 = ((a0 >> 20) & 0x3ff) << 6;
237     y1 = ((a1 >> 0) & 0x3ff) << 6;
238
239     u2 = ((a1 >> 10) & 0x3ff) << 6;
240     y2 = ((a1 >> 20) & 0x3ff) << 6;
241     v2 = ((a2 >> 0) & 0x3ff) << 6;
242     y3 = ((a2 >> 10) & 0x3ff) << 6;
243
244     u4 = ((a2 >> 20) & 0x3ff) << 6;
245     y4 = ((a3 >> 0) & 0x3ff) << 6;
246     v4 = ((a3 >> 10) & 0x3ff) << 6;
247     y5 = ((a3 >> 20) & 0x3ff) << 6;
248
249     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
250       y0 |= (y0 >> 10);
251       y1 |= (y1 >> 10);
252       u0 |= (u0 >> 10);
253       v0 |= (v0 >> 10);
254
255       y2 |= (y2 >> 10);
256       y3 |= (y3 >> 10);
257       u2 |= (u2 >> 10);
258       v2 |= (v2 >> 10);
259
260       y4 |= (y4 >> 10);
261       y5 |= (y5 >> 10);
262       u4 |= (u4 >> 10);
263       v4 |= (v4 >> 10);
264     }
265
266     d[4 * (i + 0) + 0] = 0xffff;
267     d[4 * (i + 0) + 1] = y0;
268     d[4 * (i + 0) + 2] = u0;
269     d[4 * (i + 0) + 3] = v0;
270
271     d[4 * (i + 1) + 0] = 0xffff;
272     d[4 * (i + 1) + 1] = y1;
273     d[4 * (i + 1) + 2] = u0;
274     d[4 * (i + 1) + 3] = v0;
275
276     d[4 * (i + 2) + 0] = 0xffff;
277     d[4 * (i + 2) + 1] = y2;
278     d[4 * (i + 2) + 2] = u2;
279     d[4 * (i + 2) + 3] = v2;
280
281     d[4 * (i + 3) + 0] = 0xffff;
282     d[4 * (i + 3) + 1] = y3;
283     d[4 * (i + 3) + 2] = u2;
284     d[4 * (i + 3) + 3] = v2;
285
286     d[4 * (i + 4) + 0] = 0xffff;
287     d[4 * (i + 4) + 1] = y4;
288     d[4 * (i + 4) + 2] = u4;
289     d[4 * (i + 4) + 3] = v4;
290
291     d[4 * (i + 5) + 0] = 0xffff;
292     d[4 * (i + 5) + 1] = y5;
293     d[4 * (i + 5) + 2] = u4;
294     d[4 * (i + 5) + 3] = v4;
295   }
296 }
297
298 static void
299 pack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
300     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
301     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
302     gint y, gint width)
303 {
304   int i;
305   guint8 *d = GET_LINE (y);
306   const guint16 *s = src;
307
308   for (i = 0; i < width; i += 6) {
309     guint32 a0, a1, a2, a3;
310     guint16 y0, y1, y2, y3, y4, y5;
311     guint16 u0, u1, u2;
312     guint16 v0, v1, v2;
313
314     y0 = s[4 * (i + 0) + 1] >> 6;
315     y1 = s[4 * (i + 1) + 1] >> 6;
316     y2 = s[4 * (i + 2) + 1] >> 6;
317     y3 = s[4 * (i + 3) + 1] >> 6;
318     y4 = s[4 * (i + 4) + 1] >> 6;
319     y5 = s[4 * (i + 5) + 1] >> 6;
320
321     u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 7;
322     u1 = (s[4 * (i + 2) + 2] + s[4 * (i + 3) + 2] + 1) >> 7;
323     u2 = (s[4 * (i + 4) + 2] + s[4 * (i + 5) + 2] + 1) >> 7;
324
325     v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 7;
326     v1 = (s[4 * (i + 2) + 3] + s[4 * (i + 3) + 3] + 1) >> 7;
327     v2 = (s[4 * (i + 4) + 3] + s[4 * (i + 5) + 3] + 1) >> 7;
328
329     a0 = u0 | (y0 << 10) | (v0 << 20);
330     a1 = y1 | (u1 << 10) | (y2 << 20);
331     a2 = v1 | (y3 << 10) | (u2 << 20);
332     a3 = y4 | (v2 << 10) | (y5 << 20);
333
334     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 0, a0);
335     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 4, a1);
336     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 8, a2);
337     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 12, a3);
338   }
339 }
340
341 #define PACK_v216 GST_VIDEO_FORMAT_AYUV64, unpack_v216, 1, pack_v216
342 static void
343 unpack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
344     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
345     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
346 {
347   int i;
348   const guint8 *s = GET_LINE (y);
349   guint16 *d = dest;
350
351   for (i = 0; i < width; i++) {
352     d[i * 4 + 0] = 0xffff;
353     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i * 4 + 2);
354     d[i * 4 + 2] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 0);
355     d[i * 4 + 3] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 4);
356   }
357 }
358
359 static void
360 pack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
361     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
362     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
363     gint y, gint width)
364 {
365   int i;
366   guint8 *d = GET_LINE (y);
367   const guint16 *s = src;
368
369   for (i = 0; i < width / 2; i++) {
370     GST_WRITE_UINT16_LE (d + i * 8 + 0, s[(i * 2 + 0) * 4 + 2]);
371     GST_WRITE_UINT16_LE (d + i * 8 + 2, s[(i * 2 + 0) * 4 + 1]);
372     GST_WRITE_UINT16_LE (d + i * 8 + 4, s[(i * 2 + 0) * 4 + 3]);
373     GST_WRITE_UINT16_LE (d + i * 8 + 6, s[(i * 2 + 1) * 4 + 1]);
374   }
375 }
376
377 #define PACK_Y41B GST_VIDEO_FORMAT_AYUV, unpack_Y41B, 1, pack_Y41B
378 static void
379 unpack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
380     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
381     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
382 {
383   video_orc_unpack_YUV9 (dest,
384       GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), width / 2);
385 }
386
387 static void
388 pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
389     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
390     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
391     gint y, gint width)
392 {
393   int i;
394   guint8 *destY = GET_Y_LINE (y);
395   guint8 *destU = GET_U_LINE (y);
396   guint8 *destV = GET_V_LINE (y);
397   const guint8 *s = src;
398
399   for (i = 0; i < width - 3; i += 4) {
400     destY[i] = s[i * 4 + 1];
401     destY[i + 1] = s[i * 4 + 5];
402     destY[i + 2] = s[i * 4 + 9];
403     destY[i + 3] = s[i * 4 + 13];
404
405     destU[i >> 2] =
406         (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14] + 2) >> 2;
407     destV[i >> 2] =
408         (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15] + 2) >> 2;
409   }
410
411   if (i == width - 3) {
412     destY[i] = s[i * 4 + 1];
413     destY[i + 1] = s[i * 4 + 5];
414     destY[i + 2] = s[i * 4 + 9];
415
416     destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + 1) / 3;
417     destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + 1) / 3;
418   } else if (i == width - 2) {
419     destY[i] = s[i * 4 + 1];
420     destY[i + 1] = s[i * 4 + 5];
421
422     destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1;
423     destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1;
424   } else if (i == width - 1) {
425     destY[i + 1] = s[i * 4 + 5];
426
427     destU[i >> 2] = s[i * 4 + 2];
428     destV[i >> 2] = s[i * 4 + 3];
429   }
430 }
431
432 #define PACK_Y42B GST_VIDEO_FORMAT_AYUV, unpack_Y42B, 1, pack_Y42B
433 static void
434 unpack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
435     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
436     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
437 {
438   video_orc_unpack_Y42B (dest,
439       GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), width / 2);
440 }
441
442 static void
443 pack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
444     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
445     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
446     gint y, gint width)
447 {
448   video_orc_pack_Y42B (GET_Y_LINE (y),
449       GET_U_LINE (y), GET_V_LINE (y), src, width / 2);
450 }
451
452 #define PACK_Y444 GST_VIDEO_FORMAT_AYUV, unpack_Y444, 1, pack_Y444
453 static void
454 unpack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
455     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
456     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
457 {
458   video_orc_unpack_Y444 (dest, GET_Y_LINE (y), GET_U_LINE (y),
459       GET_V_LINE (y), width);
460 }
461
462 static void
463 pack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
464     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
465     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
466     gint y, gint width)
467 {
468   video_orc_pack_Y444 (GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), src,
469       width);
470 }
471
472 #define PACK_GBR GST_VIDEO_FORMAT_ARGB, unpack_GBR, 1, pack_GBR
473 static void
474 unpack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
475     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
476     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
477 {
478   video_orc_unpack_Y444 (dest, GET_R_LINE (y), GET_G_LINE (y),
479       GET_B_LINE (y), width);
480 }
481
482 static void
483 pack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
484     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
485     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
486     gint y, gint width)
487 {
488   video_orc_pack_Y444 (GET_R_LINE (y), GET_G_LINE (y), GET_B_LINE (y), src,
489       width);
490 }
491
492 #define PACK_GRAY8 GST_VIDEO_FORMAT_AYUV, unpack_GRAY8, 1, pack_GRAY8
493 static void
494 unpack_GRAY8 (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   video_orc_unpack_GRAY8 (dest, GET_LINE (y), width);
499 }
500
501 static void
502 pack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
503     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
504     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
505     gint y, gint width)
506 {
507   video_orc_pack_GRAY8 (GET_LINE (y), src, width);
508 }
509
510 #define PACK_GRAY16_BE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_BE, 1, pack_GRAY16_BE
511 static void
512 unpack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
513     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
514     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
515 {
516   int i;
517   const guint16 *s = GET_LINE (y);
518   guint16 *d = dest;
519
520   for (i = 0; i < width; i++) {
521     d[i * 4 + 0] = 0xffff;
522     d[i * 4 + 1] = GST_READ_UINT16_BE (s + i);
523     d[i * 4 + 2] = 0x8000;
524     d[i * 4 + 3] = 0x8000;
525   }
526 }
527
528 static void
529 pack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
530     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
531     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
532     gint y, gint width)
533 {
534   int i;
535   guint16 *d = GET_LINE (y);
536   const guint16 *s = src;
537
538   for (i = 0; i < width; i++) {
539     GST_WRITE_UINT16_BE (d + i, s[i * 4 + 1]);
540   }
541 }
542
543 #define PACK_GRAY16_LE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_LE, 1, pack_GRAY16_LE
544 static void
545 unpack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
546     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
547     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
548 {
549   int i;
550   const guint16 *s = GET_LINE (y);
551   guint16 *d = dest;
552
553   for (i = 0; i < width; i++) {
554     d[i * 4 + 0] = 0xffff;
555     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i);
556     d[i * 4 + 2] = 0x8000;
557     d[i * 4 + 3] = 0x8000;
558   }
559 }
560
561 static void
562 pack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
563     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
564     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
565     gint y, gint width)
566 {
567   int i;
568   guint16 *d = GET_LINE (y);
569   const guint16 *s = src;
570
571   for (i = 0; i < width; i++) {
572     GST_WRITE_UINT16_LE (d + i, s[i * 4 + 1]);
573   }
574 }
575
576 #define PACK_RGB16 GST_VIDEO_FORMAT_ARGB, unpack_RGB16, 1, pack_RGB16
577 static void
578 unpack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
579     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
580     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
581 {
582   int i;
583   const guint16 *s = GET_LINE (y);
584   guint8 *d = dest, r, g, b;
585
586   for (i = 0; i < width; i++) {
587     r = ((s[i] >> 11) & 0x1f) << 3;
588     g = ((s[i] >> 5) & 0x3f) << 2;
589     b = ((s[i]) & 0x1f) << 3;
590
591     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
592       r |= (r >> 5);
593       g |= (g >> 6);
594       b |= (b >> 5);
595     }
596
597     d[i * 4 + 0] = 0xff;
598     d[i * 4 + 1] = r;
599     d[i * 4 + 2] = g;
600     d[i * 4 + 3] = b;
601   }
602 }
603
604 static void
605 pack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
606     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
607     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
608     gint y, gint width)
609 {
610   int i;
611   guint16 *d = GET_LINE (y);
612   const guint8 *s = src;
613
614   for (i = 0; i < width; i++) {
615     d[i] = ((s[i * 4 + 1] >> 3) << 11) |
616         ((s[i * 4 + 2] >> 2) << 5) | (s[i * 4 + 3] >> 3);
617   }
618 }
619
620 #define PACK_BGR16 GST_VIDEO_FORMAT_ARGB, unpack_BGR16, 1, pack_BGR16
621 static void
622 unpack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
623     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
624     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
625 {
626   int i;
627   const guint16 *s = GET_LINE (y);
628   guint8 *d = dest, r, g, b;
629
630   for (i = 0; i < width; i++) {
631     b = ((s[i] >> 11) & 0x1f) << 3;
632     g = ((s[i] >> 5) & 0x3f) << 2;
633     r = ((s[i]) & 0x1f) << 3;
634
635     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
636       r |= (r >> 5);
637       g |= (g >> 6);
638       b |= (b >> 5);
639     }
640
641     d[i * 4 + 0] = 0xff;
642     d[i * 4 + 1] = r;
643     d[i * 4 + 2] = g;
644     d[i * 4 + 3] = b;
645   }
646 }
647
648 static void
649 pack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
650     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
651     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
652     gint y, gint width)
653 {
654   int i;
655   guint16 *d = GET_LINE (y);
656   const guint8 *s = src;
657
658   for (i = 0; i < width; i++) {
659     d[i] = ((s[i * 4 + 3] >> 3) << 11) |
660         ((s[i * 4 + 2] >> 2) << 5) | (s[i * 4 + 1] >> 3);
661   }
662 }
663
664 #define PACK_RGB15 GST_VIDEO_FORMAT_ARGB, unpack_RGB15, 1, pack_RGB15
665 static void
666 unpack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
667     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
668     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
669 {
670   int i;
671   const guint16 *s = GET_LINE (y);
672   guint8 *d = dest, r, g, b;
673
674   for (i = 0; i < width; i++) {
675     r = ((s[i] >> 10) & 0x1f) << 3;
676     g = ((s[i] >> 5) & 0x1f) << 3;
677     b = ((s[i]) & 0x1f) << 3;
678
679     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
680       r |= (r >> 5);
681       g |= (g >> 5);
682       b |= (b >> 5);
683     }
684
685     d[i * 4 + 0] = 0xff;
686     d[i * 4 + 1] = r;
687     d[i * 4 + 2] = g;
688     d[i * 4 + 3] = b;
689   }
690 }
691
692 static void
693 pack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
694     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
695     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
696     gint y, gint width)
697 {
698   int i;
699   guint16 *d = GET_LINE (y);
700   const guint8 *s = src;
701
702   for (i = 0; i < width; i++) {
703     d[i] = ((s[i * 4 + 1] >> 3) << 10) |
704         ((s[i * 4 + 2] >> 3) << 5) | (s[i * 4 + 3] >> 3);
705   }
706 }
707
708 #define PACK_BGR15 GST_VIDEO_FORMAT_ARGB, unpack_BGR15, 1, pack_BGR15
709 static void
710 unpack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
711     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
712     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
713 {
714   int i;
715   const guint16 *s = GET_LINE (y);
716   guint8 *d = dest, r, g, b;
717
718   for (i = 0; i < width; i++) {
719     b = ((s[i] >> 10) & 0x1f) << 3;
720     g = ((s[i] >> 5) & 0x1f) << 3;
721     r = ((s[i]) & 0x1f) << 3;
722
723     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
724       r |= (r >> 5);
725       g |= (g >> 5);
726       b |= (b >> 5);
727     }
728
729     d[i * 4 + 0] = 0xff;
730     d[i * 4 + 1] = r;
731     d[i * 4 + 2] = g;
732     d[i * 4 + 3] = b;
733   }
734 }
735
736 static void
737 pack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
738     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
739     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
740     gint y, gint width)
741 {
742   int i;
743   guint16 *d = GET_LINE (y);
744   const guint8 *s = src;
745
746   for (i = 0; i < width; i++) {
747     d[i] = ((s[i * 4 + 3] >> 3) << 10) |
748         ((s[i * 4 + 2] >> 3) << 5) | (s[i * 4 + 1] >> 3);
749   }
750 }
751
752 #define PACK_BGRA GST_VIDEO_FORMAT_ARGB, unpack_BGRA, 1, pack_BGRA
753 static void
754 unpack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
755     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
756     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
757 {
758   video_orc_unpack_BGRA (dest, GET_LINE (y), width);
759 }
760
761 static void
762 pack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
763     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
764     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
765     gint y, gint width)
766 {
767   video_orc_pack_BGRA (GET_LINE (y), src, width);
768 }
769
770 #define PACK_ABGR GST_VIDEO_FORMAT_ARGB, unpack_ABGR, 1, pack_ABGR
771 static void
772 unpack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
773     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
774     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
775 {
776   video_orc_unpack_ABGR (dest, GET_LINE (y), width);
777 }
778
779 static void
780 pack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
781     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
782     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
783     gint y, gint width)
784 {
785   video_orc_pack_ABGR (GET_LINE (y), src, width);
786 }
787
788 #define PACK_RGBA GST_VIDEO_FORMAT_ARGB, unpack_RGBA, 1, pack_RGBA
789 static void
790 unpack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
791     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
792     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
793 {
794   video_orc_unpack_RGBA (dest, GET_LINE (y), width);
795 }
796
797 static void
798 pack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
799     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
800     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
801     gint y, gint width)
802 {
803   video_orc_pack_RGBA (GET_LINE (y), src, width);
804 }
805
806 #define PACK_RGB GST_VIDEO_FORMAT_ARGB, unpack_RGB, 1, pack_RGB
807 static void
808 unpack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
809     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
810     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
811 {
812   int i;
813   const guint8 *s = GET_LINE (y);
814   guint8 *d = dest;
815
816   for (i = 0; i < width; i++) {
817     d[i * 4 + 0] = 0xff;
818     d[i * 4 + 1] = s[i * 3 + 0];
819     d[i * 4 + 2] = s[i * 3 + 1];
820     d[i * 4 + 3] = s[i * 3 + 2];
821   }
822 }
823
824 static void
825 pack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
826     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
827     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
828     gint y, gint width)
829 {
830   int i;
831   guint8 *d = GET_LINE (y);
832   const guint8 *s = src;
833
834   for (i = 0; i < width; i++) {
835     d[i * 3 + 0] = s[i * 4 + 1];
836     d[i * 3 + 1] = s[i * 4 + 2];
837     d[i * 3 + 2] = s[i * 4 + 3];
838   }
839 }
840
841 #define PACK_BGR GST_VIDEO_FORMAT_ARGB, unpack_BGR, 1, pack_BGR
842 static void
843 unpack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
844     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
845     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
846 {
847   int i;
848   const guint8 *s = GET_LINE (y);
849   guint8 *d = dest;
850
851   for (i = 0; i < width; i++) {
852     d[i * 4 + 0] = 0xff;
853     d[i * 4 + 1] = s[i * 3 + 2];
854     d[i * 4 + 2] = s[i * 3 + 1];
855     d[i * 4 + 3] = s[i * 3 + 0];
856   }
857 }
858
859 static void
860 pack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
861     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
862     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
863     gint y, gint width)
864 {
865   int i;
866   guint8 *d = GET_LINE (y);
867   const guint8 *s = src;
868
869   for (i = 0; i < width; i++) {
870     d[i * 3 + 0] = s[i * 4 + 3];
871     d[i * 3 + 1] = s[i * 4 + 2];
872     d[i * 3 + 2] = s[i * 4 + 1];
873   }
874 }
875
876 #define PACK_NV12 GST_VIDEO_FORMAT_AYUV, unpack_NV12, 1, pack_NV12
877 static void
878 unpack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
879     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
880     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
881 {
882   gint uv = GET_UV_420 (y, flags);
883
884   video_orc_unpack_NV12 (dest,
885       GET_PLANE_LINE (0, y), GET_PLANE_LINE (1, uv), width / 2);
886 }
887
888 static void
889 pack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
890     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
891     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
892     gint y, gint width)
893 {
894   gint uv = GET_UV_420 (y, flags);
895
896   video_orc_pack_NV12 (GET_PLANE_LINE (0, y), GET_PLANE_LINE (1, uv),
897       src, width / 2);
898 }
899
900 #define PACK_NV21 GST_VIDEO_FORMAT_AYUV, unpack_NV21, 1, pack_NV21
901 static void
902 unpack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
903     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
904     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
905 {
906   gint uv = GET_UV_420 (y, flags);
907
908   video_orc_unpack_NV21 (dest,
909       GET_PLANE_LINE (0, y), GET_PLANE_LINE (1, uv), width / 2);
910 }
911
912 static void
913 pack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
914     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
915     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
916     gint y, gint width)
917 {
918   gint uv = GET_UV_420 (y, flags);
919
920   video_orc_pack_NV21 (GET_PLANE_LINE (0, y),
921       GET_PLANE_LINE (1, uv), src, width / 2);
922 }
923
924 #define PACK_UYVP GST_VIDEO_FORMAT_AYUV64, unpack_UYVP, 1, pack_UYVP
925 static void
926 unpack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
927     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
928     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
929 {
930   int i;
931   const guint8 *s = GET_LINE (y);
932   guint16 *d = dest;
933
934   for (i = 0; i < width; i += 2) {
935     guint16 y0, y1;
936     guint16 u0;
937     guint16 v0;
938
939     u0 = ((s[(i / 2) * 5 + 0] << 2) | (s[(i / 2) * 5 + 1] >> 6)) << 6;
940     y0 = (((s[(i / 2) * 5 + 1] & 0x3f) << 4) | (s[(i / 2) * 5 + 2] >> 4)) << 6;
941     v0 = (((s[(i / 2) * 5 + 2] & 0x0f) << 6) | (s[(i / 2) * 5 + 3] >> 2)) << 6;
942     y1 = (((s[(i / 2) * 5 + 3] & 0x03) << 8) | s[(i / 2) * 5 + 4]) << 6;
943
944     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
945       y0 |= (y0 >> 4);
946       y1 |= (y1 >> 4);
947       u0 |= (u0 >> 4);
948       v0 |= (v0 >> 4);
949     }
950
951     d[i * 4 + 0] = 0xffff;
952     d[i * 4 + 1] = y0;
953     d[i * 4 + 2] = u0;
954     d[i * 4 + 3] = v0;
955
956     d[i * 4 + 4] = 0xffff;
957     d[i * 4 + 5] = y1;
958     d[i * 4 + 6] = u0;
959     d[i * 4 + 7] = v0;
960   }
961 }
962
963 static void
964 pack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
965     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
966     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
967     gint y, gint width)
968 {
969   int i;
970   guint8 *d = GET_LINE (y);
971   const guint16 *s = src;
972
973   for (i = 0; i < width; i += 2) {
974     guint16 y0, y1;
975     guint16 u0;
976     guint16 v0;
977
978     y0 = s[4 * (i + 0) + 1];
979     y1 = s[4 * (i + 1) + 1];
980     u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 1;
981     v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 1;
982
983     d[(i / 2) * 5 + 0] = u0 >> 8;
984     d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10;
985     d[(i / 2) * 5 + 2] = ((y0 & 0x3c0) >> 2) | (v0 >> 12);
986     d[(i / 2) * 5 + 3] = ((v0 & 0xfc0) >> 4) | (y1 >> 14);
987     d[(i / 2) * 5 + 4] = (y1 >> 6);
988   }
989 }
990
991 #define PACK_A420 GST_VIDEO_FORMAT_AYUV, unpack_A420, 1, pack_A420
992 static void
993 unpack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
994     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
995     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
996 {
997   gint uv = GET_UV_420 (y, flags);
998
999   video_orc_unpack_A420 (dest, GET_Y_LINE (y), GET_U_LINE (uv),
1000       GET_V_LINE (uv), GET_A_LINE (y), width);
1001 }
1002
1003 static void
1004 pack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1005     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1006     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1007     gint y, gint width)
1008 {
1009   gint uv = GET_UV_420 (y, flags);
1010
1011   video_orc_pack_A420 (GET_Y_LINE (y), GET_U_LINE (uv), GET_V_LINE (uv),
1012       GET_A_LINE (y), src, width / 2);
1013 }
1014
1015 #define PACK_RGB8P GST_VIDEO_FORMAT_ARGB, unpack_RGB8P, 1, pack_RGB8P
1016 static void
1017 unpack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1018     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1019     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1020 {
1021   int i;
1022   const guint8 *s = GET_LINE (y);
1023   const guint32 *p = data[1];
1024   guint8 *d = dest;
1025
1026   for (i = 0; i < width; i++) {
1027     guint32 v = p[s[i]];
1028     d[i * 4 + 0] = (v >> 24) & 0xff;
1029     d[i * 4 + 1] = (v >> 16) & 0xff;
1030     d[i * 4 + 2] = (v >> 8) & 0xff;
1031     d[i * 4 + 3] = (v) & 0xff;
1032   }
1033 }
1034
1035 static const guint32 std_palette_RGB8P[] = {
1036   0xff000000, 0xff000033, 0xff000066, 0xff000099, 0xff0000cc, 0xff0000ff,
1037   0xff003300, 0xff003333, 0xff003366, 0xff003399, 0xff0033cc, 0xff0033ff,
1038   0xff006600, 0xff006633, 0xff006666, 0xff006699, 0xff0066cc, 0xff0066ff,
1039   0xff009900, 0xff009933, 0xff009966, 0xff009999, 0xff0099cc, 0xff0099ff,
1040   0xff00cc00, 0xff00cc33, 0xff00cc66, 0xff00cc99, 0xff00cccc, 0xff00ccff,
1041   0xff00ff00, 0xff00ff33, 0xff00ff66, 0xff00ff99, 0xff00ffcc, 0xff00ffff,
1042   0xff330000, 0xff330033, 0xff330066, 0xff330099, 0xff3300cc, 0xff3300ff,
1043   0xff333300, 0xff333333, 0xff333366, 0xff333399, 0xff3333cc, 0xff3333ff,
1044   0xff336600, 0xff336633, 0xff336666, 0xff336699, 0xff3366cc, 0xff3366ff,
1045   0xff339900, 0xff339933, 0xff339966, 0xff339999, 0xff3399cc, 0xff3399ff,
1046   0xff33cc00, 0xff33cc33, 0xff33cc66, 0xff33cc99, 0xff33cccc, 0xff33ccff,
1047   0xff33ff00, 0xff33ff33, 0xff33ff66, 0xff33ff99, 0xff33ffcc, 0xff33ffff,
1048   0xff660000, 0xff660033, 0xff660066, 0xff660099, 0xff6600cc, 0xff6600ff,
1049   0xff663300, 0xff663333, 0xff663366, 0xff663399, 0xff6633cc, 0xff6633ff,
1050   0xff666600, 0xff666633, 0xff666666, 0xff666699, 0xff6666cc, 0xff6666ff,
1051   0xff669900, 0xff669933, 0xff669966, 0xff669999, 0xff6699cc, 0xff6699ff,
1052   0xff66cc00, 0xff66cc33, 0xff66cc66, 0xff66cc99, 0xff66cccc, 0xff66ccff,
1053   0xff66ff00, 0xff66ff33, 0xff66ff66, 0xff66ff99, 0xff66ffcc, 0xff66ffff,
1054   0xff990000, 0xff990033, 0xff990066, 0xff990099, 0xff9900cc, 0xff9900ff,
1055   0xff993300, 0xff993333, 0xff993366, 0xff993399, 0xff9933cc, 0xff9933ff,
1056   0xff996600, 0xff996633, 0xff996666, 0xff996699, 0xff9966cc, 0xff9966ff,
1057   0xff999900, 0xff999933, 0xff999966, 0xff999999, 0xff9999cc, 0xff9999ff,
1058   0xff99cc00, 0xff99cc33, 0xff99cc66, 0xff99cc99, 0xff99cccc, 0xff99ccff,
1059   0xff99ff00, 0xff99ff33, 0xff99ff66, 0xff99ff99, 0xff99ffcc, 0xff99ffff,
1060   0xffcc0000, 0xffcc0033, 0xffcc0066, 0xffcc0099, 0xffcc00cc, 0xffcc00ff,
1061   0xffcc3300, 0xffcc3333, 0xffcc3366, 0xffcc3399, 0xffcc33cc, 0xffcc33ff,
1062   0xffcc6600, 0xffcc6633, 0xffcc6666, 0xffcc6699, 0xffcc66cc, 0xffcc66ff,
1063   0xffcc9900, 0xffcc9933, 0xffcc9966, 0xffcc9999, 0xffcc99cc, 0xffcc99ff,
1064   0xffcccc00, 0xffcccc33, 0xffcccc66, 0xffcccc99, 0xffcccccc, 0xffccccff,
1065   0xffccff00, 0xffccff33, 0xffccff66, 0xffccff99, 0xffccffcc, 0xffccffff,
1066   0xffff0000, 0xffff0033, 0xffff0066, 0xffff0099, 0xffff00cc, 0xffff00ff,
1067   0xffff3300, 0xffff3333, 0xffff3366, 0xffff3399, 0xffff33cc, 0xffff33ff,
1068   0xffff6600, 0xffff6633, 0xffff6666, 0xffff6699, 0xffff66cc, 0xffff66ff,
1069   0xffff9900, 0xffff9933, 0xffff9966, 0xffff9999, 0xffff99cc, 0xffff99ff,
1070   0xffffcc00, 0xffffcc33, 0xffffcc66, 0xffffcc99, 0xffffcccc, 0xffffccff,
1071   0xffffff00, 0xffffff33, 0xffffff66, 0xffffff99, 0xffffffcc, 0xffffffff,
1072   0x00000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1073   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1074   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1075   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1076   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1077   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1078   0xff000000, 0xff000000, 0xff000000, 0xff000000
1079 };
1080
1081 static void
1082 pack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1083     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1084     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1085     gint y, gint width)
1086 {
1087   int i;
1088   guint8 *d = GET_LINE (y);
1089   const guint8 *s = src;
1090
1091   /* Use our poor man's palette, taken from ffmpegcolorspace too */
1092   for (i = 0; i < width; i++) {
1093     /* crude approximation for alpha ! */
1094     if (s[i * 4 + 0] < 0x80)
1095       d[i] = 6 * 6 * 6;
1096     else
1097       d[i] =
1098           ((((s[i * 4 + 1]) / 47) % 6) * 6 * 6 + (((s[i * 4 +
1099                           2]) / 47) % 6) * 6 + (((s[i * 4 + 3]) / 47) % 6));
1100   }
1101 }
1102
1103 #define PACK_410 GST_VIDEO_FORMAT_AYUV, unpack_410, 1, pack_410
1104 static void
1105 unpack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1106     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1107     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1108 {
1109   gint uv = GET_UV_410 (y, flags);
1110
1111   video_orc_unpack_YUV9 (dest,
1112       GET_Y_LINE (y), GET_U_LINE (uv), GET_V_LINE (uv), width / 2);
1113 }
1114
1115 static void
1116 pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1117     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1118     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1119     gint y, gint width)
1120 {
1121   int i;
1122   gint uv = GET_UV_410 (y, flags);
1123   guint8 *destY = GET_Y_LINE (y);
1124   guint8 *destU = GET_U_LINE (uv);
1125   guint8 *destV = GET_V_LINE (uv);
1126   const guint8 *s = src;
1127
1128   for (i = 0; i < width - 3; i += 4) {
1129     destY[i] = s[i * 4 + 1];
1130     destY[i + 1] = s[i * 4 + 5];
1131     destY[i + 2] = s[i * 4 + 9];
1132     destY[i + 3] = s[i * 4 + 13];
1133     if (y % 4 == 0) {
1134       destU[i >> 2] =
1135           (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2;
1136       destV[i >> 2] =
1137           (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2;
1138     }
1139   }
1140
1141   if (i == width - 3) {
1142     destY[i] = s[i * 4 + 1];
1143     destY[i + 1] = s[i * 4 + 5];
1144     destY[i + 2] = s[i * 4 + 9];
1145     if (y % 4 == 0) {
1146       destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3;
1147       destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3;
1148     }
1149   } else if (i == width - 2) {
1150     destY[i] = s[i * 4 + 1];
1151     destY[i + 1] = s[i * 4 + 5];
1152     if (y % 4 == 0) {
1153       destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1;
1154       destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1;
1155     }
1156   } else if (i == width - 1) {
1157     destY[i] = s[i * 4 + 1];
1158     destU[i >> 2] = s[i * 4 + 2];
1159     destV[i >> 2] = s[i * 4 + 3];
1160   }
1161 }
1162
1163 #define PACK_IYU1 GST_VIDEO_FORMAT_AYUV, unpack_IYU1, 1, pack_IYU1
1164 static void
1165 unpack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1166     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1167     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1168 {
1169   int i;
1170   const guint8 *s = GET_LINE (y);
1171   guint8 *d = dest;
1172
1173   for (i = 0; i < width - 3; i += 4) {
1174     d[i * 4 + 0] = 0xff;
1175     d[i * 4 + 4] = 0xff;
1176     d[i * 4 + 8] = 0xff;
1177     d[i * 4 + 12] = 0xff;
1178     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1179     d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
1180     d[i * 4 + 9] = s[(i >> 2) * 6 + 4];
1181     d[i * 4 + 13] = s[(i >> 2) * 6 + 5];
1182     d[i * 4 + 2] = d[i * 4 + 6] = d[i * 4 + 10] = d[i * 4 + 14] =
1183         s[(i >> 2) * 6 + 0];
1184     d[i * 4 + 3] = d[i * 4 + 7] = d[i * 4 + 11] = d[i * 4 + 15] =
1185         s[(i >> 2) * 6 + 3];
1186   }
1187
1188   if (i == width - 3) {
1189     d[i * 4 + 0] = 0xff;
1190     d[i * 4 + 4] = 0xff;
1191     d[i * 4 + 8] = 0xff;
1192     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1193     d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
1194     d[i * 4 + 9] = s[(i >> 2) * 6 + 4];
1195     d[i * 4 + 2] = d[i * 4 + 6] = d[i * 4 + 10] = s[(i >> 2) * 6 + 0];
1196     d[i * 4 + 3] = d[i * 4 + 7] = d[i * 4 + 11] = s[(i >> 2) * 6 + 3];
1197   } else if (i == width - 2) {
1198     d[i * 4 + 0] = 0xff;
1199     d[i * 4 + 4] = 0xff;
1200     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1201     d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
1202     d[i * 4 + 2] = d[i * 4 + 6] = s[(i >> 2) * 6 + 0];
1203     d[i * 4 + 3] = d[i * 4 + 7] = s[(i >> 2) * 6 + 3];
1204   } else if (i == width - 1) {
1205     d[i * 4 + 0] = 0xff;
1206     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
1207     d[i * 4 + 2] = s[(i >> 2) * 6 + 0];
1208     d[i * 4 + 3] = s[(i >> 2) * 6 + 3];
1209   }
1210 }
1211
1212 static void
1213 pack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1214     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1215     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1216     gint y, gint width)
1217 {
1218   int i;
1219   guint8 *d = GET_LINE (y);
1220   const guint8 *s = src;
1221
1222   for (i = 0; i < width - 3; i += 4) {
1223     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1224     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
1225     d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
1226     d[(i >> 2) * 6 + 5] = s[i * 4 + 13];
1227     d[(i >> 2) * 6 + 0] =
1228         (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2;
1229     d[(i >> 2) * 6 + 3] =
1230         (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2;
1231   }
1232
1233   if (i == width - 3) {
1234     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1235     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
1236     d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
1237     d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3;
1238     d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3;
1239   } else if (i == width - 2) {
1240     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1241     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
1242     d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1;
1243     d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1;
1244   } else if (i == width - 1) {
1245     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
1246     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
1247     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
1248   }
1249 }
1250
1251 #define PACK_ARGB64 GST_VIDEO_FORMAT_ARGB64, unpack_copy8, 1, pack_copy8
1252 #define PACK_AYUV64 GST_VIDEO_FORMAT_AYUV64, unpack_copy8, 1, pack_copy8
1253 static void
1254 unpack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1255     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1256     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1257 {
1258   memcpy (dest, GET_LINE (y), width * 8);
1259 }
1260
1261 static void
1262 pack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1263     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1264     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1265     gint y, gint width)
1266 {
1267   memcpy (GET_LINE (y), src, width * 8);
1268 }
1269
1270 #define PACK_r210 GST_VIDEO_FORMAT_ARGB64, unpack_r210, 1, pack_r210
1271 static void
1272 unpack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1273     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1274     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1275 {
1276   int i;
1277   const guint8 *s = GET_LINE (y);
1278   guint16 *d = dest, R, G, B;
1279
1280   for (i = 0; i < width; i++) {
1281     guint32 x = GST_READ_UINT32_BE (s + i * 4);
1282
1283     R = ((x >> 14) & 0xffc0);
1284     G = ((x >> 4) & 0xffc0);
1285     B = ((x << 6) & 0xffc0);
1286
1287     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1288       R |= (R >> 10);
1289       G |= (G >> 10);
1290       B |= (B >> 10);
1291     }
1292
1293     d[i * 4 + 0] = 0xffff;
1294     d[i * 4 + 1] = R;
1295     d[i * 4 + 2] = G;
1296     d[i * 4 + 3] = B;
1297   }
1298 }
1299
1300 static void
1301 pack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1302     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1303     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1304     gint y, gint width)
1305 {
1306   int i;
1307   guint8 *d = GET_LINE (y);
1308   const guint16 *s = src;
1309
1310   for (i = 0; i < width; i++) {
1311     guint32 x = 0;
1312     x |= (s[i * 4 + 1] & 0xffc0) << 14;
1313     x |= (s[i * 4 + 2] & 0xffc0) << 4;
1314     x |= (s[i * 4 + 3] & 0xffc0) >> 6;
1315     GST_WRITE_UINT32_BE (d + i * 4, x);
1316   }
1317 }
1318
1319 #define PACK_GBR_10LE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10LE, 1, pack_GBR_10LE
1320 static void
1321 unpack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1322     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1323     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1324 {
1325   int i;
1326   guint16 *srcG = GET_G_LINE (y);
1327   guint16 *srcB = GET_B_LINE (y);
1328   guint16 *srcR = GET_R_LINE (y);
1329   guint16 *d = dest, G, B, R;
1330
1331   for (i = 0; i < width; i++) {
1332     G = GST_READ_UINT16_LE (srcG + i) << 6;
1333     B = GST_READ_UINT16_LE (srcB + i) << 6;
1334     R = GST_READ_UINT16_LE (srcR + i) << 6;
1335
1336     d[i * 4 + 0] = 0xffff;
1337     d[i * 4 + 1] = R;
1338     d[i * 4 + 2] = G;
1339     d[i * 4 + 3] = B;
1340   }
1341 }
1342
1343 static void
1344 pack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1345     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1346     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1347     gint y, gint width)
1348 {
1349   int i;
1350   guint16 *destG = GET_G_LINE (y);
1351   guint16 *destB = GET_B_LINE (y);
1352   guint16 *destR = GET_R_LINE (y);
1353   guint16 G, B, R;
1354   const guint16 *s = src;
1355
1356   for (i = 0; i < width; i++) {
1357     G = (s[i * 4 + 2]) >> 6;
1358     B = (s[i * 4 + 3]) >> 6;
1359     R = (s[i * 4 + 1]) >> 6;
1360
1361     GST_WRITE_UINT16_LE (destG + i, G);
1362     GST_WRITE_UINT16_LE (destB + i, B);
1363     GST_WRITE_UINT16_LE (destR + i, R);
1364   }
1365 }
1366
1367 #define PACK_GBR_10BE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10BE, 1, pack_GBR_10BE
1368 static void
1369 unpack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1370     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1371     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1372 {
1373   int i;
1374   guint16 *srcG = GET_G_LINE (y);
1375   guint16 *srcB = GET_B_LINE (y);
1376   guint16 *srcR = GET_R_LINE (y);
1377   guint16 *d = dest, G, B, R;
1378
1379   for (i = 0; i < width; i++) {
1380     G = GST_READ_UINT16_BE (srcG + i) << 6;
1381     B = GST_READ_UINT16_BE (srcB + i) << 6;
1382     R = GST_READ_UINT16_BE (srcR + i) << 6;
1383
1384     d[i * 4 + 0] = 0xffff;
1385     d[i * 4 + 1] = R;
1386     d[i * 4 + 2] = G;
1387     d[i * 4 + 3] = B;
1388   }
1389 }
1390
1391 static void
1392 pack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1393     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1394     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1395     gint y, gint width)
1396 {
1397   int i;
1398   guint16 *destG = GET_G_LINE (y);
1399   guint16 *destB = GET_B_LINE (y);
1400   guint16 *destR = GET_R_LINE (y);
1401   guint16 G, B, R;
1402   const guint16 *s = src;
1403
1404   for (i = 0; i < width; i++) {
1405     G = s[i * 4 + 2] >> 6;
1406     B = s[i * 4 + 3] >> 6;
1407     R = s[i * 4 + 1] >> 6;
1408
1409     GST_WRITE_UINT16_BE (destG + i, G);
1410     GST_WRITE_UINT16_BE (destB + i, B);
1411     GST_WRITE_UINT16_BE (destR + i, R);
1412   }
1413 }
1414
1415 #define PACK_Y444_10LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10LE, 1, pack_Y444_10LE
1416 static void
1417 unpack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1418     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1419     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1420 {
1421   int i;
1422   guint16 *srcY = GET_Y_LINE (y);
1423   guint16 *srcU = GET_U_LINE (y);
1424   guint16 *srcV = GET_V_LINE (y);
1425   guint16 *d = dest, Y, U, V;
1426
1427   for (i = 0; i < width; i++) {
1428     Y = GST_READ_UINT16_LE (srcY + i) << 6;
1429     U = GST_READ_UINT16_LE (srcU + i) << 6;
1430     V = GST_READ_UINT16_LE (srcV + i) << 6;
1431
1432     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1433       Y |= (Y >> 10);
1434       U |= (U >> 10);
1435       V |= (V >> 10);
1436     }
1437
1438     d[i * 4 + 0] = 0xffff;
1439     d[i * 4 + 1] = Y;
1440     d[i * 4 + 2] = U;
1441     d[i * 4 + 3] = V;
1442   }
1443 }
1444
1445 static void
1446 pack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1447     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1448     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1449     gint y, gint width)
1450 {
1451   int i;
1452   guint16 *destY = GET_Y_LINE (y);
1453   guint16 *destU = GET_U_LINE (y);
1454   guint16 *destV = GET_V_LINE (y);
1455   guint16 Y, U, V;
1456   const guint16 *s = src;
1457
1458   for (i = 0; i < width; i++) {
1459     Y = (s[i * 4 + 1]) >> 6;
1460     U = (s[i * 4 + 2]) >> 6;
1461     V = (s[i * 4 + 3]) >> 6;
1462
1463     GST_WRITE_UINT16_LE (destY + i, Y);
1464     GST_WRITE_UINT16_LE (destU + i, U);
1465     GST_WRITE_UINT16_LE (destV + i, V);
1466   }
1467 }
1468
1469 #define PACK_Y444_10BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10BE, 1, pack_Y444_10BE
1470 static void
1471 unpack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1472     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1473     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1474 {
1475   int i;
1476   guint16 *srcY = GET_Y_LINE (y);
1477   guint16 *srcU = GET_U_LINE (y);
1478   guint16 *srcV = GET_V_LINE (y);
1479   guint16 *d = dest, Y, U, V;
1480
1481   for (i = 0; i < width; i++) {
1482     Y = GST_READ_UINT16_BE (srcY + i) << 6;
1483     U = GST_READ_UINT16_BE (srcU + i) << 6;
1484     V = GST_READ_UINT16_BE (srcV + i) << 6;
1485
1486     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1487       Y |= (Y >> 10);
1488       U |= (U >> 10);
1489       V |= (V >> 10);
1490     }
1491
1492     d[i * 4 + 0] = 0xffff;
1493     d[i * 4 + 1] = Y;
1494     d[i * 4 + 2] = U;
1495     d[i * 4 + 3] = V;
1496   }
1497 }
1498
1499 static void
1500 pack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1501     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1502     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1503     gint y, gint width)
1504 {
1505   int i;
1506   guint16 *destY = GET_Y_LINE (y);
1507   guint16 *destU = GET_U_LINE (y);
1508   guint16 *destV = GET_V_LINE (y);
1509   guint16 Y, U, V;
1510   const guint16 *s = src;
1511
1512   for (i = 0; i < width; i++) {
1513     Y = s[i * 4 + 1] >> 6;
1514     U = s[i * 4 + 2] >> 6;
1515     V = s[i * 4 + 3] >> 6;
1516
1517     GST_WRITE_UINT16_BE (destY + i, Y);
1518     GST_WRITE_UINT16_BE (destU + i, U);
1519     GST_WRITE_UINT16_BE (destV + i, V);
1520   }
1521 }
1522
1523 #define PACK_I420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10LE, 1, pack_I420_10LE
1524 static void
1525 unpack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1526     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1527     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1528 {
1529   int i;
1530   gint uv = GET_UV_420 (y, flags);
1531   guint16 *srcY = GET_Y_LINE (y);
1532   guint16 *srcU = GET_U_LINE (uv);
1533   guint16 *srcV = GET_V_LINE (uv);
1534   guint16 *d = dest, Y, U, V;
1535
1536   for (i = 0; i < width; i++) {
1537     Y = GST_READ_UINT16_LE (srcY + i) << 6;
1538     U = GST_READ_UINT16_LE (srcU + (i >> 1)) << 6;
1539     V = GST_READ_UINT16_LE (srcV + (i >> 1)) << 6;
1540
1541     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1542       Y |= (Y >> 10);
1543       U |= (U >> 10);
1544       V |= (V >> 10);
1545     }
1546
1547     d[i * 4 + 0] = 0xffff;
1548     d[i * 4 + 1] = Y;
1549     d[i * 4 + 2] = U;
1550     d[i * 4 + 3] = V;
1551   }
1552 }
1553
1554 static void
1555 pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1556     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1557     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1558     gint y, gint width)
1559 {
1560   int i;
1561   gint uv = GET_UV_420 (y, flags);
1562   guint16 *destY = GET_Y_LINE (y);
1563   guint16 *destU = GET_U_LINE (uv);
1564   guint16 *destV = GET_V_LINE (uv);
1565   guint16 Y0, Y1, U, V;
1566   const guint16 *s = src;
1567
1568   for (i = 0; i < width - 1; i += 2) {
1569     Y0 = (s[i * 4 + 1]) >> 6;
1570     Y1 = (s[i * 4 + 5]) >> 6;
1571     U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6;
1572     V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6;
1573
1574     GST_WRITE_UINT16_LE (destY + i + 0, Y0);
1575     GST_WRITE_UINT16_LE (destY + i + 1, Y1);
1576     GST_WRITE_UINT16_LE (destU + (i >> 1), U);
1577     GST_WRITE_UINT16_LE (destV + (i >> 1), V);
1578   }
1579   if (i == width - 1) {
1580     Y0 = s[i * 4 + 1] >> 6;
1581     U = s[i * 4 + 2] >> 6;
1582     V = s[i * 4 + 3] >> 6;
1583
1584     GST_WRITE_UINT16_LE (destY + i, Y0);
1585     GST_WRITE_UINT16_LE (destU + (i >> 1), U);
1586     GST_WRITE_UINT16_LE (destV + (i >> 1), V);
1587   }
1588 }
1589
1590 #define PACK_I420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10BE, 1, pack_I420_10BE
1591 static void
1592 unpack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1593     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1594     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1595 {
1596   int i;
1597   gint uv = GET_UV_420 (y, flags);
1598   guint16 *srcY = GET_Y_LINE (y);
1599   guint16 *srcU = GET_U_LINE (uv);
1600   guint16 *srcV = GET_V_LINE (uv);
1601   guint16 *d = dest, Y, U, V;
1602
1603   for (i = 0; i < width; i++) {
1604     Y = GST_READ_UINT16_BE (srcY + i) << 6;
1605     U = GST_READ_UINT16_BE (srcU + (i >> 1)) << 6;
1606     V = GST_READ_UINT16_BE (srcV + (i >> 1)) << 6;
1607
1608     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1609       Y |= (Y >> 10);
1610       U |= (U >> 10);
1611       V |= (V >> 10);
1612     }
1613
1614     d[i * 4 + 0] = 0xffff;
1615     d[i * 4 + 1] = Y;
1616     d[i * 4 + 2] = U;
1617     d[i * 4 + 3] = V;
1618   }
1619 }
1620
1621 static void
1622 pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1623     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1624     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1625     gint y, gint width)
1626 {
1627   int i;
1628   gint uv = GET_UV_420 (y, flags);
1629   guint16 *destY = GET_Y_LINE (y);
1630   guint16 *destU = GET_U_LINE (uv);
1631   guint16 *destV = GET_V_LINE (uv);
1632   guint16 Y0, Y1, U, V;
1633   const guint16 *s = src;
1634
1635   for (i = 0; i < width - 1; i += 2) {
1636     Y0 = s[i * 4 + 1] >> 6;
1637     Y1 = s[i * 4 + 5] >> 6;
1638     U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6;
1639     V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6;
1640
1641     GST_WRITE_UINT16_BE (destY + i + 0, Y0);
1642     GST_WRITE_UINT16_BE (destY + i + 1, Y1);
1643     GST_WRITE_UINT16_BE (destU + (i >> 1), U);
1644     GST_WRITE_UINT16_BE (destV + (i >> 1), V);
1645   }
1646   if (i == width - 1) {
1647     Y0 = s[i * 4 + 1] >> 6;
1648     U = s[i * 4 + 2] >> 6;
1649     V = s[i * 4 + 3] >> 6;
1650
1651     GST_WRITE_UINT16_BE (destY + i, Y0);
1652     GST_WRITE_UINT16_BE (destU + (i >> 1), U);
1653     GST_WRITE_UINT16_BE (destV + (i >> 1), V);
1654   }
1655 }
1656
1657 #define PACK_I422_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10LE, 1, pack_I422_10LE
1658 static void
1659 unpack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1660     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1661     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1662 {
1663   int i;
1664   guint16 *srcY = GET_Y_LINE (y);
1665   guint16 *srcU = GET_U_LINE (y);
1666   guint16 *srcV = GET_V_LINE (y);
1667   guint16 *d = dest, Y, U, V;
1668
1669   for (i = 0; i < width; i++) {
1670     Y = GST_READ_UINT16_LE (srcY + i) << 6;
1671     U = GST_READ_UINT16_LE (srcU + (i >> 1)) << 6;
1672     V = GST_READ_UINT16_LE (srcV + (i >> 1)) << 6;
1673
1674     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1675       Y |= (Y >> 10);
1676       U |= (U >> 10);
1677       V |= (V >> 10);
1678     }
1679
1680     d[i * 4 + 0] = 0xffff;
1681     d[i * 4 + 1] = Y;
1682     d[i * 4 + 2] = U;
1683     d[i * 4 + 3] = V;
1684   }
1685 }
1686
1687 static void
1688 pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1689     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1690     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1691     gint y, gint width)
1692 {
1693   int i;
1694   guint16 *destY = GET_Y_LINE (y);
1695   guint16 *destU = GET_U_LINE (y);
1696   guint16 *destV = GET_V_LINE (y);
1697   guint16 Y0, Y1, U, V;
1698   const guint16 *s = src;
1699
1700   for (i = 0; i < width - 1; i += 2) {
1701     Y0 = (s[i * 4 + 1]) >> 6;
1702     Y1 = (s[i * 4 + 5]) >> 6;
1703     U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6;
1704     V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6;
1705
1706     GST_WRITE_UINT16_LE (destY + i + 0, Y0);
1707     GST_WRITE_UINT16_LE (destY + i + 1, Y1);
1708     GST_WRITE_UINT16_LE (destU + (i >> 1), U);
1709     GST_WRITE_UINT16_LE (destV + (i >> 1), V);
1710   }
1711   if (i == width - 1) {
1712     Y0 = s[i * 4 + 1] >> 6;
1713     U = s[i * 4 + 2] >> 6;
1714     V = s[i * 4 + 3] >> 6;
1715
1716     GST_WRITE_UINT16_LE (destY + i, Y0);
1717     GST_WRITE_UINT16_LE (destU + (i >> 1), U);
1718     GST_WRITE_UINT16_LE (destV + (i >> 1), V);
1719   }
1720 }
1721
1722 #define PACK_I422_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10BE, 1, pack_I422_10BE
1723 static void
1724 unpack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1725     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1726     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1727 {
1728   int i;
1729   guint16 *srcY = GET_Y_LINE (y);
1730   guint16 *srcU = GET_U_LINE (y);
1731   guint16 *srcV = GET_V_LINE (y);
1732   guint16 *d = dest, Y, U, V;
1733
1734   for (i = 0; i < width; i++) {
1735     Y = GST_READ_UINT16_BE (srcY + i) << 6;
1736     U = GST_READ_UINT16_BE (srcU + (i >> 1)) << 6;
1737     V = GST_READ_UINT16_BE (srcV + (i >> 1)) << 6;
1738
1739     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1740       Y |= (Y >> 10);
1741       U |= (U >> 10);
1742       V |= (V >> 10);
1743     }
1744
1745     d[i * 4 + 0] = 0xffff;
1746     d[i * 4 + 1] = Y;
1747     d[i * 4 + 2] = U;
1748     d[i * 4 + 3] = V;
1749   }
1750 }
1751
1752 static void
1753 pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1754     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1755     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1756     gint y, gint width)
1757 {
1758   int i;
1759   guint16 *destY = GET_Y_LINE (y);
1760   guint16 *destU = GET_U_LINE (y);
1761   guint16 *destV = GET_V_LINE (y);
1762   guint16 Y0, Y1, U, V;
1763   const guint16 *s = src;
1764
1765   for (i = 0; i < width - 1; i += 2) {
1766     Y0 = s[i * 4 + 1] >> 6;
1767     Y1 = s[i * 4 + 5] >> 6;
1768     U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6;
1769     V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6;
1770
1771     GST_WRITE_UINT16_BE (destY + i + 0, Y0);
1772     GST_WRITE_UINT16_BE (destY + i + 1, Y1);
1773     GST_WRITE_UINT16_BE (destU + (i >> 1), U);
1774     GST_WRITE_UINT16_BE (destV + (i >> 1), V);
1775   }
1776   if (i == width - 1) {
1777     Y0 = s[i * 4 + 1] >> 6;
1778     U = s[i * 4 + 2] >> 6;
1779     V = s[i * 4 + 3] >> 6;
1780
1781     GST_WRITE_UINT16_BE (destY + i, Y0);
1782     GST_WRITE_UINT16_BE (destU + (i >> 1), U);
1783     GST_WRITE_UINT16_BE (destV + (i >> 1), V);
1784   }
1785 }
1786
1787 typedef struct
1788 {
1789   guint32 fourcc;
1790   GstVideoFormatInfo info;
1791 } VideoFormat;
1792
1793 /* depths: bits, n_components, shift, depth */
1794 #define DPTH0            0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1795 #define DPTH8            8, 1, { 0, 0, 0, 0 }, { 8, 0, 0, 0 }
1796 #define DPTH8_32         8, 2, { 0, 0, 0, 0 }, { 8, 32, 0, 0 }
1797 #define DPTH888          8, 3, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
1798 #define DPTH8888         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 8 }
1799 #define DPTH10_10_10     10, 3, { 0, 0, 0, 0 }, { 10, 10, 10, 0 }
1800 #define DPTH16           16, 1, { 0, 0, 0, 0 }, { 16, 0, 0, 0 }
1801 #define DPTH16_16_16     16, 3, { 0, 0, 0, 0 }, { 16, 16, 16, 0 }
1802 #define DPTH16_16_16_16  16, 4, { 0, 0, 0, 0 }, { 16, 16, 16, 16 }
1803 #define DPTH555          16, 3, { 10, 5, 0, 0 }, { 5, 5, 5, 0 }
1804 #define DPTH565          16, 3, { 11, 5, 0, 0 }, { 5, 6, 5, 0 }
1805
1806 /* pixel strides */
1807 #define PSTR0             { 0, 0, 0, 0 }
1808 #define PSTR1             { 1, 0, 0, 0 }
1809 #define PSTR14            { 1, 4, 0, 0 }
1810 #define PSTR111           { 1, 1, 1, 0 }
1811 #define PSTR1111          { 1, 1, 1, 1 }
1812 #define PSTR122           { 1, 2, 2, 0 }
1813 #define PSTR2             { 2, 0, 0, 0 }
1814 #define PSTR222           { 2, 2, 2, 0 }
1815 #define PSTR244           { 2, 4, 4, 0 }
1816 #define PSTR444           { 4, 4, 4, 0 }
1817 #define PSTR4444          { 4, 4, 4, 4 }
1818 #define PSTR333           { 3, 3, 3, 0 }
1819 #define PSTR488           { 4, 8, 8, 0 }
1820 #define PSTR8888          { 8, 8, 8, 8 }
1821
1822 /* planes, in what plane do we find component N */
1823 #define PLANE_NA          0, { 0, 0, 0, 0 }
1824 #define PLANE0            1, { 0, 0, 0, 0 }
1825 #define PLANE01           2, { 0, 1, 0, 0 }
1826 #define PLANE011          2, { 0, 1, 1, 0 }
1827 #define PLANE012          3, { 0, 1, 2, 0 }
1828 #define PLANE0123         4, { 0, 1, 2, 3 }
1829 #define PLANE021          3, { 0, 2, 1, 0 }
1830 #define PLANE201          3, { 2, 0, 1, 0 }
1831
1832 /* offsets */
1833 #define OFFS0             { 0, 0, 0, 0 }
1834 #define OFFS013           { 0, 1, 3, 0 }
1835 #define OFFS102           { 1, 0, 2, 0 }
1836 #define OFFS1230          { 1, 2, 3, 0 }
1837 #define OFFS012           { 0, 1, 2, 0 }
1838 #define OFFS210           { 2, 1, 0, 0 }
1839 #define OFFS123           { 1, 2, 3, 0 }
1840 #define OFFS321           { 3, 2, 1, 0 }
1841 #define OFFS0123          { 0, 1, 2, 3 }
1842 #define OFFS2103          { 2, 1, 0, 3 }
1843 #define OFFS3210          { 3, 2, 1, 0 }
1844 #define OFFS031           { 0, 3, 1, 0 }
1845 #define OFFS204           { 2, 0, 4, 0 }
1846 #define OFFS001           { 0, 0, 1, 0 }
1847 #define OFFS010           { 0, 1, 0, 0 }
1848 #define OFFS104           { 1, 0, 4, 0 }
1849 #define OFFS2460          { 2, 4, 6, 0 }
1850
1851 /* subsampling */
1852 #define SUB410            { 0, 2, 2, 0 }, { 0, 2, 2, 0 }
1853 #define SUB411            { 0, 2, 2, 0 }, { 0, 0, 0, 0 }
1854 #define SUB420            { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
1855 #define SUB422            { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
1856 #define SUB4              { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1857 #define SUB44             { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1858 #define SUB444            { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1859 #define SUB4444           { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
1860 #define SUB4204           { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
1861
1862 #define MAKE_YUV_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
1863  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV, depth, pstride, plane, offs, sub, pack } }
1864 #define MAKE_YUV_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
1865  { 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 } }
1866 #define MAKE_YUVA_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
1867  { 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 } }
1868 #define MAKE_YUVA_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
1869  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_UNPACK, depth, pstride, plane, offs, sub, pack } }
1870 #define MAKE_YUVA_LE_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
1871  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_UNPACK | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
1872 #define MAKE_YUV_C_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
1873  { 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 } }
1874
1875 #define MAKE_RGB_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1876  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB, depth, pstride, plane, offs, sub, pack } }
1877 #define MAKE_RGB_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1878  { 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 } }
1879 #define MAKE_RGBA_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1880  { 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 } }
1881 #define MAKE_RGBAP_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1882  { 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 } }
1883 #define MAKE_RGBA_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1884  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_UNPACK, depth, pstride, plane, offs, sub, pack } }
1885 #define MAKE_RGBA_LE_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1886  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_UNPACK | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
1887
1888 #define MAKE_GRAY_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1889  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY, depth, pstride, plane, offs, sub, pack } }
1890 #define MAKE_GRAY_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
1891  { 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 } }
1892
1893 static VideoFormat formats[] = {
1894   {0x00000000, {GST_VIDEO_FORMAT_UNKNOWN, "UNKNOWN", "unknown video", 0, DPTH0,
1895           PSTR0, PLANE_NA, OFFS0}},
1896   {0x00000000, {GST_VIDEO_FORMAT_ENCODED, "ENCODED", "encoded video",
1897           GST_VIDEO_FORMAT_FLAG_COMPLEX, DPTH0, PSTR0, PLANE_NA, OFFS0}},
1898
1899   MAKE_YUV_FORMAT (I420, "raw video", GST_MAKE_FOURCC ('I', '4', '2', '0'),
1900       DPTH888, PSTR111, PLANE012, OFFS0, SUB420, PACK_420),
1901   MAKE_YUV_FORMAT (YV12, "raw video", GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
1902       DPTH888, PSTR111, PLANE021, OFFS0, SUB420, PACK_420),
1903   MAKE_YUV_FORMAT (YUY2, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
1904       DPTH888, PSTR244, PLANE0, OFFS013, SUB422, PACK_YUY2),
1905   MAKE_YUV_FORMAT (UYVY, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
1906       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_UYVY),
1907   MAKE_YUVA_PACK_FORMAT (AYUV, "raw video", GST_MAKE_FOURCC ('A', 'Y', 'U',
1908           'V'), DPTH8888, PSTR4444, PLANE0, OFFS1230, SUB4444, PACK_AYUV),
1909   MAKE_RGB_FORMAT (RGBx, "raw video", DPTH888, PSTR444, PLANE0, OFFS012,
1910       SUB444, PACK_RGBA),
1911   MAKE_RGB_FORMAT (BGRx, "raw video", DPTH888, PSTR444, PLANE0, OFFS210,
1912       SUB444, PACK_BGRA),
1913   MAKE_RGB_FORMAT (xRGB, "raw video", DPTH888, PSTR444, PLANE0, OFFS123,
1914       SUB444, PACK_ARGB),
1915   MAKE_RGB_FORMAT (xBGR, "raw video", DPTH888, PSTR444, PLANE0, OFFS321,
1916       SUB444, PACK_ABGR),
1917   MAKE_RGBA_FORMAT (RGBA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS0123,
1918       SUB4444, PACK_RGBA),
1919   MAKE_RGBA_FORMAT (BGRA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS2103,
1920       SUB4444, PACK_BGRA),
1921   MAKE_RGBA_PACK_FORMAT (ARGB, "raw video", DPTH8888, PSTR4444, PLANE0,
1922       OFFS1230, SUB4444, PACK_ARGB),
1923   MAKE_RGBA_FORMAT (ABGR, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS3210,
1924       SUB4444, PACK_ABGR),
1925   MAKE_RGB_FORMAT (RGB, "raw video", DPTH888, PSTR333, PLANE0, OFFS012, SUB444,
1926       PACK_RGB),
1927   MAKE_RGB_FORMAT (BGR, "raw video", DPTH888, PSTR333, PLANE0, OFFS210, SUB444,
1928       PACK_BGR),
1929
1930   MAKE_YUV_FORMAT (Y41B, "raw video", GST_MAKE_FOURCC ('Y', '4', '1', 'B'),
1931       DPTH888, PSTR111, PLANE012, OFFS0, SUB411, PACK_Y41B),
1932   MAKE_YUV_FORMAT (Y42B, "raw video", GST_MAKE_FOURCC ('Y', '4', '2', 'B'),
1933       DPTH888, PSTR111, PLANE012, OFFS0, SUB422, PACK_Y42B),
1934   MAKE_YUV_FORMAT (YVYU, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'),
1935       DPTH888, PSTR244, PLANE0, OFFS031, SUB422, PACK_YVYU),
1936   MAKE_YUV_FORMAT (Y444, "raw video", GST_MAKE_FOURCC ('Y', '4', '4', '4'),
1937       DPTH888, PSTR111, PLANE012, OFFS0, SUB444, PACK_Y444),
1938   MAKE_YUV_C_FORMAT (v210, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '0'),
1939       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_v210),
1940   MAKE_YUV_FORMAT (v216, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '6'),
1941       DPTH16_16_16, PSTR488, PLANE0, OFFS204, SUB422, PACK_v216),
1942   MAKE_YUV_FORMAT (NV12, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '2'),
1943       DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12),
1944   MAKE_YUV_FORMAT (NV21, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '1'),
1945       DPTH888, PSTR122, PLANE011, OFFS010, SUB420, PACK_NV21),
1946
1947   MAKE_GRAY_FORMAT (GRAY8, "raw video", DPTH8, PSTR1, PLANE0, OFFS0, SUB4,
1948       PACK_GRAY8),
1949   MAKE_GRAY_FORMAT (GRAY16_BE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0, SUB4,
1950       PACK_GRAY16_BE),
1951   MAKE_GRAY_LE_FORMAT (GRAY16_LE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0,
1952       SUB4, PACK_GRAY16_LE),
1953
1954   MAKE_YUV_FORMAT (v308, "raw video", GST_MAKE_FOURCC ('v', '3', '0', '8'),
1955       DPTH888, PSTR333, PLANE0, OFFS012, SUB444, PACK_v308),
1956
1957 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1958   MAKE_RGB_LE_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
1959       SUB444, PACK_RGB16),
1960   MAKE_RGB_LE_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
1961       SUB444, PACK_BGR16),
1962   MAKE_RGB_LE_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
1963       SUB444, PACK_RGB15),
1964   MAKE_RGB_LE_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
1965       SUB444, PACK_BGR15),
1966 #else
1967   MAKE_RGB_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
1968       PACK_RGB16),
1969   MAKE_RGB_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
1970       PACK_BGR16),
1971   MAKE_RGB_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
1972       PACK_RGB15),
1973   MAKE_RGB_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
1974       PACK_BGR15),
1975 #endif
1976
1977   MAKE_YUV_C_FORMAT (UYVP, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'),
1978       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_UYVP),
1979   MAKE_YUVA_FORMAT (A420, "raw video", GST_MAKE_FOURCC ('A', '4', '2', '0'),
1980       DPTH8888, PSTR1111, PLANE0123, OFFS0, SUB4204, PACK_A420),
1981   MAKE_RGBAP_FORMAT (RGB8P, "raw video", DPTH8_32, PSTR14, PLANE01,
1982       OFFS0, SUB44, PACK_RGB8P),
1983   MAKE_YUV_FORMAT (YUV9, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'V', '9'),
1984       DPTH888, PSTR111, PLANE012, OFFS0, SUB410, PACK_410),
1985   MAKE_YUV_FORMAT (YVU9, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'U', '9'),
1986       DPTH888, PSTR111, PLANE021, OFFS0, SUB410, PACK_410),
1987   MAKE_YUV_FORMAT (IYU1, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '1'),
1988       DPTH888, PSTR0, PLANE0, OFFS104, SUB411, PACK_IYU1),
1989 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1990   MAKE_RGBA_LE_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888,
1991       PLANE0,
1992       OFFS2460, SUB444, PACK_ARGB64),
1993   MAKE_YUVA_LE_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
1994       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
1995 #else
1996   MAKE_RGBA_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
1997       OFFS2460, SUB444, PACK_ARGB64),
1998   MAKE_YUVA_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
1999       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
2000 #endif
2001   MAKE_RGB_FORMAT (r210, "raw video", DPTH10_10_10, PSTR444, PLANE0, OFFS0,
2002       SUB444, PACK_r210),
2003   MAKE_YUV_FORMAT (I420_10BE, "raw video", 0x00000000, DPTH10_10_10,
2004       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10BE),
2005   MAKE_YUV_LE_FORMAT (I420_10LE, "raw video", 0x00000000, DPTH10_10_10,
2006       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10LE),
2007   MAKE_YUV_FORMAT (I422_10BE, "raw video", 0x00000000, DPTH10_10_10,
2008       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10BE),
2009   MAKE_YUV_LE_FORMAT (I422_10LE, "raw video", 0x00000000, DPTH10_10_10,
2010       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10LE),
2011   MAKE_YUV_FORMAT (Y444_10BE, "raw video", 0x00000000, DPTH10_10_10,
2012       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10BE),
2013   MAKE_YUV_LE_FORMAT (Y444_10LE, "raw video", 0x00000000, DPTH10_10_10,
2014       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10LE),
2015   MAKE_RGB_FORMAT (GBR, "raw video", DPTH888, PSTR111, PLANE201, OFFS0, SUB444,
2016       PACK_GBR),
2017   MAKE_RGB_FORMAT (GBR_10BE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
2018       OFFS0, SUB444,
2019       PACK_GBR_10BE),
2020   MAKE_RGB_LE_FORMAT (GBR_10LE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
2021       OFFS0, SUB444,
2022       PACK_GBR_10LE),
2023 };
2024
2025 static GstVideoFormat
2026 gst_video_format_from_rgb32_masks (int red_mask, int green_mask, int blue_mask)
2027 {
2028   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
2029       blue_mask == 0x0000ff00) {
2030     return GST_VIDEO_FORMAT_RGBx;
2031   }
2032   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
2033       blue_mask == 0xff000000) {
2034     return GST_VIDEO_FORMAT_BGRx;
2035   }
2036   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
2037       blue_mask == 0x000000ff) {
2038     return GST_VIDEO_FORMAT_xRGB;
2039   }
2040   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
2041       blue_mask == 0x00ff0000) {
2042     return GST_VIDEO_FORMAT_xBGR;
2043   }
2044
2045   return GST_VIDEO_FORMAT_UNKNOWN;
2046 }
2047
2048 static GstVideoFormat
2049 gst_video_format_from_rgba32_masks (int red_mask, int green_mask,
2050     int blue_mask, int alpha_mask)
2051 {
2052   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
2053       blue_mask == 0x0000ff00 && alpha_mask == 0x000000ff) {
2054     return GST_VIDEO_FORMAT_RGBA;
2055   }
2056   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
2057       blue_mask == 0xff000000 && alpha_mask == 0x000000ff) {
2058     return GST_VIDEO_FORMAT_BGRA;
2059   }
2060   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
2061       blue_mask == 0x000000ff && alpha_mask == 0xff000000) {
2062     return GST_VIDEO_FORMAT_ARGB;
2063   }
2064   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
2065       blue_mask == 0x00ff0000 && alpha_mask == 0xff000000) {
2066     return GST_VIDEO_FORMAT_ABGR;
2067   }
2068   return GST_VIDEO_FORMAT_UNKNOWN;
2069 }
2070
2071 static GstVideoFormat
2072 gst_video_format_from_rgb24_masks (int red_mask, int green_mask, int blue_mask)
2073 {
2074   if (red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff) {
2075     return GST_VIDEO_FORMAT_RGB;
2076   }
2077   if (red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000) {
2078     return GST_VIDEO_FORMAT_BGR;
2079   }
2080
2081   return GST_VIDEO_FORMAT_UNKNOWN;
2082 }
2083
2084 #define GST_VIDEO_COMP1_MASK_16_INT 0xf800
2085 #define GST_VIDEO_COMP2_MASK_16_INT 0x07e0
2086 #define GST_VIDEO_COMP3_MASK_16_INT 0x001f
2087
2088 #define GST_VIDEO_COMP1_MASK_15_INT 0x7c00
2089 #define GST_VIDEO_COMP2_MASK_15_INT 0x03e0
2090 #define GST_VIDEO_COMP3_MASK_15_INT 0x001f
2091
2092 static GstVideoFormat
2093 gst_video_format_from_rgb16_masks (int red_mask, int green_mask, int blue_mask)
2094 {
2095   if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
2096       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
2097       && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
2098     return GST_VIDEO_FORMAT_RGB16;
2099   }
2100   if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
2101       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
2102       && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
2103     return GST_VIDEO_FORMAT_BGR16;
2104   }
2105   if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
2106       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
2107       && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
2108     return GST_VIDEO_FORMAT_RGB15;
2109   }
2110   if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
2111       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
2112       && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
2113     return GST_VIDEO_FORMAT_BGR15;
2114   }
2115   return GST_VIDEO_FORMAT_UNKNOWN;
2116 }
2117
2118 /**
2119  * gst_video_format_from_masks:
2120  * @depth: the amount of bits used for a pixel
2121  * @bpp: the amount of bits used to store a pixel. This value is bigger than
2122  *   @depth
2123  * @endianness: the endianness of the masks
2124  * @red_mask: the red mask
2125  * @green_mask: the green mask
2126  * @blue_mask: the blue mask
2127  * @alpha_mask: the optional alpha mask
2128  *
2129  * Find the #GstVideoFormat for the given parameters.
2130  *
2131  * Returns: a #GstVideoFormat or GST_VIDEO_FORMAT_UNKNOWN when the parameters to
2132  * not specify a known format.
2133  */
2134 GstVideoFormat
2135 gst_video_format_from_masks (gint depth, gint bpp, gint endianness,
2136     gint red_mask, gint green_mask, gint blue_mask, gint alpha_mask)
2137 {
2138   GstVideoFormat format;
2139
2140   /* our caps system handles 24/32bpp RGB as big-endian. */
2141   if ((bpp == 24 || bpp == 32) && endianness == G_LITTLE_ENDIAN) {
2142     red_mask = GUINT32_TO_BE (red_mask);
2143     green_mask = GUINT32_TO_BE (green_mask);
2144     blue_mask = GUINT32_TO_BE (blue_mask);
2145     endianness = G_BIG_ENDIAN;
2146     if (bpp == 24) {
2147       red_mask >>= 8;
2148       green_mask >>= 8;
2149       blue_mask >>= 8;
2150     }
2151   }
2152
2153   if (depth == 30 && bpp == 32) {
2154     format = GST_VIDEO_FORMAT_r210;
2155   } else if (depth == 24 && bpp == 32) {
2156     format = gst_video_format_from_rgb32_masks (red_mask, green_mask,
2157         blue_mask);
2158   } else if (depth == 32 && bpp == 32 && alpha_mask) {
2159     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
2160         blue_mask, alpha_mask);
2161   } else if (depth == 24 && bpp == 24) {
2162     format = gst_video_format_from_rgb24_masks (red_mask, green_mask,
2163         blue_mask);
2164   } else if ((depth == 15 || depth == 16) && bpp == 16 &&
2165       endianness == G_BYTE_ORDER) {
2166     format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
2167         blue_mask);
2168   } else if (depth == 8 && bpp == 8) {
2169     format = GST_VIDEO_FORMAT_RGB8P;
2170   } else if (depth == 64 && bpp == 64) {
2171     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
2172         blue_mask, alpha_mask);
2173     if (format == GST_VIDEO_FORMAT_ARGB) {
2174       format = GST_VIDEO_FORMAT_ARGB64;
2175     } else {
2176       format = GST_VIDEO_FORMAT_UNKNOWN;
2177     }
2178   } else {
2179     format = GST_VIDEO_FORMAT_UNKNOWN;
2180   }
2181   return format;
2182 }
2183
2184 /**
2185  * gst_video_format_from_fourcc:
2186  * @fourcc: a FOURCC value representing raw YUV video
2187  *
2188  * Converts a FOURCC value into the corresponding #GstVideoFormat.
2189  * If the FOURCC cannot be represented by #GstVideoFormat,
2190  * #GST_VIDEO_FORMAT_UNKNOWN is returned.
2191  *
2192  * Returns: the #GstVideoFormat describing the FOURCC value
2193  */
2194 GstVideoFormat
2195 gst_video_format_from_fourcc (guint32 fourcc)
2196 {
2197   switch (fourcc) {
2198     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
2199       return GST_VIDEO_FORMAT_I420;
2200     case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
2201       return GST_VIDEO_FORMAT_YV12;
2202     case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
2203       return GST_VIDEO_FORMAT_YUY2;
2204     case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
2205       return GST_VIDEO_FORMAT_YVYU;
2206     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
2207       return GST_VIDEO_FORMAT_UYVY;
2208     case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
2209       return GST_VIDEO_FORMAT_AYUV;
2210     case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
2211       return GST_VIDEO_FORMAT_Y41B;
2212     case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
2213       return GST_VIDEO_FORMAT_Y42B;
2214     case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
2215       return GST_VIDEO_FORMAT_Y444;
2216     case GST_MAKE_FOURCC ('v', '2', '1', '0'):
2217       return GST_VIDEO_FORMAT_v210;
2218     case GST_MAKE_FOURCC ('v', '2', '1', '6'):
2219       return GST_VIDEO_FORMAT_v216;
2220     case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
2221       return GST_VIDEO_FORMAT_NV12;
2222     case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
2223       return GST_VIDEO_FORMAT_NV21;
2224     case GST_MAKE_FOURCC ('v', '3', '0', '8'):
2225       return GST_VIDEO_FORMAT_v308;
2226     case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
2227     case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
2228     case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
2229       return GST_VIDEO_FORMAT_GRAY8;
2230     case GST_MAKE_FOURCC ('Y', '1', '6', ' '):
2231       return GST_VIDEO_FORMAT_GRAY16_LE;
2232     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'):
2233       return GST_VIDEO_FORMAT_UYVP;
2234     case GST_MAKE_FOURCC ('A', '4', '2', '0'):
2235       return GST_VIDEO_FORMAT_A420;
2236     case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
2237       return GST_VIDEO_FORMAT_YUV9;
2238     case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
2239       return GST_VIDEO_FORMAT_YVU9;
2240     case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
2241       return GST_VIDEO_FORMAT_IYU1;
2242     case GST_MAKE_FOURCC ('A', 'Y', '6', '4'):
2243       return GST_VIDEO_FORMAT_AYUV64;
2244     default:
2245       return GST_VIDEO_FORMAT_UNKNOWN;
2246   }
2247 }
2248
2249 /**
2250  * gst_video_format_from_string:
2251  * @format: a format string
2252  *
2253  * Convert the @format string to its #GstVideoFormat.
2254  *
2255  * Returns: the #GstVideoFormat for @format or GST_VIDEO_FORMAT_UNKNOWN when the
2256  * string is not a known format.
2257  */
2258 GstVideoFormat
2259 gst_video_format_from_string (const gchar * format)
2260 {
2261   guint i;
2262
2263   g_return_val_if_fail (format != NULL, GST_VIDEO_FORMAT_UNKNOWN);
2264
2265   for (i = 0; i < G_N_ELEMENTS (formats); i++) {
2266     if (strcmp (GST_VIDEO_FORMAT_INFO_NAME (&formats[i].info), format) == 0)
2267       return GST_VIDEO_FORMAT_INFO_FORMAT (&formats[i].info);
2268   }
2269   return GST_VIDEO_FORMAT_UNKNOWN;
2270 }
2271
2272
2273 /**
2274  * gst_video_format_to_fourcc:
2275  * @format: a #GstVideoFormat video format
2276  *
2277  * Converts a #GstVideoFormat value into the corresponding FOURCC.  Only
2278  * a few YUV formats have corresponding FOURCC values.  If @format has
2279  * no corresponding FOURCC value, 0 is returned.
2280  *
2281  * Returns: the FOURCC corresponding to @format
2282  */
2283 guint32
2284 gst_video_format_to_fourcc (GstVideoFormat format)
2285 {
2286   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
2287
2288   if (format >= G_N_ELEMENTS (formats))
2289     return 0;
2290
2291   return formats[format].fourcc;
2292 }
2293
2294 const gchar *
2295 gst_video_format_to_string (GstVideoFormat format)
2296 {
2297   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
2298
2299   if (format >= G_N_ELEMENTS (formats))
2300     return NULL;
2301
2302   return GST_VIDEO_FORMAT_INFO_NAME (&formats[format].info);
2303 }
2304
2305 /**
2306  * gst_video_format_get_info:
2307  * @format: a #GstVideoFormat
2308  *
2309  * Get the #GstVideoFormatInfo for @format
2310  *
2311  * Returns: The #GstVideoFormatInfo for @format.
2312  */
2313 const GstVideoFormatInfo *
2314 gst_video_format_get_info (GstVideoFormat format)
2315 {
2316   g_return_val_if_fail (format < G_N_ELEMENTS (formats), NULL);
2317
2318   return &formats[format].info;
2319 }
2320
2321 /**
2322  * gst_video_format_get_palette:
2323  * @format: a #GstVideoFormat
2324  * @size: (out): size of the palette in bytes
2325  *
2326  * Get the default palette of @format. This the palette used in the pack
2327  * function for paletted formats.
2328  *
2329  * Returns: the default palette of @format or %NULL when @format does not have a
2330  * palette.
2331  *
2332  * Since: 1.2
2333  */
2334 gconstpointer
2335 gst_video_format_get_palette (GstVideoFormat format, gsize * size)
2336 {
2337   g_return_val_if_fail (format < G_N_ELEMENTS (formats), NULL);
2338   g_return_val_if_fail (size != NULL, NULL);
2339
2340   switch (format) {
2341     case GST_VIDEO_FORMAT_RGB8P:
2342       *size = sizeof (std_palette_RGB8P);
2343       return std_palette_RGB8P;
2344     default:
2345       return NULL;
2346   }
2347 }
2348
2349 typedef struct
2350 {
2351   const gchar *name;
2352   GstVideoChromaSite site;
2353 } ChromaSiteInfo;
2354
2355 static const ChromaSiteInfo chromasite[] = {
2356   {"jpeg", GST_VIDEO_CHROMA_SITE_JPEG},
2357   {"mpeg2", GST_VIDEO_CHROMA_SITE_MPEG2},
2358   {"dv", GST_VIDEO_CHROMA_SITE_DV}
2359 };
2360
2361 /**
2362  * gst_video_chroma_from_string:
2363  * @s: a chromasite string
2364  *
2365  * Convert @s to a #GstVideoChromaSite
2366  *
2367  * Returns: a #GstVideoChromaSite or %GST_VIDEO_CHROMA_SITE_UNKNOWN when @s does
2368  * not contain a valid chroma description.
2369  */
2370 GstVideoChromaSite
2371 gst_video_chroma_from_string (const gchar * s)
2372 {
2373   gint i;
2374   for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
2375     if (g_str_equal (chromasite[i].name, s))
2376       return chromasite[i].site;
2377   }
2378   return GST_VIDEO_CHROMA_SITE_UNKNOWN;
2379 }
2380
2381 /**
2382  * gst_video_chroma_to_string:
2383  * @site: a #GstVideoChromaSite
2384  *
2385  * Converts @site to its string representation.
2386  *
2387  * Returns: a string describing @site.
2388  */
2389 const gchar *
2390 gst_video_chroma_to_string (GstVideoChromaSite site)
2391 {
2392   gint i;
2393   for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
2394     if (chromasite[i].site == site)
2395       return chromasite[i].name;
2396   }
2397   return NULL;
2398 }