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