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