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