video: Add I420/I422/Y444_12LE/BE and GBRA video formats
[platform/upstream/gst-plugins-base.git] / gst-libs / gst / video / video-format.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Library       <2002> Ronald Bultje <rbultje@ronald.bitfreak.net>
4  * Copyright (C) 2007 David A. Schleef <ds@schleef.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28
29 #include "video-format.h"
30 #include "video-orc.h"
31
32 #ifndef restrict
33 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
34 /* restrict should be available */
35 #elif defined(__GNUC__) && __GNUC__ >= 4
36 #define restrict __restrict__
37 #elif defined(_MSC_VER) &&  _MSC_VER >= 1500
38 #define restrict __restrict
39 #else
40 #define restrict                /* no op */
41 #endif
42 #endif
43
44 /* Line conversion to AYUV */
45
46 #define GET_PLANE_STRIDE(plane) (stride(plane))
47 #define GET_PLANE_LINE(plane, line) \
48   (gpointer)(((guint8*)(data[plane])) + stride[plane] * (line))
49
50 #define GET_COMP_STRIDE(comp) \
51   GST_VIDEO_FORMAT_INFO_STRIDE (info, stride, comp)
52 #define GET_COMP_DATA(comp) \
53   GST_VIDEO_FORMAT_INFO_DATA (info, data, comp)
54
55 #define GET_COMP_LINE(comp, line) \
56   (gpointer)(((guint8*)GET_COMP_DATA (comp)) + \
57       GET_COMP_STRIDE(comp) * (line))
58
59 #define GET_LINE(line)               GET_PLANE_LINE (0, line)
60
61 #define GET_Y_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_Y, line)
62 #define GET_U_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_U, line)
63 #define GET_V_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_V, line)
64
65 #define GET_R_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_R, line)
66 #define GET_G_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_G, line)
67 #define GET_B_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_B, line)
68
69 #define GET_A_LINE(line)             GET_COMP_LINE(GST_VIDEO_COMP_A, line)
70
71 #define GET_UV_420(line, flags)                 \
72   (flags & GST_VIDEO_PACK_FLAG_INTERLACED ?     \
73    ((line & ~3) >> 1) + (line & 1) :            \
74    line >> 1)
75 #define GET_UV_410(line, flags)                 \
76   (flags & GST_VIDEO_PACK_FLAG_INTERLACED ?     \
77    ((line & ~7) >> 2) + (line & 1) :            \
78    line >> 2)
79
80 #define IS_CHROMA_LINE_420(line, flags)         \
81   (flags & GST_VIDEO_PACK_FLAG_INTERLACED ?     \
82    !(line & 2) : !(line & 1))
83 #define IS_CHROMA_LINE_410(line, flags)         \
84   (flags & GST_VIDEO_PACK_FLAG_INTERLACED ?     \
85    !(line & 6) : !(line & 3))
86
87 #define IS_ALIGNED(x,n) ((((guintptr)(x)&((n)-1))) == 0)
88
89 #define PACK_420 GST_VIDEO_FORMAT_AYUV, unpack_planar_420, 1, pack_planar_420
90 static void
91 unpack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
92     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
93     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
94 {
95   gint uv = GET_UV_420 (y, flags);
96   const guint8 *restrict sy = GET_Y_LINE (y);
97   const guint8 *restrict su = GET_U_LINE (uv);
98   const guint8 *restrict sv = GET_V_LINE (uv);
99   guint8 *restrict d = dest;
100
101   sy += x;
102   su += x >> 1;
103   sv += x >> 1;
104
105   if (x & 1) {
106     d[0] = 0xff;
107     d[1] = *sy++;
108     d[2] = *su++;
109     d[3] = *sv++;
110     width--;
111     d += 4;
112   }
113   video_orc_unpack_I420 (d, sy, su, sv, width);
114 }
115
116 static void
117 pack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
118     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
119     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
120     gint y, gint width)
121 {
122   gint uv = GET_UV_420 (y, flags);
123   guint8 *dy = GET_Y_LINE (y);
124   guint8 *du = GET_U_LINE (uv);
125   guint8 *dv = GET_V_LINE (uv);
126   const guint8 *s = src;
127
128   if (IS_CHROMA_LINE_420 (y, flags)) {
129     if (IS_ALIGNED (s, 8))
130       video_orc_pack_I420 (dy, du, dv, s, width / 2);
131     else {
132       gint i;
133
134       for (i = 0; i < width / 2; i++) {
135         dy[i * 2 + 0] = s[i * 8 + 1];
136         dy[i * 2 + 1] = s[i * 8 + 5];
137         du[i] = s[i * 8 + 2];
138         dv[i] = s[i * 8 + 3];
139       }
140     }
141     if (width & 1) {
142       gint i = width - 1;
143
144       dy[i] = s[i * 4 + 1];
145       du[i >> 1] = s[i * 4 + 2];
146       dv[i >> 1] = s[i * 4 + 3];
147     }
148   } else
149     video_orc_pack_Y (dy, s, width);
150 }
151
152 #define PACK_YUY2 GST_VIDEO_FORMAT_AYUV, unpack_YUY2, 1, pack_YUY2
153 static void
154 unpack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
155     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
156     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
157 {
158   const guint8 *restrict s = GET_LINE (y);
159   guint8 *restrict d = dest;
160
161   s += (x & ~1) << 1;
162   if (x & 1) {
163     d[0] = 0xff;
164     d[1] = s[2];
165     d[2] = s[1];
166     d[3] = s[3];
167     s += 4;
168     d += 4;
169     width--;
170   }
171
172   if (IS_ALIGNED (d, 8))
173     video_orc_unpack_YUY2 (d, s, width / 2);
174   else {
175     gint i;
176
177     for (i = 0; i < width / 2; i++) {
178       d[i * 8 + 0] = 0xff;
179       d[i * 8 + 1] = s[i * 4 + 0];
180       d[i * 8 + 2] = s[i * 4 + 1];
181       d[i * 8 + 3] = s[i * 4 + 3];
182       d[i * 8 + 4] = 0xff;
183       d[i * 8 + 5] = s[i * 4 + 2];
184       d[i * 8 + 6] = s[i * 4 + 1];
185       d[i * 8 + 7] = s[i * 4 + 3];
186     }
187   }
188
189   if (width & 1) {
190     gint i = width - 1;
191
192     d[i * 4 + 0] = 0xff;
193     d[i * 4 + 1] = s[i * 2 + 0];
194     d[i * 4 + 2] = s[i * 2 + 1];
195     d[i * 4 + 3] = s[i * 2 + 3];
196   }
197 }
198
199 static void
200 pack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
201     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
202     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
203     gint y, gint width)
204 {
205   guint8 *restrict d = GET_LINE (y);
206   const guint8 *restrict s = src;
207
208   if (IS_ALIGNED (s, 8))
209     video_orc_pack_YUY2 (d, s, width / 2);
210   else {
211     gint i;
212     for (i = 0; i < width / 2; i++) {
213       d[i * 4 + 0] = s[i * 8 + 1];
214       d[i * 4 + 1] = s[i * 8 + 2];
215       d[i * 4 + 2] = s[i * 8 + 5];
216       d[i * 4 + 3] = s[i * 8 + 3];
217     }
218   }
219
220   if (width & 1) {
221     gint i = width - 1;
222
223     d[i * 2 + 0] = s[i * 4 + 1];
224     d[i * 2 + 1] = s[i * 4 + 2];
225     d[i * 2 + 3] = s[i * 4 + 3];
226   }
227 }
228
229 #define PACK_UYVY GST_VIDEO_FORMAT_AYUV, unpack_UYVY, 1, pack_UYVY
230 static void
231 unpack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
232     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
233     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
234 {
235   const guint8 *s = GET_LINE (y);
236   guint8 *d = dest;
237
238   s += (x & ~1) << 1;
239   if (x & 1) {
240     d[0] = 0xff;
241     d[1] = s[3];
242     d[2] = s[0];
243     d[3] = s[2];
244     s += 4;
245     d += 4;
246     width--;
247   }
248
249   if (IS_ALIGNED (d, 8))
250     video_orc_unpack_UYVY (d, s, width / 2);
251   else {
252     gint i;
253
254     for (i = 0; i < width / 2; i++) {
255       d[i * 8 + 0] = 0xff;
256       d[i * 8 + 1] = s[i * 4 + 1];
257       d[i * 8 + 2] = s[i * 4 + 0];
258       d[i * 8 + 3] = s[i * 4 + 2];
259       d[i * 8 + 4] = 0xff;
260       d[i * 8 + 5] = s[i * 4 + 3];
261       d[i * 8 + 6] = s[i * 4 + 0];
262       d[i * 8 + 7] = s[i * 4 + 2];
263     }
264   }
265
266   if (width & 1) {
267     gint i = width - 1;
268
269     d[i * 4 + 0] = 0xff;
270     d[i * 4 + 1] = s[i * 2 + 1];
271     d[i * 4 + 2] = s[i * 2 + 0];
272     d[i * 4 + 3] = s[i * 2 + 2];
273   }
274 }
275
276 static void
277 pack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
278     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
279     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
280     gint y, gint width)
281 {
282   guint8 *restrict d = GET_LINE (y);
283   const guint8 *restrict s = src;
284
285   if (IS_ALIGNED (s, 8))
286     video_orc_pack_UYVY (d, s, width / 2);
287   else {
288     gint i;
289     for (i = 0; i < width / 2; i++) {
290       d[i * 4 + 0] = s[i * 8 + 2];
291       d[i * 4 + 1] = s[i * 8 + 1];
292       d[i * 4 + 2] = s[i * 8 + 3];
293       d[i * 4 + 3] = s[i * 8 + 5];
294     }
295   }
296   if (width & 1) {
297     gint i = width - 1;
298
299     d[i * 2 + 0] = s[i * 4 + 2];
300     d[i * 2 + 1] = s[i * 4 + 1];
301     d[i * 2 + 2] = s[i * 4 + 3];
302   }
303 }
304
305 #define PACK_VYUY GST_VIDEO_FORMAT_AYUV, unpack_VYUY, 1, pack_VYUY
306 static void
307 unpack_VYUY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
308     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
309     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
310 {
311   const guint8 *s = GET_LINE (y);
312   guint8 *d = dest;
313
314   s += (x & ~1) << 1;
315   if (x & 1) {
316     d[0] = 0xff;
317     d[1] = s[3];
318     d[2] = s[0];
319     d[3] = s[2];
320     s += 4;
321     d += 4;
322     width--;
323   }
324
325   if (IS_ALIGNED (d, 8))
326     video_orc_unpack_VYUY (d, s, width / 2);
327   else {
328     gint i;
329
330     for (i = 0; i < width / 2; i++) {
331       d[i * 8 + 0] = 0xff;
332       d[i * 8 + 1] = s[i * 4 + 1];
333       d[i * 8 + 2] = s[i * 4 + 0];
334       d[i * 8 + 3] = s[i * 4 + 2];
335       d[i * 8 + 4] = 0xff;
336       d[i * 8 + 5] = s[i * 4 + 3];
337       d[i * 8 + 6] = s[i * 4 + 0];
338       d[i * 8 + 7] = s[i * 4 + 2];
339     }
340   }
341
342   if (width & 1) {
343     gint i = width - 1;
344
345     d[i * 4 + 0] = 0xff;
346     d[i * 4 + 1] = s[i * 2 + 1];
347     d[i * 4 + 2] = s[i * 2 + 0];
348     d[i * 4 + 3] = s[i * 2 + 2];
349   }
350 }
351
352 static void
353 pack_VYUY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
354     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
355     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
356     gint y, gint width)
357 {
358   guint8 *restrict d = GET_LINE (y);
359   const guint8 *restrict s = src;
360
361   if (IS_ALIGNED (s, 8))
362     video_orc_pack_VYUY (d, s, width / 2);
363   else {
364     gint i;
365     for (i = 0; i < width / 2; i++) {
366       d[i * 4 + 0] = s[i * 8 + 2];
367       d[i * 4 + 1] = s[i * 8 + 1];
368       d[i * 4 + 2] = s[i * 8 + 3];
369       d[i * 4 + 3] = s[i * 8 + 5];
370     }
371   }
372   if (width & 1) {
373     gint i = width - 1;
374
375     d[i * 2 + 0] = s[i * 4 + 2];
376     d[i * 2 + 1] = s[i * 4 + 1];
377     d[i * 2 + 2] = s[i * 4 + 3];
378   }
379 }
380
381 #define PACK_YVYU GST_VIDEO_FORMAT_AYUV, unpack_YVYU, 1, pack_YVYU
382 static void
383 unpack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
384     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
385     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
386 {
387   const guint8 *restrict s = GET_LINE (y);
388   guint8 *restrict d = dest;
389
390   s += (x & ~1) << 1;
391   if (x & 1) {
392     d[0] = 0xff;
393     d[1] = s[2];
394     d[2] = s[3];
395     d[3] = s[1];
396     s += 4;
397     d += 4;
398     width--;
399   }
400
401   if (IS_ALIGNED (d, 8))
402     video_orc_unpack_YVYU (d, s, width / 2);
403   else {
404     gint i;
405
406     for (i = 0; i < width / 2; i++) {
407       d[i * 8 + 0] = 0xff;
408       d[i * 8 + 1] = s[i * 4 + 0];
409       d[i * 8 + 2] = s[i * 4 + 3];
410       d[i * 8 + 3] = s[i * 4 + 1];
411       d[i * 8 + 4] = 0xff;
412       d[i * 8 + 5] = s[i * 4 + 2];
413       d[i * 8 + 6] = s[i * 4 + 3];
414       d[i * 8 + 7] = s[i * 4 + 1];
415     }
416   }
417
418   if (width & 1) {
419     gint i = width - 1;
420
421     d[i * 4 + 0] = 0xff;
422     d[i * 4 + 1] = s[i * 2 + 0];
423     d[i * 4 + 2] = s[i * 2 + 3];
424     d[i * 4 + 3] = s[i * 2 + 1];
425   }
426 }
427
428 static void
429 pack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
430     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
431     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
432     gint y, gint width)
433 {
434   guint8 *restrict d = GET_LINE (y);
435   const guint8 *restrict s = src;
436
437   if (IS_ALIGNED (s, 8))
438     video_orc_pack_YVYU (d, s, width / 2);
439   else {
440     gint i;
441     for (i = 0; i < width / 2; i++) {
442       d[i * 4 + 0] = s[i * 8 + 1];
443       d[i * 4 + 1] = s[i * 8 + 3];
444       d[i * 4 + 2] = s[i * 8 + 5];
445       d[i * 4 + 3] = s[i * 8 + 2];
446     }
447   }
448
449   if (width & 1) {
450     gint i = width - 1;
451
452     d[i * 2 + 0] = s[i * 4 + 1];
453     d[i * 2 + 1] = s[i * 4 + 3];
454     d[i * 2 + 3] = s[i * 4 + 2];
455   }
456 }
457
458 #define PACK_v308 GST_VIDEO_FORMAT_AYUV, unpack_v308, 1, pack_v308
459 static void
460 unpack_v308 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
461     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
462     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
463 {
464   int i;
465   const guint8 *restrict s = GET_LINE (y);
466   guint8 *restrict d = dest;
467
468   s += x * 3;
469
470   for (i = 0; i < width; i++) {
471     d[i * 4 + 0] = 0xff;
472     d[i * 4 + 1] = s[i * 3 + 0];
473     d[i * 4 + 2] = s[i * 3 + 1];
474     d[i * 4 + 3] = s[i * 3 + 2];
475   }
476 }
477
478 static void
479 pack_v308 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
480     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
481     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
482     gint y, gint width)
483 {
484   int i;
485   guint8 *restrict d = GET_LINE (y);
486   const guint8 *restrict s = src;
487
488   for (i = 0; i < width; i++) {
489     d[i * 3 + 0] = s[i * 4 + 1];
490     d[i * 3 + 1] = s[i * 4 + 2];
491     d[i * 3 + 2] = s[i * 4 + 3];
492   }
493 }
494
495 #define PACK_IYU2 GST_VIDEO_FORMAT_AYUV, unpack_IYU2, 1, pack_IYU2
496 static void
497 unpack_IYU2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
498     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
499     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
500 {
501   int i;
502   const guint8 *restrict s = GET_LINE (y);
503   guint8 *restrict d = dest;
504
505   s += x * 3;
506
507   for (i = 0; i < width; i++) {
508     d[i * 4 + 0] = 0xff;
509     d[i * 4 + 1] = s[i * 3 + 1];
510     d[i * 4 + 2] = s[i * 3 + 0];
511     d[i * 4 + 3] = s[i * 3 + 2];
512   }
513 }
514
515 static void
516 pack_IYU2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
517     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
518     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
519     gint y, gint width)
520 {
521   int i;
522   guint8 *restrict d = GET_LINE (y);
523   const guint8 *restrict s = src;
524
525   for (i = 0; i < width; i++) {
526     d[i * 3 + 0] = s[i * 4 + 2];
527     d[i * 3 + 1] = s[i * 4 + 1];
528     d[i * 3 + 2] = s[i * 4 + 3];
529   }
530 }
531
532 #define PACK_AYUV GST_VIDEO_FORMAT_AYUV, unpack_copy4, 1, pack_copy4
533 #define PACK_ARGB GST_VIDEO_FORMAT_ARGB, unpack_copy4, 1, pack_copy4
534 static void
535 unpack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
536     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
537     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
538 {
539   const guint8 *restrict s = GET_LINE (y);
540
541   s += x * 4;
542
543   memcpy (dest, s, width * 4);
544 }
545
546 static void
547 pack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
548     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
549     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
550     gint y, gint width)
551 {
552   guint8 *restrict d = GET_LINE (y);
553
554   memcpy (d, src, width * 4);
555 }
556
557 #define PACK_v210 GST_VIDEO_FORMAT_AYUV64, unpack_v210, 1, pack_v210
558 static void
559 unpack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
560     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
561     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
562 {
563   int i;
564   const guint8 *restrict s = GET_LINE (y);
565   guint16 *restrict d = dest;
566   guint32 a0, a1, a2, a3;
567   guint16 y0, y1, y2, y3, y4, y5;
568   guint16 u0, u2, u4;
569   guint16 v0, v2, v4;
570
571   /* FIXME */
572   s += x * 2;
573
574   for (i = 0; i < width; i += 6) {
575     a0 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 0);
576     a1 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 4);
577     a2 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 8);
578     a3 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 12);
579
580     u0 = ((a0 >> 0) & 0x3ff) << 6;
581     y0 = ((a0 >> 10) & 0x3ff) << 6;
582     v0 = ((a0 >> 20) & 0x3ff) << 6;
583     y1 = ((a1 >> 0) & 0x3ff) << 6;
584
585     u2 = ((a1 >> 10) & 0x3ff) << 6;
586     y2 = ((a1 >> 20) & 0x3ff) << 6;
587     v2 = ((a2 >> 0) & 0x3ff) << 6;
588     y3 = ((a2 >> 10) & 0x3ff) << 6;
589
590     u4 = ((a2 >> 20) & 0x3ff) << 6;
591     y4 = ((a3 >> 0) & 0x3ff) << 6;
592     v4 = ((a3 >> 10) & 0x3ff) << 6;
593     y5 = ((a3 >> 20) & 0x3ff) << 6;
594
595     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
596       y0 |= (y0 >> 10);
597       y1 |= (y1 >> 10);
598       u0 |= (u0 >> 10);
599       v0 |= (v0 >> 10);
600
601       y2 |= (y2 >> 10);
602       y3 |= (y3 >> 10);
603       u2 |= (u2 >> 10);
604       v2 |= (v2 >> 10);
605
606       y4 |= (y4 >> 10);
607       y5 |= (y5 >> 10);
608       u4 |= (u4 >> 10);
609       v4 |= (v4 >> 10);
610     }
611
612     d[4 * (i + 0) + 0] = 0xffff;
613     d[4 * (i + 0) + 1] = y0;
614     d[4 * (i + 0) + 2] = u0;
615     d[4 * (i + 0) + 3] = v0;
616
617     if (i < width - 1) {
618       d[4 * (i + 1) + 0] = 0xffff;
619       d[4 * (i + 1) + 1] = y1;
620       d[4 * (i + 1) + 2] = u0;
621       d[4 * (i + 1) + 3] = v0;
622     }
623     if (i < width - 2) {
624       d[4 * (i + 2) + 0] = 0xffff;
625       d[4 * (i + 2) + 1] = y2;
626       d[4 * (i + 2) + 2] = u2;
627       d[4 * (i + 2) + 3] = v2;
628     }
629     if (i < width - 3) {
630       d[4 * (i + 3) + 0] = 0xffff;
631       d[4 * (i + 3) + 1] = y3;
632       d[4 * (i + 3) + 2] = u2;
633       d[4 * (i + 3) + 3] = v2;
634     }
635     if (i < width - 4) {
636       d[4 * (i + 4) + 0] = 0xffff;
637       d[4 * (i + 4) + 1] = y4;
638       d[4 * (i + 4) + 2] = u4;
639       d[4 * (i + 4) + 3] = v4;
640     }
641     if (i < width - 5) {
642       d[4 * (i + 5) + 0] = 0xffff;
643       d[4 * (i + 5) + 1] = y5;
644       d[4 * (i + 5) + 2] = u4;
645       d[4 * (i + 5) + 3] = v4;
646     }
647   }
648 }
649
650 static void
651 pack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
652     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
653     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
654     gint y, gint width)
655 {
656   int i;
657   guint8 *restrict d = GET_LINE (y);
658   const guint16 *restrict s = src;
659   guint32 a0, a1, a2, a3;
660   guint16 y0, y1, y2, y3, y4, y5;
661   guint16 u0, u1, u2;
662   guint16 v0, v1, v2;
663
664   for (i = 0; i < width - 5; i += 6) {
665     y0 = s[4 * (i + 0) + 1] >> 6;
666     y1 = s[4 * (i + 1) + 1] >> 6;
667     y2 = s[4 * (i + 2) + 1] >> 6;
668     y3 = s[4 * (i + 3) + 1] >> 6;
669     y4 = s[4 * (i + 4) + 1] >> 6;
670     y5 = s[4 * (i + 5) + 1] >> 6;
671
672     u0 = s[4 * (i + 0) + 2] >> 6;
673     u1 = s[4 * (i + 2) + 2] >> 6;
674     u2 = s[4 * (i + 4) + 2] >> 6;
675
676     v0 = s[4 * (i + 0) + 3] >> 6;
677     v1 = s[4 * (i + 2) + 3] >> 6;
678     v2 = s[4 * (i + 4) + 3] >> 6;
679
680     a0 = u0 | (y0 << 10) | (v0 << 20);
681     a1 = y1 | (u1 << 10) | (y2 << 20);
682     a2 = v1 | (y3 << 10) | (u2 << 20);
683     a3 = y4 | (v2 << 10) | (y5 << 20);
684
685     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 0, a0);
686     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 4, a1);
687     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 8, a2);
688     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 12, a3);
689   }
690   if (i < width) {
691     y0 = s[4 * (i + 0) + 1] >> 6;
692     u0 = s[4 * (i + 0) + 2] >> 6;
693     v0 = s[4 * (i + 0) + 3] >> 6;
694     if (i < width - 1)
695       y1 = s[4 * (i + 1) + 1] >> 6;
696     else
697       y1 = y0;
698     if (i < width - 2) {
699       y2 = s[4 * (i + 2) + 1] >> 6;
700       u1 = s[4 * (i + 2) + 2] >> 6;
701       v1 = s[4 * (i + 2) + 3] >> 6;
702     } else {
703       y2 = y1;
704       u1 = u0;
705       v1 = v0;
706     }
707     if (i < width - 3)
708       y3 = s[4 * (i + 3) + 1] >> 6;
709     else
710       y3 = y2;
711     if (i < width - 4) {
712       y4 = s[4 * (i + 4) + 1] >> 6;
713       u2 = s[4 * (i + 4) + 2] >> 6;
714       v2 = s[4 * (i + 4) + 3] >> 6;
715     } else {
716       y4 = y3;
717       u2 = u1;
718       v2 = v1;
719     }
720     y5 = y4;
721
722     a0 = u0 | (y0 << 10) | (v0 << 20);
723     a1 = y1 | (u1 << 10) | (y2 << 20);
724     a2 = v1 | (y3 << 10) | (u2 << 20);
725     a3 = y4 | (v2 << 10) | (y5 << 20);
726
727     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 0, a0);
728     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 4, a1);
729     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 8, a2);
730     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 12, a3);
731   }
732 }
733
734 #define PACK_v216 GST_VIDEO_FORMAT_AYUV64, unpack_v216, 1, pack_v216
735 static void
736 unpack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
737     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
738     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
739 {
740   int i;
741   const guint8 *restrict s = GET_LINE (y);
742   guint16 *restrict d = dest;
743
744   s += (x & ~1) << 2;
745   if (x & 1) {
746     d[0] = 0xffff;
747     d[1] = GST_READ_UINT16_LE (s + 6);
748     d[2] = GST_READ_UINT16_LE (s + 0);
749     d[3] = GST_READ_UINT16_LE (s + 4);
750     s += 8;
751     d += 4;
752     width--;
753   }
754
755   for (i = 0; i < width; i++) {
756     d[i * 4 + 0] = 0xffff;
757     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i * 4 + 2);
758     d[i * 4 + 2] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 0);
759     d[i * 4 + 3] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 4);
760   }
761 }
762
763 static void
764 pack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
765     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
766     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
767     gint y, gint width)
768 {
769   int i;
770   guint8 *restrict d = GET_LINE (y);
771   const guint16 *restrict s = src;
772
773   for (i = 0; i < width - 1; i += 2) {
774     GST_WRITE_UINT16_LE (d + i * 4 + 0, s[(i + 0) * 4 + 2]);
775     GST_WRITE_UINT16_LE (d + i * 4 + 2, s[(i + 0) * 4 + 1]);
776     GST_WRITE_UINT16_LE (d + i * 4 + 4, s[(i + 0) * 4 + 3]);
777     GST_WRITE_UINT16_LE (d + i * 4 + 6, s[(i + 1) * 4 + 1]);
778   }
779   if (i == width - 1) {
780     GST_WRITE_UINT16_LE (d + i * 4 + 0, s[i * 4 + 2]);
781     GST_WRITE_UINT16_LE (d + i * 4 + 2, s[i * 4 + 1]);
782     GST_WRITE_UINT16_LE (d + i * 4 + 4, s[i * 4 + 3]);
783     GST_WRITE_UINT16_LE (d + i * 4 + 6, s[i * 4 + 1]);
784   }
785 }
786
787 #define PACK_Y41B GST_VIDEO_FORMAT_AYUV, unpack_Y41B, 1, pack_Y41B
788 static void
789 unpack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
790     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
791     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
792 {
793   const guint8 *restrict sy = GET_Y_LINE (y);
794   const guint8 *restrict su = GET_U_LINE (y);
795   const guint8 *restrict sv = GET_V_LINE (y);
796   guint8 *restrict d = dest;
797
798   sy += x;
799   su += x >> 2;
800   sv += x >> 2;
801
802   if (x & 3) {
803     for (; x & 3; x++) {
804       d[0] = 0xff;
805       d[1] = *sy++;
806       d[2] = *su;
807       d[3] = *sv;
808       width--;
809       d += 4;
810     }
811     su++;
812     sy++;
813   }
814
815   if (IS_ALIGNED (d, 8))
816     video_orc_unpack_YUV9 (d, sy, su, sv, width / 2);
817   else {
818     gint i;
819     for (i = 0; i < width / 2; i++) {
820       d[i * 8 + 0] = 0xff;
821       d[i * 8 + 1] = sy[i * 2 + 0];
822       d[i * 8 + 2] = su[i >> 1];
823       d[i * 8 + 3] = sv[i >> 1];
824       d[i * 8 + 4] = 0xff;
825       d[i * 8 + 5] = sy[i * 2 + 1];
826       d[i * 8 + 6] = su[i >> 1];
827       d[i * 8 + 7] = sv[i >> 1];
828     }
829   }
830
831   if (width & 1) {
832     gint i = width - 1;
833
834     d[i * 4 + 0] = 0xff;
835     d[i * 4 + 1] = sy[i];
836     d[i * 4 + 2] = su[i >> 2];
837     d[i * 4 + 3] = sv[i >> 2];
838   }
839 }
840
841 static void
842 pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
843     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
844     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
845     gint y, gint width)
846 {
847   int i;
848   guint8 *restrict dy = GET_Y_LINE (y);
849   guint8 *restrict du = GET_U_LINE (y);
850   guint8 *restrict dv = GET_V_LINE (y);
851   const guint8 *restrict s = src;
852
853   for (i = 0; i < width - 3; i += 4) {
854     dy[i] = s[i * 4 + 1];
855     dy[i + 1] = s[i * 4 + 5];
856     dy[i + 2] = s[i * 4 + 9];
857     dy[i + 3] = s[i * 4 + 13];
858
859     du[i >> 2] = s[i * 4 + 2];
860     dv[i >> 2] = s[i * 4 + 3];
861   }
862   if (i < width) {
863     dy[i] = s[i * 4 + 1];
864     du[i >> 2] = s[i * 4 + 2];
865     dv[i >> 2] = s[i * 4 + 3];
866     if (i < width - 1)
867       dy[i + 1] = s[i * 4 + 5];
868     if (i < width - 2)
869       dy[i + 2] = s[i * 4 + 9];
870   }
871 }
872
873 #define PACK_Y42B GST_VIDEO_FORMAT_AYUV, unpack_Y42B, 1, pack_Y42B
874 static void
875 unpack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
876     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
877     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
878 {
879   const guint8 *restrict sy = GET_Y_LINE (y);
880   const guint8 *restrict su = GET_U_LINE (y);
881   const guint8 *restrict sv = GET_V_LINE (y);
882   guint8 *restrict d = dest;
883
884   sy += x;
885   su += x >> 1;
886   sv += x >> 1;
887
888   if (x & 1) {
889     d[0] = 0xff;
890     d[1] = *sy++;
891     d[2] = *su++;
892     d[3] = *sv++;
893     width--;
894     d += 4;
895   }
896
897   if (IS_ALIGNED (d, 8))
898     video_orc_unpack_Y42B (d, sy, su, sv, width / 2);
899   else {
900     gint i;
901     for (i = 0; i < width / 2; i++) {
902       d[i * 8 + 0] = 0xff;
903       d[i * 8 + 1] = sy[i * 2 + 0];
904       d[i * 8 + 2] = su[i];
905       d[i * 8 + 3] = sv[i];
906       d[i * 8 + 4] = 0xff;
907       d[i * 8 + 5] = sy[i * 2 + 1];
908       d[i * 8 + 6] = su[i];
909       d[i * 8 + 7] = sv[i];
910     }
911   }
912
913   if (width & 1) {
914     gint i = width - 1;
915
916     d[i * 4 + 0] = 0xff;
917     d[i * 4 + 1] = sy[i];
918     d[i * 4 + 2] = su[i >> 1];
919     d[i * 4 + 3] = sv[i >> 1];
920   }
921 }
922
923 static void
924 pack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
925     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
926     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
927     gint y, gint width)
928 {
929   guint8 *restrict dy = GET_Y_LINE (y);
930   guint8 *restrict du = GET_U_LINE (y);
931   guint8 *restrict dv = GET_V_LINE (y);
932   const guint8 *restrict s = src;
933
934   if (IS_ALIGNED (s, 8))
935     video_orc_pack_Y42B (dy, du, dv, s, width / 2);
936   else {
937     gint i;
938     for (i = 0; i < width / 2; i++) {
939       dy[i * 2 + 0] = s[i * 8 + 1];
940       dy[i * 2 + 1] = s[i * 8 + 5];
941       du[i] = s[i * 8 + 2];
942       dv[i] = s[i * 8 + 3];
943     }
944   }
945
946   if (width & 1) {
947     gint i = width - 1;
948
949     dy[i] = s[i * 4 + 1];
950     du[i >> 1] = s[i * 4 + 2];
951     dv[i >> 1] = s[i * 4 + 3];
952   }
953 }
954
955 #define PACK_Y444 GST_VIDEO_FORMAT_AYUV, unpack_Y444, 1, pack_Y444
956 static void
957 unpack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
958     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
959     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
960 {
961   const guint8 *restrict sy = GET_Y_LINE (y);
962   const guint8 *restrict su = GET_U_LINE (y);
963   const guint8 *restrict sv = GET_V_LINE (y);
964
965   sy += x;
966   su += x;
967   sv += x;
968
969   video_orc_unpack_Y444 (dest, sy, su, sv, width);
970 }
971
972 static void
973 pack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
974     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
975     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
976     gint y, gint width)
977 {
978   guint8 *restrict dy = GET_Y_LINE (y);
979   guint8 *restrict du = GET_U_LINE (y);
980   guint8 *restrict dv = GET_V_LINE (y);
981
982   video_orc_pack_Y444 (dy, du, dv, src, width);
983 }
984
985 #define PACK_GBR GST_VIDEO_FORMAT_ARGB, unpack_GBR, 1, pack_GBR
986 static void
987 unpack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
988     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
989     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
990 {
991   const guint8 *restrict sr = GET_R_LINE (y);
992   const guint8 *restrict sg = GET_G_LINE (y);
993   const guint8 *restrict sb = GET_B_LINE (y);
994
995   sr += x;
996   sg += x;
997   sb += x;
998
999   video_orc_unpack_Y444 (dest, sr, sg, sb, width);
1000 }
1001
1002 static void
1003 pack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1004     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1005     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1006     gint y, gint width)
1007 {
1008   guint8 *restrict dr = GET_R_LINE (y);
1009   guint8 *restrict dg = GET_G_LINE (y);
1010   guint8 *restrict db = GET_B_LINE (y);
1011
1012   video_orc_pack_Y444 (dr, dg, db, src, width);
1013 }
1014
1015 #define PACK_GBRA GST_VIDEO_FORMAT_ARGB, unpack_GBRA, 1, pack_GBRA
1016 static void
1017 unpack_GBRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1018     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1019     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1020 {
1021   int i;
1022   const guint8 *sg = GET_G_LINE (y);
1023   const guint8 *sb = GET_B_LINE (y);
1024   const guint8 *sr = GET_R_LINE (y);
1025   const guint8 *sa = GET_A_LINE (y);
1026   guint8 *d = dest, G, B, R, A;
1027
1028   sg += x;
1029   sb += x;
1030   sr += x;
1031   sa += x;
1032
1033   for (i = 0; i < width; i++) {
1034     G = GST_READ_UINT8 (sg + i);
1035     B = GST_READ_UINT8 (sb + i);
1036     R = GST_READ_UINT8 (sr + i);
1037     A = GST_READ_UINT8 (sa + i);
1038
1039     d[i * 4 + 0] = A;
1040     d[i * 4 + 1] = R;
1041     d[i * 4 + 2] = G;
1042     d[i * 4 + 3] = B;
1043   }
1044 }
1045
1046 static void
1047 pack_GBRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1048     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1049     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1050     gint y, gint width)
1051 {
1052   int i;
1053   guint8 *restrict dg = GET_G_LINE (y);
1054   guint8 *restrict db = GET_B_LINE (y);
1055   guint8 *restrict dr = GET_R_LINE (y);
1056   guint8 *restrict da = GET_A_LINE (y);
1057   guint8 G, B, R, A;
1058   const guint8 *restrict s = src;
1059
1060   for (i = 0; i < width; i++) {
1061     G = (s[i * 4 + 2]);
1062     B = (s[i * 4 + 3]);
1063     R = (s[i * 4 + 1]);
1064     A = (s[i * 4 + 0]);
1065
1066     GST_WRITE_UINT8 (dg + i, G);
1067     GST_WRITE_UINT8 (db + i, B);
1068     GST_WRITE_UINT8 (dr + i, R);
1069     GST_WRITE_UINT8 (da + i, A);
1070   }
1071 }
1072
1073 #define PACK_GRAY8 GST_VIDEO_FORMAT_AYUV, unpack_GRAY8, 1, pack_GRAY8
1074 static void
1075 unpack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1076     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1077     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1078 {
1079   const guint8 *restrict s = GET_LINE (y);
1080
1081   s += x;
1082
1083   video_orc_unpack_GRAY8 (dest, s, width);
1084 }
1085
1086 static void
1087 pack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1088     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1089     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1090     gint y, gint width)
1091 {
1092   guint8 *restrict d = GET_LINE (y);
1093
1094   video_orc_pack_GRAY8 (d, src, width);
1095 }
1096
1097 #define PACK_GRAY16_BE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_BE, 1, pack_GRAY16_BE
1098 static void
1099 unpack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1100     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1101     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1102 {
1103   int i;
1104   const guint16 *restrict s = GET_LINE (y);
1105   guint16 *restrict d = dest;
1106
1107   s += x;
1108
1109   for (i = 0; i < width; i++) {
1110     d[i * 4 + 0] = 0xffff;
1111     d[i * 4 + 1] = GST_READ_UINT16_BE (s + i);
1112     d[i * 4 + 2] = 0x8000;
1113     d[i * 4 + 3] = 0x8000;
1114   }
1115 }
1116
1117 static void
1118 pack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1119     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1120     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1121     gint y, gint width)
1122 {
1123   int i;
1124   guint16 *restrict d = GET_LINE (y);
1125   const guint16 *restrict s = src;
1126
1127   for (i = 0; i < width; i++) {
1128     GST_WRITE_UINT16_BE (d + i, s[i * 4 + 1]);
1129   }
1130 }
1131
1132 #define PACK_GRAY16_LE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_LE, 1, pack_GRAY16_LE
1133 static void
1134 unpack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1135     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1136     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1137 {
1138   int i;
1139   const guint16 *restrict s = GET_LINE (y);
1140   guint16 *restrict d = dest;
1141
1142   s += x;
1143
1144   for (i = 0; i < width; i++) {
1145     d[i * 4 + 0] = 0xffff;
1146     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i);
1147     d[i * 4 + 2] = 0x8000;
1148     d[i * 4 + 3] = 0x8000;
1149   }
1150 }
1151
1152 static void
1153 pack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1154     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1155     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1156     gint y, gint width)
1157 {
1158   int i;
1159   guint16 *restrict d = GET_LINE (y);
1160   const guint16 *restrict s = src;
1161
1162   for (i = 0; i < width; i++) {
1163     GST_WRITE_UINT16_LE (d + i, s[i * 4 + 1]);
1164   }
1165 }
1166
1167 #define PACK_RGB16 GST_VIDEO_FORMAT_ARGB, unpack_RGB16, 1, pack_RGB16
1168 static void
1169 unpack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1170     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1171     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1172 {
1173   const guint16 *restrict s = GET_LINE (y);
1174
1175   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1176     video_orc_unpack_RGB16_trunc (dest, s + x, width);
1177   else
1178     video_orc_unpack_RGB16 (dest, s + x, width);
1179 }
1180
1181 static void
1182 pack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1183     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1184     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1185     gint y, gint width)
1186 {
1187   guint16 *restrict d = GET_LINE (y);
1188
1189 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1190   video_orc_pack_RGB16_le (d, src, width);
1191 #else
1192   video_orc_pack_RGB16_be (d, src, width);
1193 #endif
1194 }
1195
1196 #define PACK_BGR16 GST_VIDEO_FORMAT_ARGB, unpack_BGR16, 1, pack_BGR16
1197 static void
1198 unpack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1199     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1200     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1201 {
1202   const guint16 *restrict s = GET_LINE (y);
1203
1204   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1205     video_orc_unpack_BGR16_trunc (dest, s + x, width);
1206   else
1207     video_orc_unpack_BGR16 (dest, s + x, width);
1208 }
1209
1210 static void
1211 pack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1212     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1213     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1214     gint y, gint width)
1215 {
1216   guint16 *restrict d = GET_LINE (y);
1217
1218 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1219   video_orc_pack_BGR16_le (d, src, width);
1220 #else
1221   video_orc_pack_BGR16_be (d, src, width);
1222 #endif
1223 }
1224
1225 #define PACK_RGB15 GST_VIDEO_FORMAT_ARGB, unpack_RGB15, 1, pack_RGB15
1226 static void
1227 unpack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1228     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1229     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1230 {
1231   const guint16 *restrict s = GET_LINE (y);
1232
1233 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1234   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1235     video_orc_unpack_RGB15_le_trunc (dest, s + x, width);
1236   else
1237     video_orc_unpack_RGB15_le (dest, s + x, width);
1238 #else
1239   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1240     video_orc_unpack_RGB15_be_trunc (dest, s + x, width);
1241   else
1242     video_orc_unpack_RGB15_be (dest, s + x, width);
1243 #endif
1244 }
1245
1246 static void
1247 pack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1248     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1249     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1250     gint y, gint width)
1251 {
1252   guint16 *restrict d = GET_LINE (y);
1253
1254 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1255   video_orc_pack_RGB15_le (d, src, width);
1256 #else
1257   video_orc_pack_RGB15_be (d, src, width);
1258 #endif
1259 }
1260
1261 #define PACK_BGR15 GST_VIDEO_FORMAT_ARGB, unpack_BGR15, 1, pack_BGR15
1262 static void
1263 unpack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1264     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1265     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1266 {
1267   const guint16 *restrict s = GET_LINE (y);
1268
1269 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1270   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1271     video_orc_unpack_BGR15_le_trunc (dest, s + x, width);
1272   else
1273     video_orc_unpack_BGR15_le (dest, s + x, width);
1274 #else
1275   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1276     video_orc_unpack_BGR15_be_trunc (dest, s + x, width);
1277   else
1278     video_orc_unpack_BGR15_be (dest, s + x, width);
1279 #endif
1280 }
1281
1282 static void
1283 pack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1284     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1285     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1286     gint y, gint width)
1287 {
1288   guint16 *restrict d = GET_LINE (y);
1289
1290 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1291   video_orc_pack_BGR15_le (d, src, width);
1292 #else
1293   video_orc_pack_BGR15_be (d, src, width);
1294 #endif
1295 }
1296
1297 #define PACK_BGRA GST_VIDEO_FORMAT_ARGB, unpack_BGRA, 1, pack_BGRA
1298 static void
1299 unpack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1300     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1301     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1302 {
1303   const guint8 *restrict s = GET_LINE (y);
1304
1305   s += x * 4;
1306
1307   video_orc_unpack_BGRA (dest, s, width);
1308 }
1309
1310 static void
1311 pack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1312     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1313     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1314     gint y, gint width)
1315 {
1316   guint8 *restrict d = GET_LINE (y);
1317
1318   video_orc_pack_BGRA (d, src, width);
1319 }
1320
1321 #define PACK_ABGR GST_VIDEO_FORMAT_ARGB, unpack_ABGR, 1, pack_ABGR
1322 static void
1323 unpack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1324     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1325     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1326 {
1327   const guint8 *restrict s = GET_LINE (y);
1328
1329   s += x * 4;
1330
1331   video_orc_unpack_ABGR (dest, s, width);
1332 }
1333
1334 static void
1335 pack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1336     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1337     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1338     gint y, gint width)
1339 {
1340   guint8 *restrict d = GET_LINE (y);
1341
1342   video_orc_pack_ABGR (d, src, width);
1343 }
1344
1345 #define PACK_RGBA GST_VIDEO_FORMAT_ARGB, unpack_RGBA, 1, pack_RGBA
1346 static void
1347 unpack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1348     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1349     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1350 {
1351   const guint8 *restrict s = GET_LINE (y);
1352
1353   s += x * 4;
1354
1355   video_orc_unpack_RGBA (dest, s, width);
1356 }
1357
1358 static void
1359 pack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1360     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1361     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1362     gint y, gint width)
1363 {
1364   guint8 *restrict d = GET_LINE (y);
1365
1366   video_orc_pack_RGBA (d, src, width);
1367 }
1368
1369 #define PACK_RGB GST_VIDEO_FORMAT_ARGB, unpack_RGB, 1, pack_RGB
1370 static void
1371 unpack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1372     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1373     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1374 {
1375   int i;
1376   const guint8 *restrict s = GET_LINE (y);
1377   guint8 *restrict d = dest;
1378
1379   s += x * 3;
1380
1381   for (i = 0; i < width; i++) {
1382     d[i * 4 + 0] = 0xff;
1383     d[i * 4 + 1] = s[i * 3 + 0];
1384     d[i * 4 + 2] = s[i * 3 + 1];
1385     d[i * 4 + 3] = s[i * 3 + 2];
1386   }
1387 }
1388
1389 static void
1390 pack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1391     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1392     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1393     gint y, gint width)
1394 {
1395   int i;
1396   guint8 *restrict d = GET_LINE (y);
1397   const guint8 *restrict s = src;
1398
1399   for (i = 0; i < width; i++) {
1400     d[i * 3 + 0] = s[i * 4 + 1];
1401     d[i * 3 + 1] = s[i * 4 + 2];
1402     d[i * 3 + 2] = s[i * 4 + 3];
1403   }
1404 }
1405
1406 #define PACK_BGR GST_VIDEO_FORMAT_ARGB, unpack_BGR, 1, pack_BGR
1407 static void
1408 unpack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1409     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1410     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1411 {
1412   int i;
1413   const guint8 *restrict s = GET_LINE (y);
1414   guint8 *restrict d = dest;
1415
1416   s += x * 3;
1417
1418   for (i = 0; i < width; i++) {
1419     d[i * 4 + 0] = 0xff;
1420     d[i * 4 + 1] = s[i * 3 + 2];
1421     d[i * 4 + 2] = s[i * 3 + 1];
1422     d[i * 4 + 3] = s[i * 3 + 0];
1423   }
1424 }
1425
1426 static void
1427 pack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1428     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1429     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1430     gint y, gint width)
1431 {
1432   int i;
1433   guint8 *restrict d = GET_LINE (y);
1434   const guint8 *restrict s = src;
1435
1436   for (i = 0; i < width; i++) {
1437     d[i * 3 + 0] = s[i * 4 + 3];
1438     d[i * 3 + 1] = s[i * 4 + 2];
1439     d[i * 3 + 2] = s[i * 4 + 1];
1440   }
1441 }
1442
1443 #define PACK_NV12 GST_VIDEO_FORMAT_AYUV, unpack_NV12, 1, pack_NV12
1444 static void
1445 unpack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1446     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1447     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1448 {
1449   gint uv = GET_UV_420 (y, flags);
1450   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1451   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
1452   guint8 *restrict d = dest;
1453
1454   sy += x;
1455   suv += (x & ~1);
1456
1457   if (x & 1) {
1458     d[0] = 0xff;
1459     d[1] = *sy++;
1460     d[2] = suv[0];
1461     d[3] = suv[1];
1462     width--;
1463     d += 4;
1464     suv += 2;
1465   }
1466
1467   if (IS_ALIGNED (d, 8))
1468     video_orc_unpack_NV12 (d, sy, suv, width / 2);
1469   else {
1470     gint i;
1471     for (i = 0; i < width / 2; i++) {
1472       d[i * 8 + 0] = 0xff;
1473       d[i * 8 + 1] = sy[i * 2 + 0];
1474       d[i * 8 + 2] = suv[i * 2 + 0];
1475       d[i * 8 + 3] = suv[i * 2 + 1];
1476       d[i * 8 + 4] = 0xff;
1477       d[i * 8 + 5] = sy[i * 2 + 1];
1478       d[i * 8 + 6] = suv[i * 2 + 0];
1479       d[i * 8 + 7] = suv[i * 2 + 1];
1480     }
1481   }
1482
1483   if (width & 1) {
1484     gint i = width - 1;
1485
1486     d[i * 4 + 0] = 0xff;
1487     d[i * 4 + 1] = sy[i];
1488     d[i * 4 + 2] = suv[i + 0];
1489     d[i * 4 + 3] = suv[i + 1];
1490   }
1491 }
1492
1493 static void
1494 pack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1495     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1496     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1497     gint y, gint width)
1498 {
1499   gint uv = GET_UV_420 (y, flags);
1500   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1501   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
1502   const guint8 *restrict s = src;
1503
1504   if (IS_CHROMA_LINE_420 (y, flags)) {
1505     if (IS_ALIGNED (s, 8))
1506       video_orc_pack_NV12 (dy, duv, s, width / 2);
1507     else {
1508       gint i;
1509       for (i = 0; i < width / 2; i++) {
1510         dy[i * 2 + 0] = s[i * 8 + 1];
1511         dy[i * 2 + 1] = s[i * 8 + 5];
1512         duv[i * 2 + 0] = s[i * 8 + 2];
1513         duv[i * 2 + 1] = s[i * 8 + 3];
1514       }
1515     }
1516     if (width & 1) {
1517       gint i = width - 1;
1518
1519       dy[i] = s[i * 4 + 1];
1520       duv[i + 0] = s[i * 4 + 2];
1521       duv[i + 1] = s[i * 4 + 3];
1522     }
1523   } else
1524     video_orc_pack_Y (dy, s, width);
1525 }
1526
1527 #define PACK_NV21 GST_VIDEO_FORMAT_AYUV, unpack_NV21, 1, pack_NV21
1528 static void
1529 unpack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1530     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1531     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1532 {
1533   gint uv = GET_UV_420 (y, flags);
1534   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1535   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
1536   guint8 *restrict d = dest;
1537
1538   sy += x;
1539   suv += (x & ~1);
1540
1541   if (x & 1) {
1542     d[0] = 0xff;
1543     d[1] = *sy++;
1544     d[2] = suv[1];
1545     d[3] = suv[0];
1546     width--;
1547     d += 4;
1548     suv += 2;
1549   }
1550
1551   if (IS_ALIGNED (d, 8))
1552     video_orc_unpack_NV21 (d, sy, suv, width / 2);
1553   else {
1554     gint i;
1555     for (i = 0; i < width / 2; i++) {
1556       d[i * 8 + 0] = 0xff;
1557       d[i * 8 + 1] = sy[i * 2 + 0];
1558       d[i * 8 + 2] = suv[i * 2 + 1];
1559       d[i * 8 + 3] = suv[i * 2 + 0];
1560       d[i * 8 + 4] = 0xff;
1561       d[i * 8 + 5] = sy[i * 2 + 1];
1562       d[i * 8 + 6] = suv[i * 2 + 1];
1563       d[i * 8 + 7] = suv[i * 2 + 0];
1564     }
1565   }
1566
1567   if (width & 1) {
1568     gint i = width - 1;
1569
1570     d[i * 4 + 0] = 0xff;
1571     d[i * 4 + 1] = sy[i];
1572     d[i * 4 + 2] = suv[i + 1];
1573     d[i * 4 + 3] = suv[i + 0];
1574   }
1575 }
1576
1577 static void
1578 pack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1579     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1580     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1581     gint y, gint width)
1582 {
1583   gint uv = GET_UV_420 (y, flags);
1584   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1585   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
1586   const guint8 *restrict s = src;
1587
1588   if (IS_CHROMA_LINE_420 (y, flags)) {
1589     if (IS_ALIGNED (s, 8))
1590       video_orc_pack_NV21 (dy, duv, s, width / 2);
1591     else {
1592       gint i;
1593       for (i = 0; i < width / 2; i++) {
1594         dy[i * 2 + 0] = s[i * 8 + 1];
1595         dy[i * 2 + 1] = s[i * 8 + 5];
1596         duv[i * 2 + 0] = s[i * 8 + 3];
1597         duv[i * 2 + 1] = s[i * 8 + 2];
1598       }
1599     }
1600     if (width & 1) {
1601       gint i = width - 1;
1602
1603       dy[i] = s[i * 4 + 1];
1604       duv[i + 0] = s[i * 4 + 3];
1605       duv[i + 1] = s[i * 4 + 2];
1606     }
1607   } else
1608     video_orc_pack_Y (dy, s, width);
1609 }
1610
1611 #define PACK_NV16 GST_VIDEO_FORMAT_AYUV, unpack_NV16, 1, pack_NV16
1612 static void
1613 unpack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1614     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1615     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1616 {
1617   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1618   const guint8 *restrict suv = GET_PLANE_LINE (1, y);
1619   guint8 *restrict d = dest;
1620
1621   sy += x;
1622   suv += (x & ~1);
1623
1624   if (x & 1) {
1625     d[0] = 0xff;
1626     d[1] = *sy++;
1627     d[2] = suv[0];
1628     d[3] = suv[1];
1629     width--;
1630     d += 4;
1631     suv += 2;
1632   }
1633
1634   if (IS_ALIGNED (d, 8))
1635     video_orc_unpack_NV12 (d, sy, suv, width / 2);
1636   else {
1637     gint i;
1638     for (i = 0; i < width / 2; i++) {
1639       d[i * 8 + 0] = 0xff;
1640       d[i * 8 + 1] = sy[i * 2 + 0];
1641       d[i * 8 + 2] = suv[i * 2 + 0];
1642       d[i * 8 + 3] = suv[i * 2 + 1];
1643       d[i * 8 + 4] = 0xff;
1644       d[i * 8 + 5] = sy[i * 2 + 1];
1645       d[i * 8 + 6] = suv[i * 2 + 0];
1646       d[i * 8 + 7] = suv[i * 2 + 1];
1647     }
1648   }
1649
1650   if (width & 1) {
1651     gint i = width - 1;
1652
1653     d[i * 4 + 0] = 0xff;
1654     d[i * 4 + 1] = sy[i];
1655     d[i * 4 + 2] = suv[i + 0];
1656     d[i * 4 + 3] = suv[i + 1];
1657   }
1658 }
1659
1660 static void
1661 pack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1662     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1663     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1664     gint y, gint width)
1665 {
1666   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1667   guint8 *restrict duv = GET_PLANE_LINE (1, y);
1668   const guint8 *restrict s = src;
1669
1670   if (IS_ALIGNED (s, 8))
1671     video_orc_pack_NV12 (dy, duv, s, width / 2);
1672   else {
1673     gint i;
1674     for (i = 0; i < width / 2; i++) {
1675       dy[i * 2 + 0] = s[i * 8 + 1];
1676       dy[i * 2 + 1] = s[i * 8 + 5];
1677       duv[i * 2 + 0] = s[i * 8 + 2];
1678       duv[i * 2 + 1] = s[i * 8 + 3];
1679     }
1680   }
1681
1682   if (width & 1) {
1683     gint i = width - 1;
1684
1685     dy[i] = s[i * 4 + 1];
1686     duv[i + 0] = s[i * 4 + 2];
1687     duv[i + 1] = s[i * 4 + 3];
1688   }
1689 }
1690
1691 #define PACK_NV61 GST_VIDEO_FORMAT_AYUV, unpack_NV61, 1, pack_NV61
1692 static void
1693 unpack_NV61 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1694     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1695     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1696 {
1697   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1698   const guint8 *restrict svu = GET_PLANE_LINE (1, y);
1699   guint8 *restrict d = dest;
1700
1701   sy += x;
1702   svu += (x & ~1);
1703
1704   if (x & 1) {
1705     d[0] = 0xff;
1706     d[1] = *sy++;
1707     d[2] = svu[1];
1708     d[3] = svu[0];
1709     width--;
1710     d += 4;
1711     svu += 2;
1712   }
1713
1714   if (IS_ALIGNED (d, 8)) {
1715     video_orc_unpack_NV21 (d, sy, svu, width / 2);
1716   } else {
1717     gint i;
1718
1719     for (i = 0; i < width / 2; i++) {
1720       d[i * 8 + 0] = 0xff;
1721       d[i * 8 + 1] = sy[i * 2 + 0];
1722       d[i * 8 + 2] = svu[i * 2 + 1];
1723       d[i * 8 + 3] = svu[i * 2 + 0];
1724       d[i * 8 + 4] = 0xff;
1725       d[i * 8 + 5] = sy[i * 2 + 1];
1726       d[i * 8 + 6] = svu[i * 2 + 1];
1727       d[i * 8 + 7] = svu[i * 2 + 0];
1728     }
1729   }
1730
1731   if (width & 1) {
1732     gint i = width - 1;
1733
1734     d[i * 4 + 0] = 0xff;
1735     d[i * 4 + 1] = sy[i];
1736     d[i * 4 + 2] = svu[i + 1];
1737     d[i * 4 + 3] = svu[i + 0];
1738   }
1739 }
1740
1741 static void
1742 pack_NV61 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1743     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1744     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1745     gint y, gint width)
1746 {
1747   const guint8 *restrict s = src;
1748   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1749   guint8 *restrict dvu = GET_PLANE_LINE (1, y);
1750
1751   if (IS_ALIGNED (s, 8)) {
1752     video_orc_pack_NV21 (dy, dvu, s, width / 2);
1753   } else {
1754     gint i;
1755
1756     for (i = 0; i < width / 2; i++) {
1757       dy[i * 2 + 0] = s[i * 8 + 1];
1758       dy[i * 2 + 1] = s[i * 8 + 5];
1759       dvu[i * 2 + 0] = s[i * 8 + 3];
1760       dvu[i * 2 + 1] = s[i * 8 + 2];
1761     }
1762   }
1763
1764   if (width & 1) {
1765     gint i = width - 1;
1766
1767     dy[i] = s[i * 4 + 1];
1768     dvu[i + 0] = s[i * 4 + 2];
1769     dvu[i + 1] = s[i * 4 + 3];
1770   }
1771 }
1772
1773 #define PACK_NV24 GST_VIDEO_FORMAT_AYUV, unpack_NV24, 1, pack_NV24
1774 static void
1775 unpack_NV24 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1776     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1777     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1778 {
1779   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1780   const guint8 *restrict suv = GET_PLANE_LINE (1, y);
1781
1782   sy += x;
1783   suv += x << 1;
1784
1785   video_orc_unpack_NV24 (dest, sy, suv, width);
1786 }
1787
1788 static void
1789 pack_NV24 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1790     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1791     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1792     gint y, gint width)
1793 {
1794   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1795   guint8 *restrict duv = GET_PLANE_LINE (1, y);
1796
1797   video_orc_pack_NV24 (dy, duv, src, width);
1798 }
1799
1800 #define PACK_UYVP GST_VIDEO_FORMAT_AYUV64, unpack_UYVP, 1, pack_UYVP
1801 static void
1802 unpack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1803     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1804     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1805 {
1806   int i;
1807   const guint8 *restrict s = GET_LINE (y);
1808   guint16 *restrict d = dest;
1809
1810   /* FIXME */
1811   s += x << 1;
1812
1813   for (i = 0; i < width; i += 2) {
1814     guint16 y0, y1;
1815     guint16 u0;
1816     guint16 v0;
1817
1818     u0 = ((s[(i / 2) * 5 + 0] << 2) | (s[(i / 2) * 5 + 1] >> 6)) << 6;
1819     y0 = (((s[(i / 2) * 5 + 1] & 0x3f) << 4) | (s[(i / 2) * 5 + 2] >> 4)) << 6;
1820     v0 = (((s[(i / 2) * 5 + 2] & 0x0f) << 6) | (s[(i / 2) * 5 + 3] >> 2)) << 6;
1821     y1 = (((s[(i / 2) * 5 + 3] & 0x03) << 8) | s[(i / 2) * 5 + 4]) << 6;
1822
1823     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1824       y0 |= (y0 >> 10);
1825       y1 |= (y1 >> 10);
1826       u0 |= (u0 >> 10);
1827       v0 |= (v0 >> 10);
1828     }
1829
1830     d[i * 4 + 0] = 0xffff;
1831     d[i * 4 + 1] = y0;
1832     d[i * 4 + 2] = u0;
1833     d[i * 4 + 3] = v0;
1834
1835     if (i < width - 1) {
1836       d[i * 4 + 4] = 0xffff;
1837       d[i * 4 + 5] = y1;
1838       d[i * 4 + 6] = u0;
1839       d[i * 4 + 7] = v0;
1840     }
1841   }
1842 }
1843
1844 static void
1845 pack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1846     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1847     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1848     gint y, gint width)
1849 {
1850   int i;
1851   guint8 *restrict d = GET_LINE (y);
1852   const guint16 *restrict s = src;
1853
1854   for (i = 0; i < width; i += 2) {
1855     guint16 y0, y1;
1856     guint16 u0;
1857     guint16 v0;
1858
1859     y0 = s[4 * (i + 0) + 1];
1860     if (i < width - 1)
1861       y1 = s[4 * (i + 1) + 1];
1862     else
1863       y1 = y0;
1864
1865     u0 = s[4 * (i + 0) + 2];
1866     v0 = s[4 * (i + 0) + 3];
1867
1868     d[(i / 2) * 5 + 0] = u0 >> 8;
1869     d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10;
1870     d[(i / 2) * 5 + 2] = ((y0 & 0x3c0) >> 2) | (v0 >> 12);
1871     d[(i / 2) * 5 + 3] = ((v0 & 0xfc0) >> 4) | (y1 >> 14);
1872     d[(i / 2) * 5 + 4] = (y1 >> 6);
1873   }
1874 }
1875
1876 #define PACK_A420 GST_VIDEO_FORMAT_AYUV, unpack_A420, 1, pack_A420
1877 static void
1878 unpack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1879     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1880     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1881 {
1882   gint uv = GET_UV_420 (y, flags);
1883   const guint8 *restrict sy = GET_Y_LINE (y);
1884   const guint8 *restrict su = GET_U_LINE (uv);
1885   const guint8 *restrict sv = GET_V_LINE (uv);
1886   const guint8 *restrict sa = GET_A_LINE (y);
1887   guint8 *restrict d = dest;
1888
1889   sy += x;
1890   su += x >> 1;
1891   sv += x >> 1;
1892   sa += x;
1893
1894   if (x & 1) {
1895     d[0] = *sa++;
1896     d[1] = *sy++;
1897     d[2] = *su++;
1898     d[3] = *sv++;
1899     width--;
1900     d += 4;
1901   }
1902   video_orc_unpack_A420 (d, sy, su, sv, sa, width);
1903 }
1904
1905 static void
1906 pack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1907     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1908     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1909     gint y, gint width)
1910 {
1911   gint uv = GET_UV_420 (y, flags);
1912   guint8 *restrict dy = GET_Y_LINE (y);
1913   guint8 *restrict du = GET_U_LINE (uv);
1914   guint8 *restrict dv = GET_V_LINE (uv);
1915   guint8 *restrict da = GET_A_LINE (y);
1916   const guint8 *restrict s = src;
1917
1918   if (IS_CHROMA_LINE_420 (y, flags)) {
1919     if (IS_ALIGNED (s, 8))
1920       video_orc_pack_A420 (dy, du, dv, da, s, width / 2);
1921     else {
1922       gint i;
1923       for (i = 0; i < width / 2; i++) {
1924         da[i * 2 + 0] = s[i * 8 + 0];
1925         dy[i * 2 + 0] = s[i * 8 + 1];
1926         da[i * 2 + 1] = s[i * 8 + 4];
1927         dy[i * 2 + 1] = s[i * 8 + 5];
1928         du[i] = s[i * 8 + 2];
1929         dv[i] = s[i * 8 + 3];
1930       }
1931     }
1932
1933     if (width & 1) {
1934       gint i = width - 1;
1935
1936       da[i] = s[i * 4 + 0];
1937       dy[i] = s[i * 4 + 1];
1938       du[i >> 1] = s[i * 4 + 2];
1939       dv[i >> 1] = s[i * 4 + 3];
1940     }
1941   } else
1942     video_orc_pack_AY (dy, da, s, width);
1943 }
1944
1945 #define PACK_RGB8P GST_VIDEO_FORMAT_ARGB, unpack_RGB8P, 1, pack_RGB8P
1946 static void
1947 unpack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1948     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1949     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1950 {
1951   int i;
1952   const guint8 *restrict s = GET_LINE (y);
1953   const guint32 *restrict p = data[1];
1954   guint8 *restrict d = dest;
1955
1956   s += x;
1957
1958   for (i = 0; i < width; i++) {
1959     guint32 v = p[s[i]];
1960     d[i * 4 + 0] = (v >> 24) & 0xff;
1961     d[i * 4 + 1] = (v >> 16) & 0xff;
1962     d[i * 4 + 2] = (v >> 8) & 0xff;
1963     d[i * 4 + 3] = (v) & 0xff;
1964   }
1965 }
1966
1967 static const guint32 std_palette_RGB8P[] = {
1968   0xff000000, 0xff000033, 0xff000066, 0xff000099, 0xff0000cc, 0xff0000ff,
1969   0xff003300, 0xff003333, 0xff003366, 0xff003399, 0xff0033cc, 0xff0033ff,
1970   0xff006600, 0xff006633, 0xff006666, 0xff006699, 0xff0066cc, 0xff0066ff,
1971   0xff009900, 0xff009933, 0xff009966, 0xff009999, 0xff0099cc, 0xff0099ff,
1972   0xff00cc00, 0xff00cc33, 0xff00cc66, 0xff00cc99, 0xff00cccc, 0xff00ccff,
1973   0xff00ff00, 0xff00ff33, 0xff00ff66, 0xff00ff99, 0xff00ffcc, 0xff00ffff,
1974   0xff330000, 0xff330033, 0xff330066, 0xff330099, 0xff3300cc, 0xff3300ff,
1975   0xff333300, 0xff333333, 0xff333366, 0xff333399, 0xff3333cc, 0xff3333ff,
1976   0xff336600, 0xff336633, 0xff336666, 0xff336699, 0xff3366cc, 0xff3366ff,
1977   0xff339900, 0xff339933, 0xff339966, 0xff339999, 0xff3399cc, 0xff3399ff,
1978   0xff33cc00, 0xff33cc33, 0xff33cc66, 0xff33cc99, 0xff33cccc, 0xff33ccff,
1979   0xff33ff00, 0xff33ff33, 0xff33ff66, 0xff33ff99, 0xff33ffcc, 0xff33ffff,
1980   0xff660000, 0xff660033, 0xff660066, 0xff660099, 0xff6600cc, 0xff6600ff,
1981   0xff663300, 0xff663333, 0xff663366, 0xff663399, 0xff6633cc, 0xff6633ff,
1982   0xff666600, 0xff666633, 0xff666666, 0xff666699, 0xff6666cc, 0xff6666ff,
1983   0xff669900, 0xff669933, 0xff669966, 0xff669999, 0xff6699cc, 0xff6699ff,
1984   0xff66cc00, 0xff66cc33, 0xff66cc66, 0xff66cc99, 0xff66cccc, 0xff66ccff,
1985   0xff66ff00, 0xff66ff33, 0xff66ff66, 0xff66ff99, 0xff66ffcc, 0xff66ffff,
1986   0xff990000, 0xff990033, 0xff990066, 0xff990099, 0xff9900cc, 0xff9900ff,
1987   0xff993300, 0xff993333, 0xff993366, 0xff993399, 0xff9933cc, 0xff9933ff,
1988   0xff996600, 0xff996633, 0xff996666, 0xff996699, 0xff9966cc, 0xff9966ff,
1989   0xff999900, 0xff999933, 0xff999966, 0xff999999, 0xff9999cc, 0xff9999ff,
1990   0xff99cc00, 0xff99cc33, 0xff99cc66, 0xff99cc99, 0xff99cccc, 0xff99ccff,
1991   0xff99ff00, 0xff99ff33, 0xff99ff66, 0xff99ff99, 0xff99ffcc, 0xff99ffff,
1992   0xffcc0000, 0xffcc0033, 0xffcc0066, 0xffcc0099, 0xffcc00cc, 0xffcc00ff,
1993   0xffcc3300, 0xffcc3333, 0xffcc3366, 0xffcc3399, 0xffcc33cc, 0xffcc33ff,
1994   0xffcc6600, 0xffcc6633, 0xffcc6666, 0xffcc6699, 0xffcc66cc, 0xffcc66ff,
1995   0xffcc9900, 0xffcc9933, 0xffcc9966, 0xffcc9999, 0xffcc99cc, 0xffcc99ff,
1996   0xffcccc00, 0xffcccc33, 0xffcccc66, 0xffcccc99, 0xffcccccc, 0xffccccff,
1997   0xffccff00, 0xffccff33, 0xffccff66, 0xffccff99, 0xffccffcc, 0xffccffff,
1998   0xffff0000, 0xffff0033, 0xffff0066, 0xffff0099, 0xffff00cc, 0xffff00ff,
1999   0xffff3300, 0xffff3333, 0xffff3366, 0xffff3399, 0xffff33cc, 0xffff33ff,
2000   0xffff6600, 0xffff6633, 0xffff6666, 0xffff6699, 0xffff66cc, 0xffff66ff,
2001   0xffff9900, 0xffff9933, 0xffff9966, 0xffff9999, 0xffff99cc, 0xffff99ff,
2002   0xffffcc00, 0xffffcc33, 0xffffcc66, 0xffffcc99, 0xffffcccc, 0xffffccff,
2003   0xffffff00, 0xffffff33, 0xffffff66, 0xffffff99, 0xffffffcc, 0xffffffff,
2004   0x00000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2005   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2006   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2007   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2008   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2009   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2010   0xff000000, 0xff000000, 0xff000000, 0xff000000
2011 };
2012
2013 static void
2014 pack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2015     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2016     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2017     gint y, gint width)
2018 {
2019   int i;
2020   guint8 *restrict d = GET_LINE (y);
2021   const guint8 *restrict s = src;
2022
2023   /* Use our poor man's palette, taken from ffmpegcolorspace too */
2024   for (i = 0; i < width; i++) {
2025     /* crude approximation for alpha ! */
2026     if (s[i * 4 + 0] < 0x80)
2027       d[i] = 6 * 6 * 6;
2028     else
2029       d[i] =
2030           ((((s[i * 4 + 1]) / 47) % 6) * 6 * 6 + (((s[i * 4 +
2031                           2]) / 47) % 6) * 6 + (((s[i * 4 + 3]) / 47) % 6));
2032   }
2033 }
2034
2035 #define PACK_410 GST_VIDEO_FORMAT_AYUV, unpack_410, 1, pack_410
2036 static void
2037 unpack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2038     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2039     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2040 {
2041   gint uv = GET_UV_410 (y, flags);
2042   const guint8 *restrict sy = GET_Y_LINE (y);
2043   const guint8 *restrict su = GET_U_LINE (uv);
2044   const guint8 *restrict sv = GET_V_LINE (uv);
2045   guint8 *restrict d = dest;
2046
2047   sy += x;
2048   su += x >> 2;
2049   sv += x >> 2;
2050
2051   if (x & 3) {
2052     for (; x & 3; x++) {
2053       d[0] = 0xff;
2054       d[1] = *sy++;
2055       d[2] = *su;
2056       d[3] = *sv;
2057       width--;
2058       d += 4;
2059     }
2060     su++;
2061     sy++;
2062   }
2063
2064   if (IS_ALIGNED (d, 8))
2065     video_orc_unpack_YUV9 (d, sy, su, sv, width / 2);
2066   else {
2067     gint i;
2068     for (i = 0; i < width / 2; i++) {
2069       d[i * 8 + 0] = 0xff;
2070       d[i * 8 + 1] = sy[i * 2 + 0];
2071       d[i * 8 + 2] = su[i >> 1];
2072       d[i * 8 + 3] = sv[i >> 1];
2073       d[i * 8 + 4] = 0xff;
2074       d[i * 8 + 5] = sy[i * 2 + 1];
2075       d[i * 8 + 6] = su[i >> 1];
2076       d[i * 8 + 7] = sv[i >> 1];
2077     }
2078   }
2079
2080   if (width & 1) {
2081     gint i = width - 1;
2082
2083     d[i * 4 + 0] = 0xff;
2084     d[i * 4 + 1] = sy[i];
2085     d[i * 4 + 2] = su[i >> 2];
2086     d[i * 4 + 3] = sv[i >> 2];
2087   }
2088 }
2089
2090 static void
2091 pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2092     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2093     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2094     gint y, gint width)
2095 {
2096   int i;
2097   gint uv = GET_UV_410 (y, flags);
2098   guint8 *restrict dy = GET_Y_LINE (y);
2099   guint8 *restrict du = GET_U_LINE (uv);
2100   guint8 *restrict dv = GET_V_LINE (uv);
2101   const guint8 *restrict s = src;
2102
2103   for (i = 0; i < width - 3; i += 4) {
2104     dy[i] = s[i * 4 + 1];
2105     dy[i + 1] = s[i * 4 + 5];
2106     dy[i + 2] = s[i * 4 + 9];
2107     dy[i + 3] = s[i * 4 + 13];
2108     if (IS_CHROMA_LINE_410 (y, flags)) {
2109       du[i >> 2] = s[i * 4 + 2];
2110       dv[i >> 2] = s[i * 4 + 3];
2111     }
2112   }
2113   if (i < width) {
2114     dy[i] = s[i * 4 + 1];
2115     if (IS_CHROMA_LINE_410 (y, flags)) {
2116       du[i >> 2] = s[i * 4 + 2];
2117       dv[i >> 2] = s[i * 4 + 3];
2118     }
2119     if (i < width - 1)
2120       dy[i + 1] = s[i * 4 + 5];
2121     if (i < width - 2)
2122       dy[i + 2] = s[i * 4 + 9];
2123   }
2124 }
2125
2126 #define PACK_IYU1 GST_VIDEO_FORMAT_AYUV, unpack_IYU1, 1, pack_IYU1
2127 static void
2128 unpack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2129     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2130     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2131 {
2132   int i;
2133   const guint8 *restrict s = GET_LINE (y);
2134   guint8 *restrict d = dest;
2135   guint8 y0, y1, y2, y3;
2136   guint8 u0;
2137   guint8 v0;
2138
2139   /* FIXME */
2140   s += x * 4;
2141
2142   for (i = 0; i < width - 3; i += 4) {
2143     y0 = s[(i >> 2) * 6 + 1];
2144     y1 = s[(i >> 2) * 6 + 2];
2145     y2 = s[(i >> 2) * 6 + 4];
2146     y3 = s[(i >> 2) * 6 + 5];
2147
2148     u0 = s[(i >> 2) * 6 + 0];
2149     v0 = s[(i >> 2) * 6 + 3];
2150
2151     d[i * 4 + 0] = 0xff;
2152     d[i * 4 + 1] = y0;
2153     d[i * 4 + 2] = u0;
2154     d[i * 4 + 3] = v0;
2155
2156     d[i * 4 + 4] = 0xff;
2157     d[i * 4 + 5] = y1;
2158     d[i * 4 + 6] = u0;
2159     d[i * 4 + 7] = v0;
2160
2161     d[i * 4 + 8] = 0xff;
2162     d[i * 4 + 9] = y2;
2163     d[i * 4 + 10] = u0;
2164     d[i * 4 + 11] = v0;
2165
2166     d[i * 4 + 12] = 0xff;
2167     d[i * 4 + 13] = y3;
2168     d[i * 4 + 14] = u0;
2169     d[i * 4 + 15] = v0;
2170   }
2171   if (i < width) {
2172     u0 = s[(i >> 2) * 6 + 0];
2173     v0 = s[(i >> 2) * 6 + 3];
2174
2175     d[i * 4 + 0] = 0xff;
2176     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
2177     d[i * 4 + 2] = u0;
2178     d[i * 4 + 3] = v0;
2179
2180     if (i < width - 1) {
2181       d[i * 4 + 4] = 0xff;
2182       d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
2183       d[i * 4 + 6] = u0;
2184       d[i * 4 + 7] = v0;
2185     }
2186     if (i < width - 2) {
2187       d[i * 4 + 8] = 0xff;
2188       d[i * 4 + 9] = s[(i >> 2) * 6 + 4];
2189       d[i * 4 + 10] = u0;
2190       d[i * 4 + 11] = v0;
2191     }
2192   }
2193 }
2194
2195 static void
2196 pack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2197     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2198     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2199     gint y, gint width)
2200 {
2201   int i;
2202   guint8 *restrict d = GET_LINE (y);
2203   const guint8 *restrict s = src;
2204
2205   for (i = 0; i < width - 3; i += 4) {
2206     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
2207     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
2208     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
2209     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
2210     d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
2211     d[(i >> 2) * 6 + 5] = s[i * 4 + 13];
2212   }
2213   if (i < width) {
2214     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
2215     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
2216     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
2217     if (i < width - 1)
2218       d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
2219     if (i < width - 2)
2220       d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
2221   }
2222 }
2223
2224 #define PACK_ARGB64 GST_VIDEO_FORMAT_ARGB64, unpack_copy8, 1, pack_copy8
2225 #define PACK_AYUV64 GST_VIDEO_FORMAT_AYUV64, unpack_copy8, 1, pack_copy8
2226 static void
2227 unpack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2228     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2229     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2230 {
2231   const guint8 *s = GET_LINE (y);
2232
2233   s += x * 8;
2234
2235   memcpy (dest, s, width * 8);
2236 }
2237
2238 static void
2239 pack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2240     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2241     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2242     gint y, gint width)
2243 {
2244   guint8 *restrict d = GET_LINE (y);
2245
2246   memcpy (d, src, width * 8);
2247 }
2248
2249 #define PACK_r210 GST_VIDEO_FORMAT_ARGB64, unpack_r210, 1, pack_r210
2250 static void
2251 unpack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2252     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2253     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2254 {
2255   int i;
2256   const guint8 *restrict s = GET_LINE (y);
2257   guint16 *restrict d = dest, R, G, B;
2258
2259   s += x * 4;
2260
2261   for (i = 0; i < width; i++) {
2262     guint32 x = GST_READ_UINT32_BE (s + i * 4);
2263
2264     R = ((x >> 14) & 0xffc0);
2265     G = ((x >> 4) & 0xffc0);
2266     B = ((x << 6) & 0xffc0);
2267
2268     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2269       R |= (R >> 10);
2270       G |= (G >> 10);
2271       B |= (B >> 10);
2272     }
2273
2274     d[i * 4 + 0] = 0xffff;
2275     d[i * 4 + 1] = R;
2276     d[i * 4 + 2] = G;
2277     d[i * 4 + 3] = B;
2278   }
2279 }
2280
2281 static void
2282 pack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2283     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2284     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2285     gint y, gint width)
2286 {
2287   int i;
2288   guint8 *restrict d = GET_LINE (y);
2289   const guint16 *restrict s = src;
2290
2291   for (i = 0; i < width; i++) {
2292     guint32 x = 0;
2293     x |= (s[i * 4 + 1] & 0xffc0) << 14;
2294     x |= (s[i * 4 + 2] & 0xffc0) << 4;
2295     x |= (s[i * 4 + 3] & 0xffc0) >> 6;
2296     GST_WRITE_UINT32_BE (d + i * 4, x);
2297   }
2298 }
2299
2300 #define PACK_GBR_10LE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10LE, 1, pack_GBR_10LE
2301 static void
2302 unpack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2303     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2304     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2305 {
2306   int i;
2307   const guint16 *sg = GET_G_LINE (y);
2308   const guint16 *sb = GET_B_LINE (y);
2309   const guint16 *sr = GET_R_LINE (y);
2310   guint16 *d = dest, G, B, R;
2311
2312   sg += x;
2313   sb += x;
2314   sr += x;
2315
2316   for (i = 0; i < width; i++) {
2317     G = GST_READ_UINT16_LE (sg + i) << 6;
2318     B = GST_READ_UINT16_LE (sb + i) << 6;
2319     R = GST_READ_UINT16_LE (sr + i) << 6;
2320
2321     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2322       R |= (R >> 10);
2323       G |= (G >> 10);
2324       B |= (B >> 10);
2325     }
2326
2327     d[i * 4 + 0] = 0xffff;
2328     d[i * 4 + 1] = R;
2329     d[i * 4 + 2] = G;
2330     d[i * 4 + 3] = B;
2331   }
2332 }
2333
2334 static void
2335 pack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2336     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2337     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2338     gint y, gint width)
2339 {
2340   int i;
2341   guint16 *restrict dg = GET_G_LINE (y);
2342   guint16 *restrict db = GET_B_LINE (y);
2343   guint16 *restrict dr = GET_R_LINE (y);
2344   guint16 G, B, R;
2345   const guint16 *restrict s = src;
2346
2347   for (i = 0; i < width; i++) {
2348     G = (s[i * 4 + 2]) >> 6;
2349     B = (s[i * 4 + 3]) >> 6;
2350     R = (s[i * 4 + 1]) >> 6;
2351
2352     GST_WRITE_UINT16_LE (dg + i, G);
2353     GST_WRITE_UINT16_LE (db + i, B);
2354     GST_WRITE_UINT16_LE (dr + i, R);
2355   }
2356 }
2357
2358 #define PACK_GBR_10BE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10BE, 1, pack_GBR_10BE
2359 static void
2360 unpack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2361     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2362     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2363 {
2364   int i;
2365   const guint16 *restrict sg = GET_G_LINE (y);
2366   const guint16 *restrict sb = GET_B_LINE (y);
2367   const guint16 *restrict sr = GET_R_LINE (y);
2368   guint16 *restrict d = dest, G, B, R;
2369
2370   sg += x;
2371   sb += x;
2372   sr += x;
2373
2374   for (i = 0; i < width; i++) {
2375     G = GST_READ_UINT16_BE (sg + i) << 6;
2376     B = GST_READ_UINT16_BE (sb + i) << 6;
2377     R = GST_READ_UINT16_BE (sr + i) << 6;
2378
2379     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2380       R |= (R >> 10);
2381       G |= (G >> 10);
2382       B |= (B >> 10);
2383     }
2384
2385     d[i * 4 + 0] = 0xffff;
2386     d[i * 4 + 1] = R;
2387     d[i * 4 + 2] = G;
2388     d[i * 4 + 3] = B;
2389   }
2390 }
2391
2392 static void
2393 pack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2394     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2395     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2396     gint y, gint width)
2397 {
2398   int i;
2399   guint16 *restrict dg = GET_G_LINE (y);
2400   guint16 *restrict db = GET_B_LINE (y);
2401   guint16 *restrict dr = GET_R_LINE (y);
2402   guint16 G, B, R;
2403   const guint16 *restrict s = src;
2404
2405   for (i = 0; i < width; i++) {
2406     G = s[i * 4 + 2] >> 6;
2407     B = s[i * 4 + 3] >> 6;
2408     R = s[i * 4 + 1] >> 6;
2409
2410     GST_WRITE_UINT16_BE (dg + i, G);
2411     GST_WRITE_UINT16_BE (db + i, B);
2412     GST_WRITE_UINT16_BE (dr + i, R);
2413   }
2414 }
2415
2416 #define PACK_GBRA_10LE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_10LE, 1, pack_GBRA_10LE
2417 static void
2418 unpack_GBRA_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2419     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2420     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2421 {
2422   int i;
2423   const guint16 *sg = GET_G_LINE (y);
2424   const guint16 *sb = GET_B_LINE (y);
2425   const guint16 *sr = GET_R_LINE (y);
2426   const guint16 *sa = GET_A_LINE (y);
2427   guint16 *d = dest, G, B, R, A;
2428
2429   sg += x;
2430   sb += x;
2431   sr += x;
2432   sa += x;
2433
2434   for (i = 0; i < width; i++) {
2435     G = GST_READ_UINT16_LE (sg + i) << 6;
2436     B = GST_READ_UINT16_LE (sb + i) << 6;
2437     R = GST_READ_UINT16_LE (sr + i) << 6;
2438     A = GST_READ_UINT16_LE (sa + i) << 6;
2439
2440     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2441       R |= (R >> 10);
2442       G |= (G >> 10);
2443       B |= (B >> 10);
2444       A |= (A >> 10);
2445     }
2446
2447     d[i * 4 + 0] = A;
2448     d[i * 4 + 1] = R;
2449     d[i * 4 + 2] = G;
2450     d[i * 4 + 3] = B;
2451   }
2452 }
2453
2454 static void
2455 pack_GBRA_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2456     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2457     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2458     gint y, gint width)
2459 {
2460   int i;
2461   guint16 *restrict dg = GET_G_LINE (y);
2462   guint16 *restrict db = GET_B_LINE (y);
2463   guint16 *restrict dr = GET_R_LINE (y);
2464   guint16 *restrict da = GET_A_LINE (y);
2465   guint16 G, B, R, A;
2466   const guint16 *restrict s = src;
2467
2468   for (i = 0; i < width; i++) {
2469     G = (s[i * 4 + 2]) >> 6;
2470     B = (s[i * 4 + 3]) >> 6;
2471     R = (s[i * 4 + 1]) >> 6;
2472     A = (s[i * 4 + 0]) >> 6;
2473
2474     GST_WRITE_UINT16_LE (dg + i, G);
2475     GST_WRITE_UINT16_LE (db + i, B);
2476     GST_WRITE_UINT16_LE (dr + i, R);
2477     GST_WRITE_UINT16_LE (da + i, A);
2478   }
2479 }
2480
2481 #define PACK_GBRA_10BE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_10BE, 1, pack_GBRA_10BE
2482 static void
2483 unpack_GBRA_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2484     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2485     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2486 {
2487   int i;
2488   const guint16 *restrict sg = GET_G_LINE (y);
2489   const guint16 *restrict sb = GET_B_LINE (y);
2490   const guint16 *restrict sr = GET_R_LINE (y);
2491   const guint16 *restrict sa = GET_A_LINE (y);
2492   guint16 *restrict d = dest, G, B, R, A;
2493
2494   sg += x;
2495   sb += x;
2496   sr += x;
2497   sa += x;
2498
2499   for (i = 0; i < width; i++) {
2500     G = GST_READ_UINT16_BE (sg + i) << 6;
2501     B = GST_READ_UINT16_BE (sb + i) << 6;
2502     R = GST_READ_UINT16_BE (sr + i) << 6;
2503     A = GST_READ_UINT16_BE (sa + i) << 6;
2504
2505     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2506       R |= (R >> 10);
2507       G |= (G >> 10);
2508       B |= (B >> 10);
2509       A |= (A >> 10);
2510     }
2511
2512     d[i * 4 + 0] = A;
2513     d[i * 4 + 1] = R;
2514     d[i * 4 + 2] = G;
2515     d[i * 4 + 3] = B;
2516   }
2517 }
2518
2519 static void
2520 pack_GBRA_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2521     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2522     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2523     gint y, gint width)
2524 {
2525   int i;
2526   guint16 *restrict dg = GET_G_LINE (y);
2527   guint16 *restrict db = GET_B_LINE (y);
2528   guint16 *restrict dr = GET_R_LINE (y);
2529   guint16 *restrict da = GET_A_LINE (y);
2530   guint16 G, B, R, A;
2531   const guint16 *restrict s = src;
2532
2533   for (i = 0; i < width; i++) {
2534     G = s[i * 4 + 2] >> 6;
2535     B = s[i * 4 + 3] >> 6;
2536     R = s[i * 4 + 1] >> 6;
2537     A = s[i * 4 + 0] >> 6;
2538
2539     GST_WRITE_UINT16_BE (dg + i, G);
2540     GST_WRITE_UINT16_BE (db + i, B);
2541     GST_WRITE_UINT16_BE (dr + i, R);
2542     GST_WRITE_UINT16_BE (da + i, A);
2543   }
2544 }
2545
2546 #define PACK_GBR_12LE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_12LE, 1, pack_GBR_12LE
2547 static void
2548 unpack_GBR_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2549     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2550     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2551 {
2552   int i;
2553   const guint16 *sg = GET_G_LINE (y);
2554   const guint16 *sb = GET_B_LINE (y);
2555   const guint16 *sr = GET_R_LINE (y);
2556   guint16 *d = dest, G, B, R;
2557
2558   sg += x;
2559   sb += x;
2560   sr += x;
2561
2562   for (i = 0; i < width; i++) {
2563     G = GST_READ_UINT16_LE (sg + i) << 4;
2564     B = GST_READ_UINT16_LE (sb + i) << 4;
2565     R = GST_READ_UINT16_LE (sr + i) << 4;
2566
2567     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2568       R |= (R >> 12);
2569       G |= (G >> 12);
2570       B |= (B >> 12);
2571     }
2572
2573     d[i * 4 + 0] = 0xffff;
2574     d[i * 4 + 1] = R;
2575     d[i * 4 + 2] = G;
2576     d[i * 4 + 3] = B;
2577   }
2578 }
2579
2580 static void
2581 pack_GBR_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2582     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2583     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2584     gint y, gint width)
2585 {
2586   int i;
2587   guint16 *restrict dg = GET_G_LINE (y);
2588   guint16 *restrict db = GET_B_LINE (y);
2589   guint16 *restrict dr = GET_R_LINE (y);
2590   guint16 G, B, R;
2591   const guint16 *restrict s = src;
2592
2593   for (i = 0; i < width; i++) {
2594     G = (s[i * 4 + 2]) >> 4;
2595     B = (s[i * 4 + 3]) >> 4;
2596     R = (s[i * 4 + 1]) >> 4;
2597
2598     GST_WRITE_UINT16_LE (dg + i, G);
2599     GST_WRITE_UINT16_LE (db + i, B);
2600     GST_WRITE_UINT16_LE (dr + i, R);
2601   }
2602 }
2603
2604 #define PACK_GBR_12BE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_12BE, 1, pack_GBR_12BE
2605 static void
2606 unpack_GBR_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2607     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2608     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2609 {
2610   int i;
2611   const guint16 *restrict sg = GET_G_LINE (y);
2612   const guint16 *restrict sb = GET_B_LINE (y);
2613   const guint16 *restrict sr = GET_R_LINE (y);
2614   guint16 *restrict d = dest, G, B, R;
2615
2616   sg += x;
2617   sb += x;
2618   sr += x;
2619
2620   for (i = 0; i < width; i++) {
2621     G = GST_READ_UINT16_BE (sg + i) << 4;
2622     B = GST_READ_UINT16_BE (sb + i) << 4;
2623     R = GST_READ_UINT16_BE (sr + i) << 4;
2624
2625     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2626       R |= (R >> 12);
2627       G |= (G >> 12);
2628       B |= (B >> 12);
2629     }
2630
2631     d[i * 4 + 0] = 0xffff;
2632     d[i * 4 + 1] = R;
2633     d[i * 4 + 2] = G;
2634     d[i * 4 + 3] = B;
2635   }
2636 }
2637
2638 static void
2639 pack_GBR_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2640     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2641     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2642     gint y, gint width)
2643 {
2644   int i;
2645   guint16 *restrict dg = GET_G_LINE (y);
2646   guint16 *restrict db = GET_B_LINE (y);
2647   guint16 *restrict dr = GET_R_LINE (y);
2648   guint16 G, B, R;
2649   const guint16 *restrict s = src;
2650
2651   for (i = 0; i < width; i++) {
2652     G = s[i * 4 + 2] >> 4;
2653     B = s[i * 4 + 3] >> 4;
2654     R = s[i * 4 + 1] >> 4;
2655
2656     GST_WRITE_UINT16_BE (dg + i, G);
2657     GST_WRITE_UINT16_BE (db + i, B);
2658     GST_WRITE_UINT16_BE (dr + i, R);
2659   }
2660 }
2661
2662 #define PACK_GBRA_12LE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_12LE, 1, pack_GBRA_12LE
2663 static void
2664 unpack_GBRA_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2665     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2666     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2667 {
2668   int i;
2669   const guint16 *sg = GET_G_LINE (y);
2670   const guint16 *sb = GET_B_LINE (y);
2671   const guint16 *sr = GET_R_LINE (y);
2672   const guint16 *sa = GET_A_LINE (y);
2673   guint16 *d = dest, G, B, R, A;
2674
2675   sg += x;
2676   sb += x;
2677   sr += x;
2678   sa += x;
2679
2680   for (i = 0; i < width; i++) {
2681     G = GST_READ_UINT16_LE (sg + i) << 4;
2682     B = GST_READ_UINT16_LE (sb + i) << 4;
2683     R = GST_READ_UINT16_LE (sr + i) << 4;
2684     A = GST_READ_UINT16_LE (sa + i) << 4;
2685
2686     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2687       A |= (A >> 12);
2688       R |= (R >> 12);
2689       G |= (G >> 12);
2690       B |= (B >> 12);
2691     }
2692
2693     d[i * 4 + 0] = A;
2694     d[i * 4 + 1] = R;
2695     d[i * 4 + 2] = G;
2696     d[i * 4 + 3] = B;
2697   }
2698 }
2699
2700 static void
2701 pack_GBRA_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2702     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2703     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2704     gint y, gint width)
2705 {
2706   int i;
2707   guint16 *restrict dg = GET_G_LINE (y);
2708   guint16 *restrict db = GET_B_LINE (y);
2709   guint16 *restrict dr = GET_R_LINE (y);
2710   guint16 *restrict da = GET_A_LINE (y);
2711   guint16 G, B, R, A;
2712   const guint16 *restrict s = src;
2713
2714   for (i = 0; i < width; i++) {
2715     G = (s[i * 4 + 2]) >> 4;
2716     B = (s[i * 4 + 3]) >> 4;
2717     R = (s[i * 4 + 1]) >> 4;
2718     A = (s[i * 4 + 0]) >> 4;
2719
2720     GST_WRITE_UINT16_LE (dg + i, G);
2721     GST_WRITE_UINT16_LE (db + i, B);
2722     GST_WRITE_UINT16_LE (dr + i, R);
2723     GST_WRITE_UINT16_LE (da + i, A);
2724   }
2725 }
2726
2727 #define PACK_GBRA_12BE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_12BE, 1, pack_GBRA_12BE
2728 static void
2729 unpack_GBRA_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2730     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2731     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2732 {
2733   int i;
2734   const guint16 *restrict sg = GET_G_LINE (y);
2735   const guint16 *restrict sb = GET_B_LINE (y);
2736   const guint16 *restrict sr = GET_R_LINE (y);
2737   const guint16 *restrict sa = GET_A_LINE (y);
2738   guint16 *restrict d = dest, G, B, R, A;
2739
2740   sg += x;
2741   sb += x;
2742   sr += x;
2743   sa += x;
2744
2745   for (i = 0; i < width; i++) {
2746     G = GST_READ_UINT16_BE (sg + i) << 4;
2747     B = GST_READ_UINT16_BE (sb + i) << 4;
2748     R = GST_READ_UINT16_BE (sr + i) << 4;
2749     A = GST_READ_UINT16_BE (sa + i) << 4;
2750
2751     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2752       R |= (R >> 12);
2753       G |= (G >> 12);
2754       B |= (B >> 12);
2755       A |= (A >> 12);
2756     }
2757
2758     d[i * 4 + 0] = A;
2759     d[i * 4 + 1] = R;
2760     d[i * 4 + 2] = G;
2761     d[i * 4 + 3] = B;
2762   }
2763 }
2764
2765 static void
2766 pack_GBRA_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2767     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2768     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2769     gint y, gint width)
2770 {
2771   int i;
2772   guint16 *restrict dg = GET_G_LINE (y);
2773   guint16 *restrict db = GET_B_LINE (y);
2774   guint16 *restrict dr = GET_R_LINE (y);
2775   guint16 *restrict da = GET_A_LINE (y);
2776   guint16 G, B, R, A;
2777   const guint16 *restrict s = src;
2778
2779   for (i = 0; i < width; i++) {
2780     G = s[i * 4 + 2] >> 4;
2781     B = s[i * 4 + 3] >> 4;
2782     R = s[i * 4 + 1] >> 4;
2783     A = s[i * 4 + 0] >> 4;
2784
2785     GST_WRITE_UINT16_BE (dg + i, G);
2786     GST_WRITE_UINT16_BE (db + i, B);
2787     GST_WRITE_UINT16_BE (dr + i, R);
2788     GST_WRITE_UINT16_BE (da + i, A);
2789   }
2790 }
2791
2792 #define PACK_Y444_10LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10LE, 1, pack_Y444_10LE
2793 static void
2794 unpack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2795     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2796     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2797 {
2798   int i;
2799   guint16 *restrict sy = GET_Y_LINE (y);
2800   guint16 *restrict su = GET_U_LINE (y);
2801   guint16 *restrict sv = GET_V_LINE (y);
2802   guint16 *restrict d = dest, Y, U, V;
2803
2804   sy += x;
2805   su += x;
2806   sv += x;
2807
2808   for (i = 0; i < width; i++) {
2809     Y = GST_READ_UINT16_LE (sy + i) << 6;
2810     U = GST_READ_UINT16_LE (su + i) << 6;
2811     V = GST_READ_UINT16_LE (sv + i) << 6;
2812
2813     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2814       Y |= (Y >> 10);
2815       U |= (U >> 10);
2816       V |= (V >> 10);
2817     }
2818
2819     d[i * 4 + 0] = 0xffff;
2820     d[i * 4 + 1] = Y;
2821     d[i * 4 + 2] = U;
2822     d[i * 4 + 3] = V;
2823   }
2824 }
2825
2826 static void
2827 pack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2828     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2829     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2830     gint y, gint width)
2831 {
2832   int i;
2833   guint16 *restrict dy = GET_Y_LINE (y);
2834   guint16 *restrict du = GET_U_LINE (y);
2835   guint16 *restrict dv = GET_V_LINE (y);
2836   guint16 Y, U, V;
2837   const guint16 *restrict s = src;
2838
2839   for (i = 0; i < width; i++) {
2840     Y = (s[i * 4 + 1]) >> 6;
2841     U = (s[i * 4 + 2]) >> 6;
2842     V = (s[i * 4 + 3]) >> 6;
2843
2844     GST_WRITE_UINT16_LE (dy + i, Y);
2845     GST_WRITE_UINT16_LE (du + i, U);
2846     GST_WRITE_UINT16_LE (dv + i, V);
2847   }
2848 }
2849
2850 #define PACK_Y444_10BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10BE, 1, pack_Y444_10BE
2851 static void
2852 unpack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2853     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2854     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2855 {
2856   int i;
2857   const guint16 *restrict sy = GET_Y_LINE (y);
2858   const guint16 *restrict su = GET_U_LINE (y);
2859   const guint16 *restrict sv = GET_V_LINE (y);
2860   guint16 *restrict d = dest, Y, U, V;
2861
2862   sy += x;
2863   su += x;
2864   sv += x;
2865
2866   for (i = 0; i < width; i++) {
2867     Y = GST_READ_UINT16_BE (sy + i) << 6;
2868     U = GST_READ_UINT16_BE (su + i) << 6;
2869     V = GST_READ_UINT16_BE (sv + i) << 6;
2870
2871     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2872       Y |= (Y >> 10);
2873       U |= (U >> 10);
2874       V |= (V >> 10);
2875     }
2876
2877     d[i * 4 + 0] = 0xffff;
2878     d[i * 4 + 1] = Y;
2879     d[i * 4 + 2] = U;
2880     d[i * 4 + 3] = V;
2881   }
2882 }
2883
2884 static void
2885 pack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2886     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2887     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2888     gint y, gint width)
2889 {
2890   int i;
2891   guint16 *restrict dy = GET_Y_LINE (y);
2892   guint16 *restrict du = GET_U_LINE (y);
2893   guint16 *restrict dv = GET_V_LINE (y);
2894   guint16 Y, U, V;
2895   const guint16 *restrict s = src;
2896
2897   for (i = 0; i < width; i++) {
2898     Y = s[i * 4 + 1] >> 6;
2899     U = s[i * 4 + 2] >> 6;
2900     V = s[i * 4 + 3] >> 6;
2901
2902     GST_WRITE_UINT16_BE (dy + i, Y);
2903     GST_WRITE_UINT16_BE (du + i, U);
2904     GST_WRITE_UINT16_BE (dv + i, V);
2905   }
2906 }
2907
2908 #define PACK_I420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10LE, 1, pack_I420_10LE
2909 static void
2910 unpack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2911     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2912     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2913 {
2914   int i;
2915   gint uv = GET_UV_420 (y, flags);
2916   const guint16 *restrict sy = GET_Y_LINE (y);
2917   const guint16 *restrict su = GET_U_LINE (uv);
2918   const guint16 *restrict sv = GET_V_LINE (uv);
2919   guint16 *restrict d = dest, Y, U, V;
2920
2921   sy += x;
2922   su += x >> 1;
2923   sv += x >> 1;
2924
2925   for (i = 0; i < width; i++) {
2926     Y = GST_READ_UINT16_LE (sy + i) << 6;
2927     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
2928     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
2929
2930     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2931       Y |= (Y >> 10);
2932       U |= (U >> 10);
2933       V |= (V >> 10);
2934     }
2935
2936     d[i * 4 + 0] = 0xffff;
2937     d[i * 4 + 1] = Y;
2938     d[i * 4 + 2] = U;
2939     d[i * 4 + 3] = V;
2940
2941     if (x & 1) {
2942       x = 0;
2943       su++;
2944       sv++;
2945     }
2946   }
2947 }
2948
2949 static void
2950 pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2951     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2952     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2953     gint y, gint width)
2954 {
2955   int i;
2956   gint uv = GET_UV_420 (y, flags);
2957   guint16 *restrict dy = GET_Y_LINE (y);
2958   guint16 *restrict du = GET_U_LINE (uv);
2959   guint16 *restrict dv = GET_V_LINE (uv);
2960   guint16 Y0, Y1, U, V;
2961   const guint16 *restrict s = src;
2962
2963   if (IS_CHROMA_LINE_420 (y, flags)) {
2964     for (i = 0; i < width - 1; i += 2) {
2965       Y0 = s[i * 4 + 1] >> 6;
2966       Y1 = s[i * 4 + 5] >> 6;
2967       U = s[i * 4 + 2] >> 6;
2968       V = s[i * 4 + 3] >> 6;
2969
2970       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
2971       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
2972       GST_WRITE_UINT16_LE (du + (i >> 1), U);
2973       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
2974     }
2975     if (i == width - 1) {
2976       Y0 = s[i * 4 + 1] >> 6;
2977       U = s[i * 4 + 2] >> 6;
2978       V = s[i * 4 + 3] >> 6;
2979
2980       GST_WRITE_UINT16_LE (dy + i, Y0);
2981       GST_WRITE_UINT16_LE (du + (i >> 1), U);
2982       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
2983     }
2984   } else {
2985     for (i = 0; i < width; i++) {
2986       Y0 = s[i * 4 + 1] >> 6;
2987       GST_WRITE_UINT16_LE (dy + i, Y0);
2988     }
2989   }
2990 }
2991
2992 #define PACK_I420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10BE, 1, pack_I420_10BE
2993 static void
2994 unpack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2995     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2996     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2997 {
2998   int i;
2999   gint uv = GET_UV_420 (y, flags);
3000   const guint16 *restrict sy = GET_Y_LINE (y);
3001   const guint16 *restrict su = GET_U_LINE (uv);
3002   const guint16 *restrict sv = GET_V_LINE (uv);
3003   guint16 *restrict d = dest, Y, U, V;
3004
3005   sy += x;
3006   su += x >> 1;
3007   sv += x >> 1;
3008
3009   for (i = 0; i < width; i++) {
3010     Y = GST_READ_UINT16_BE (sy + i) << 6;
3011     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3012     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3013
3014     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3015       Y |= (Y >> 10);
3016       U |= (U >> 10);
3017       V |= (V >> 10);
3018     }
3019
3020     d[i * 4 + 0] = 0xffff;
3021     d[i * 4 + 1] = Y;
3022     d[i * 4 + 2] = U;
3023     d[i * 4 + 3] = V;
3024
3025     if (x & 1) {
3026       x = 0;
3027       su++;
3028       sv++;
3029     }
3030   }
3031 }
3032
3033 static void
3034 pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3035     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3036     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3037     gint y, gint width)
3038 {
3039   int i;
3040   gint uv = GET_UV_420 (y, flags);
3041   guint16 *restrict dy = GET_Y_LINE (y);
3042   guint16 *restrict du = GET_U_LINE (uv);
3043   guint16 *restrict dv = GET_V_LINE (uv);
3044   guint16 Y0, Y1, U, V;
3045   const guint16 *restrict s = src;
3046
3047   if (IS_CHROMA_LINE_420 (y, flags)) {
3048     for (i = 0; i < width - 1; i += 2) {
3049       Y0 = s[i * 4 + 1] >> 6;
3050       Y1 = s[i * 4 + 5] >> 6;
3051       U = s[i * 4 + 2] >> 6;
3052       V = s[i * 4 + 3] >> 6;
3053
3054       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3055       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3056       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3057       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3058     }
3059     if (i == width - 1) {
3060       Y0 = s[i * 4 + 1] >> 6;
3061       U = s[i * 4 + 2] >> 6;
3062       V = s[i * 4 + 3] >> 6;
3063
3064       GST_WRITE_UINT16_BE (dy + i, Y0);
3065       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3066       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3067     }
3068   } else {
3069     for (i = 0; i < width; i++) {
3070       Y0 = s[i * 4 + 1] >> 6;
3071       GST_WRITE_UINT16_BE (dy + i, Y0);
3072     }
3073   }
3074 }
3075
3076 #define PACK_I422_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10LE, 1, pack_I422_10LE
3077 static void
3078 unpack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3079     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3080     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3081 {
3082   int i;
3083   const guint16 *restrict sy = GET_Y_LINE (y);
3084   const guint16 *restrict su = GET_U_LINE (y);
3085   const guint16 *restrict sv = GET_V_LINE (y);
3086   guint16 *restrict d = dest, Y, U, V;
3087
3088   sy += x;
3089   su += x >> 1;
3090   sv += x >> 1;
3091
3092   for (i = 0; i < width; i++) {
3093     Y = GST_READ_UINT16_LE (sy + i) << 6;
3094     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
3095     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
3096
3097     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3098       Y |= (Y >> 10);
3099       U |= (U >> 10);
3100       V |= (V >> 10);
3101     }
3102
3103     d[i * 4 + 0] = 0xffff;
3104     d[i * 4 + 1] = Y;
3105     d[i * 4 + 2] = U;
3106     d[i * 4 + 3] = V;
3107
3108     if (x & 1) {
3109       x = 0;
3110       su++;
3111       sv++;
3112     }
3113   }
3114 }
3115
3116 static void
3117 pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3118     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3119     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3120     gint y, gint width)
3121 {
3122   int i;
3123   guint16 *restrict dy = GET_Y_LINE (y);
3124   guint16 *restrict du = GET_U_LINE (y);
3125   guint16 *restrict dv = GET_V_LINE (y);
3126   guint16 Y0, Y1, U, V;
3127   const guint16 *restrict s = src;
3128
3129   for (i = 0; i < width - 1; i += 2) {
3130     Y0 = s[i * 4 + 1] >> 6;
3131     Y1 = s[i * 4 + 5] >> 6;
3132     U = s[i * 4 + 2] >> 6;
3133     V = s[i * 4 + 3] >> 6;
3134
3135     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3136     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3137     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3138     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3139   }
3140   if (i == width - 1) {
3141     Y0 = s[i * 4 + 1] >> 6;
3142     U = s[i * 4 + 2] >> 6;
3143     V = s[i * 4 + 3] >> 6;
3144
3145     GST_WRITE_UINT16_LE (dy + i, Y0);
3146     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3147     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3148   }
3149 }
3150
3151 #define PACK_I422_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10BE, 1, pack_I422_10BE
3152 static void
3153 unpack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3154     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3155     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3156 {
3157   int i;
3158   const guint16 *restrict sy = GET_Y_LINE (y);
3159   const guint16 *restrict su = GET_U_LINE (y);
3160   const guint16 *restrict sv = GET_V_LINE (y);
3161   guint16 *restrict d = dest, Y, U, V;
3162
3163   sy += x;
3164   su += x >> 1;
3165   sv += x >> 1;
3166
3167   for (i = 0; i < width; i++) {
3168     Y = GST_READ_UINT16_BE (sy + i) << 6;
3169     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3170     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3171
3172     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3173       Y |= (Y >> 10);
3174       U |= (U >> 10);
3175       V |= (V >> 10);
3176     }
3177
3178     d[i * 4 + 0] = 0xffff;
3179     d[i * 4 + 1] = Y;
3180     d[i * 4 + 2] = U;
3181     d[i * 4 + 3] = V;
3182
3183     if (x & 1) {
3184       x = 0;
3185       su++;
3186       sv++;
3187     }
3188   }
3189 }
3190
3191 static void
3192 pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3193     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3194     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3195     gint y, gint width)
3196 {
3197   int i;
3198   guint16 *restrict dy = GET_Y_LINE (y);
3199   guint16 *restrict du = GET_U_LINE (y);
3200   guint16 *restrict dv = GET_V_LINE (y);
3201   guint16 Y0, Y1, U, V;
3202   const guint16 *restrict s = src;
3203
3204   for (i = 0; i < width - 1; i += 2) {
3205     Y0 = s[i * 4 + 1] >> 6;
3206     Y1 = s[i * 4 + 5] >> 6;
3207     U = s[i * 4 + 2] >> 6;
3208     V = s[i * 4 + 3] >> 6;
3209
3210     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3211     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3212     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3213     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3214   }
3215   if (i == width - 1) {
3216     Y0 = s[i * 4 + 1] >> 6;
3217     U = s[i * 4 + 2] >> 6;
3218     V = s[i * 4 + 3] >> 6;
3219
3220     GST_WRITE_UINT16_BE (dy + i, Y0);
3221     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3222     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3223   }
3224 }
3225
3226 #define PACK_Y444_12LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_12LE, 1, pack_Y444_12LE
3227 static void
3228 unpack_Y444_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3229     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3230     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3231 {
3232   int i;
3233   guint16 *restrict sy = GET_Y_LINE (y);
3234   guint16 *restrict su = GET_U_LINE (y);
3235   guint16 *restrict sv = GET_V_LINE (y);
3236   guint16 *restrict d = dest, Y, U, V;
3237
3238   sy += x;
3239   su += x;
3240   sv += x;
3241
3242   for (i = 0; i < width; i++) {
3243     Y = GST_READ_UINT16_LE (sy + i) << 4;
3244     U = GST_READ_UINT16_LE (su + i) << 4;
3245     V = GST_READ_UINT16_LE (sv + i) << 4;
3246
3247     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3248       Y |= (Y >> 12);
3249       U |= (U >> 12);
3250       V |= (V >> 12);
3251     }
3252
3253     d[i * 4 + 0] = 0xffff;
3254     d[i * 4 + 1] = Y;
3255     d[i * 4 + 2] = U;
3256     d[i * 4 + 3] = V;
3257   }
3258 }
3259
3260 static void
3261 pack_Y444_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3262     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3263     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3264     gint y, gint width)
3265 {
3266   int i;
3267   guint16 *restrict dy = GET_Y_LINE (y);
3268   guint16 *restrict du = GET_U_LINE (y);
3269   guint16 *restrict dv = GET_V_LINE (y);
3270   guint16 Y, U, V;
3271   const guint16 *restrict s = src;
3272
3273   for (i = 0; i < width; i++) {
3274     Y = (s[i * 4 + 1]) >> 4;
3275     U = (s[i * 4 + 2]) >> 4;
3276     V = (s[i * 4 + 3]) >> 4;
3277
3278     GST_WRITE_UINT16_LE (dy + i, Y);
3279     GST_WRITE_UINT16_LE (du + i, U);
3280     GST_WRITE_UINT16_LE (dv + i, V);
3281   }
3282 }
3283
3284 #define PACK_Y444_12BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_12BE, 1, pack_Y444_12BE
3285 static void
3286 unpack_Y444_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3287     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3288     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3289 {
3290   int i;
3291   const guint16 *restrict sy = GET_Y_LINE (y);
3292   const guint16 *restrict su = GET_U_LINE (y);
3293   const guint16 *restrict sv = GET_V_LINE (y);
3294   guint16 *restrict d = dest, Y, U, V;
3295
3296   sy += x;
3297   su += x;
3298   sv += x;
3299
3300   for (i = 0; i < width; i++) {
3301     Y = GST_READ_UINT16_BE (sy + i) << 4;
3302     U = GST_READ_UINT16_BE (su + i) << 4;
3303     V = GST_READ_UINT16_BE (sv + i) << 4;
3304
3305     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3306       Y |= (Y >> 12);
3307       U |= (U >> 12);
3308       V |= (V >> 12);
3309     }
3310
3311     d[i * 4 + 0] = 0xffff;
3312     d[i * 4 + 1] = Y;
3313     d[i * 4 + 2] = U;
3314     d[i * 4 + 3] = V;
3315   }
3316 }
3317
3318 static void
3319 pack_Y444_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3320     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3321     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3322     gint y, gint width)
3323 {
3324   int i;
3325   guint16 *restrict dy = GET_Y_LINE (y);
3326   guint16 *restrict du = GET_U_LINE (y);
3327   guint16 *restrict dv = GET_V_LINE (y);
3328   guint16 Y, U, V;
3329   const guint16 *restrict s = src;
3330
3331   for (i = 0; i < width; i++) {
3332     Y = s[i * 4 + 1] >> 4;
3333     U = s[i * 4 + 2] >> 4;
3334     V = s[i * 4 + 3] >> 4;
3335
3336     GST_WRITE_UINT16_BE (dy + i, Y);
3337     GST_WRITE_UINT16_BE (du + i, U);
3338     GST_WRITE_UINT16_BE (dv + i, V);
3339   }
3340 }
3341
3342 #define PACK_I420_12LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_12LE, 1, pack_I420_12LE
3343 static void
3344 unpack_I420_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3345     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3346     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3347 {
3348   int i;
3349   gint uv = GET_UV_420 (y, flags);
3350   const guint16 *restrict sy = GET_Y_LINE (y);
3351   const guint16 *restrict su = GET_U_LINE (uv);
3352   const guint16 *restrict sv = GET_V_LINE (uv);
3353   guint16 *restrict d = dest, Y, U, V;
3354
3355   sy += x;
3356   su += x >> 1;
3357   sv += x >> 1;
3358
3359   for (i = 0; i < width; i++) {
3360     Y = GST_READ_UINT16_LE (sy + i) << 4;
3361     U = GST_READ_UINT16_LE (su + (i >> 1)) << 4;
3362     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 4;
3363
3364     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3365       Y |= (Y >> 12);
3366       U |= (U >> 12);
3367       V |= (V >> 12);
3368     }
3369
3370     d[i * 4 + 0] = 0xffff;
3371     d[i * 4 + 1] = Y;
3372     d[i * 4 + 2] = U;
3373     d[i * 4 + 3] = V;
3374
3375     if (x & 1) {
3376       x = 0;
3377       su++;
3378       sv++;
3379     }
3380   }
3381 }
3382
3383 static void
3384 pack_I420_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3385     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3386     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3387     gint y, gint width)
3388 {
3389   int i;
3390   gint uv = GET_UV_420 (y, flags);
3391   guint16 *restrict dy = GET_Y_LINE (y);
3392   guint16 *restrict du = GET_U_LINE (uv);
3393   guint16 *restrict dv = GET_V_LINE (uv);
3394   guint16 Y0, Y1, U, V;
3395   const guint16 *restrict s = src;
3396
3397   if (IS_CHROMA_LINE_420 (y, flags)) {
3398     for (i = 0; i < width - 1; i += 2) {
3399       Y0 = s[i * 4 + 1] >> 4;
3400       Y1 = s[i * 4 + 5] >> 4;
3401       U = s[i * 4 + 2] >> 4;
3402       V = s[i * 4 + 3] >> 4;
3403
3404       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3405       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3406       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3407       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3408     }
3409     if (i == width - 1) {
3410       Y0 = s[i * 4 + 1] >> 4;
3411       U = s[i * 4 + 2] >> 4;
3412       V = s[i * 4 + 3] >> 4;
3413
3414       GST_WRITE_UINT16_LE (dy + i, Y0);
3415       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3416       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3417     }
3418   } else {
3419     for (i = 0; i < width; i++) {
3420       Y0 = s[i * 4 + 1] >> 4;
3421       GST_WRITE_UINT16_LE (dy + i, Y0);
3422     }
3423   }
3424 }
3425
3426 #define PACK_I420_12BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_12BE, 1, pack_I420_12BE
3427 static void
3428 unpack_I420_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3429     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3430     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3431 {
3432   int i;
3433   gint uv = GET_UV_420 (y, flags);
3434   const guint16 *restrict sy = GET_Y_LINE (y);
3435   const guint16 *restrict su = GET_U_LINE (uv);
3436   const guint16 *restrict sv = GET_V_LINE (uv);
3437   guint16 *restrict d = dest, Y, U, V;
3438
3439   sy += x;
3440   su += x >> 1;
3441   sv += x >> 1;
3442
3443   for (i = 0; i < width; i++) {
3444     Y = GST_READ_UINT16_BE (sy + i) << 4;
3445     U = GST_READ_UINT16_BE (su + (i >> 1)) << 4;
3446     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 4;
3447
3448     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3449       Y |= (Y >> 12);
3450       U |= (U >> 12);
3451       V |= (V >> 12);
3452     }
3453
3454     d[i * 4 + 0] = 0xffff;
3455     d[i * 4 + 1] = Y;
3456     d[i * 4 + 2] = U;
3457     d[i * 4 + 3] = V;
3458
3459     if (x & 1) {
3460       x = 0;
3461       su++;
3462       sv++;
3463     }
3464   }
3465 }
3466
3467 static void
3468 pack_I420_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3469     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3470     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3471     gint y, gint width)
3472 {
3473   int i;
3474   gint uv = GET_UV_420 (y, flags);
3475   guint16 *restrict dy = GET_Y_LINE (y);
3476   guint16 *restrict du = GET_U_LINE (uv);
3477   guint16 *restrict dv = GET_V_LINE (uv);
3478   guint16 Y0, Y1, U, V;
3479   const guint16 *restrict s = src;
3480
3481   if (IS_CHROMA_LINE_420 (y, flags)) {
3482     for (i = 0; i < width - 1; i += 2) {
3483       Y0 = s[i * 4 + 1] >> 4;
3484       Y1 = s[i * 4 + 5] >> 4;
3485       U = s[i * 4 + 2] >> 4;
3486       V = s[i * 4 + 3] >> 4;
3487
3488       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3489       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3490       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3491       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3492     }
3493     if (i == width - 1) {
3494       Y0 = s[i * 4 + 1] >> 4;
3495       U = s[i * 4 + 2] >> 4;
3496       V = s[i * 4 + 3] >> 4;
3497
3498       GST_WRITE_UINT16_BE (dy + i, Y0);
3499       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3500       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3501     }
3502   } else {
3503     for (i = 0; i < width; i++) {
3504       Y0 = s[i * 4 + 1] >> 6;
3505       GST_WRITE_UINT16_BE (dy + i, Y0);
3506     }
3507   }
3508 }
3509
3510 #define PACK_I422_12LE GST_VIDEO_FORMAT_AYUV64, unpack_I422_12LE, 1, pack_I422_12LE
3511 static void
3512 unpack_I422_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3513     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3514     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3515 {
3516   int i;
3517   const guint16 *restrict sy = GET_Y_LINE (y);
3518   const guint16 *restrict su = GET_U_LINE (y);
3519   const guint16 *restrict sv = GET_V_LINE (y);
3520   guint16 *restrict d = dest, Y, U, V;
3521
3522   sy += x;
3523   su += x >> 1;
3524   sv += x >> 1;
3525
3526   for (i = 0; i < width; i++) {
3527     Y = GST_READ_UINT16_LE (sy + i) << 4;
3528     U = GST_READ_UINT16_LE (su + (i >> 1)) << 4;
3529     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 4;
3530
3531     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3532       Y |= (Y >> 12);
3533       U |= (U >> 12);
3534       V |= (V >> 12);
3535     }
3536
3537     d[i * 4 + 0] = 0xffff;
3538     d[i * 4 + 1] = Y;
3539     d[i * 4 + 2] = U;
3540     d[i * 4 + 3] = V;
3541
3542     if (x & 1) {
3543       x = 0;
3544       su++;
3545       sv++;
3546     }
3547   }
3548 }
3549
3550 static void
3551 pack_I422_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3552     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3553     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3554     gint y, gint width)
3555 {
3556   int i;
3557   guint16 *restrict dy = GET_Y_LINE (y);
3558   guint16 *restrict du = GET_U_LINE (y);
3559   guint16 *restrict dv = GET_V_LINE (y);
3560   guint16 Y0, Y1, U, V;
3561   const guint16 *restrict s = src;
3562
3563   for (i = 0; i < width - 1; i += 2) {
3564     Y0 = s[i * 4 + 1] >> 4;
3565     Y1 = s[i * 4 + 5] >> 4;
3566     U = s[i * 4 + 2] >> 4;
3567     V = s[i * 4 + 3] >> 4;
3568
3569     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3570     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3571     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3572     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3573   }
3574   if (i == width - 1) {
3575     Y0 = s[i * 4 + 1] >> 4;
3576     U = s[i * 4 + 2] >> 4;
3577     V = s[i * 4 + 3] >> 4;
3578
3579     GST_WRITE_UINT16_LE (dy + i, Y0);
3580     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3581     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3582   }
3583 }
3584
3585 #define PACK_I422_12BE GST_VIDEO_FORMAT_AYUV64, unpack_I422_12BE, 1, pack_I422_12BE
3586 static void
3587 unpack_I422_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3588     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3589     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3590 {
3591   int i;
3592   const guint16 *restrict sy = GET_Y_LINE (y);
3593   const guint16 *restrict su = GET_U_LINE (y);
3594   const guint16 *restrict sv = GET_V_LINE (y);
3595   guint16 *restrict d = dest, Y, U, V;
3596
3597   sy += x;
3598   su += x >> 1;
3599   sv += x >> 1;
3600
3601   for (i = 0; i < width; i++) {
3602     Y = GST_READ_UINT16_BE (sy + i) << 4;
3603     U = GST_READ_UINT16_BE (su + (i >> 1)) << 4;
3604     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 4;
3605
3606     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3607       Y |= (Y >> 12);
3608       U |= (U >> 12);
3609       V |= (V >> 12);
3610     }
3611
3612     d[i * 4 + 0] = 0xffff;
3613     d[i * 4 + 1] = Y;
3614     d[i * 4 + 2] = U;
3615     d[i * 4 + 3] = V;
3616
3617     if (x & 1) {
3618       x = 0;
3619       su++;
3620       sv++;
3621     }
3622   }
3623 }
3624
3625 static void
3626 pack_I422_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3627     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3628     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3629     gint y, gint width)
3630 {
3631   int i;
3632   guint16 *restrict dy = GET_Y_LINE (y);
3633   guint16 *restrict du = GET_U_LINE (y);
3634   guint16 *restrict dv = GET_V_LINE (y);
3635   guint16 Y0, Y1, U, V;
3636   const guint16 *restrict s = src;
3637
3638   for (i = 0; i < width - 1; i += 2) {
3639     Y0 = s[i * 4 + 1] >> 4;
3640     Y1 = s[i * 4 + 5] >> 4;
3641     U = s[i * 4 + 2] >> 4;
3642     V = s[i * 4 + 3] >> 4;
3643
3644     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3645     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3646     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3647     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3648   }
3649   if (i == width - 1) {
3650     Y0 = s[i * 4 + 1] >> 4;
3651     U = s[i * 4 + 2] >> 4;
3652     V = s[i * 4 + 3] >> 4;
3653
3654     GST_WRITE_UINT16_BE (dy + i, Y0);
3655     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3656     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3657   }
3658 }
3659
3660 #define PACK_A444_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A444_10LE, 1, pack_A444_10LE
3661 static void
3662 unpack_A444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3663     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3664     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3665 {
3666   int i;
3667   guint16 *restrict sa = GET_A_LINE (y);
3668   guint16 *restrict sy = GET_Y_LINE (y);
3669   guint16 *restrict su = GET_U_LINE (y);
3670   guint16 *restrict sv = GET_V_LINE (y);
3671   guint16 *restrict d = dest, A, Y, U, V;
3672
3673   sa += x;
3674   sy += x;
3675   su += x;
3676   sv += x;
3677
3678   for (i = 0; i < width; i++) {
3679     A = GST_READ_UINT16_LE (sa + i) << 6;
3680     Y = GST_READ_UINT16_LE (sy + i) << 6;
3681     U = GST_READ_UINT16_LE (su + i) << 6;
3682     V = GST_READ_UINT16_LE (sv + i) << 6;
3683
3684     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3685       A |= (A >> 10);
3686       Y |= (Y >> 10);
3687       U |= (U >> 10);
3688       V |= (V >> 10);
3689     }
3690
3691     d[i * 4 + 0] = A;
3692     d[i * 4 + 1] = Y;
3693     d[i * 4 + 2] = U;
3694     d[i * 4 + 3] = V;
3695   }
3696 }
3697
3698 static void
3699 pack_A444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3700     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3701     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3702     gint y, gint width)
3703 {
3704   int i;
3705   guint16 *restrict da = GET_A_LINE (y);
3706   guint16 *restrict dy = GET_Y_LINE (y);
3707   guint16 *restrict du = GET_U_LINE (y);
3708   guint16 *restrict dv = GET_V_LINE (y);
3709   guint16 A, Y, U, V;
3710   const guint16 *restrict s = src;
3711
3712   for (i = 0; i < width; i++) {
3713     A = (s[i * 4 + 0]) >> 6;
3714     Y = (s[i * 4 + 1]) >> 6;
3715     U = (s[i * 4 + 2]) >> 6;
3716     V = (s[i * 4 + 3]) >> 6;
3717
3718     GST_WRITE_UINT16_LE (da + i, A);
3719     GST_WRITE_UINT16_LE (dy + i, Y);
3720     GST_WRITE_UINT16_LE (du + i, U);
3721     GST_WRITE_UINT16_LE (dv + i, V);
3722   }
3723 }
3724
3725 #define PACK_A444_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A444_10BE, 1, pack_A444_10BE
3726 static void
3727 unpack_A444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3728     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3729     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3730 {
3731   int i;
3732   const guint16 *restrict sa = GET_A_LINE (y);
3733   const guint16 *restrict sy = GET_Y_LINE (y);
3734   const guint16 *restrict su = GET_U_LINE (y);
3735   const guint16 *restrict sv = GET_V_LINE (y);
3736   guint16 *restrict d = dest, A, Y, U, V;
3737
3738   sa += x;
3739   sy += x;
3740   su += x;
3741   sv += x;
3742
3743   for (i = 0; i < width; i++) {
3744     A = GST_READ_UINT16_BE (sa + i) << 6;
3745     Y = GST_READ_UINT16_BE (sy + i) << 6;
3746     U = GST_READ_UINT16_BE (su + i) << 6;
3747     V = GST_READ_UINT16_BE (sv + i) << 6;
3748
3749     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3750       A |= (A >> 10);
3751       Y |= (Y >> 10);
3752       U |= (U >> 10);
3753       V |= (V >> 10);
3754     }
3755
3756     d[i * 4 + 0] = A;
3757     d[i * 4 + 1] = Y;
3758     d[i * 4 + 2] = U;
3759     d[i * 4 + 3] = V;
3760   }
3761 }
3762
3763 static void
3764 pack_A444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3765     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3766     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3767     gint y, gint width)
3768 {
3769   int i;
3770   guint16 *restrict da = GET_A_LINE (y);
3771   guint16 *restrict dy = GET_Y_LINE (y);
3772   guint16 *restrict du = GET_U_LINE (y);
3773   guint16 *restrict dv = GET_V_LINE (y);
3774   guint16 A, Y, U, V;
3775   const guint16 *restrict s = src;
3776
3777   for (i = 0; i < width; i++) {
3778     A = s[i * 4 + 0] >> 6;
3779     Y = s[i * 4 + 1] >> 6;
3780     U = s[i * 4 + 2] >> 6;
3781     V = s[i * 4 + 3] >> 6;
3782
3783     GST_WRITE_UINT16_BE (da + i, A);
3784     GST_WRITE_UINT16_BE (dy + i, Y);
3785     GST_WRITE_UINT16_BE (du + i, U);
3786     GST_WRITE_UINT16_BE (dv + i, V);
3787   }
3788 }
3789
3790 #define PACK_A420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A420_10LE, 1, pack_A420_10LE
3791 static void
3792 unpack_A420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3793     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3794     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3795 {
3796   int i;
3797   gint uv = GET_UV_420 (y, flags);
3798   const guint16 *restrict sa = GET_A_LINE (y);
3799   const guint16 *restrict sy = GET_Y_LINE (y);
3800   const guint16 *restrict su = GET_U_LINE (uv);
3801   const guint16 *restrict sv = GET_V_LINE (uv);
3802   guint16 *restrict d = dest, A, Y, U, V;
3803
3804   sa += x;
3805   sy += x;
3806   su += x >> 1;
3807   sv += x >> 1;
3808
3809   for (i = 0; i < width; i++) {
3810     A = GST_READ_UINT16_LE (sa + i) << 6;
3811     Y = GST_READ_UINT16_LE (sy + i) << 6;
3812     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
3813     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
3814
3815     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3816       A |= (A >> 10);
3817       Y |= (Y >> 10);
3818       U |= (U >> 10);
3819       V |= (V >> 10);
3820     }
3821
3822     d[i * 4 + 0] = A;
3823     d[i * 4 + 1] = Y;
3824     d[i * 4 + 2] = U;
3825     d[i * 4 + 3] = V;
3826
3827     if (x & 1) {
3828       x = 0;
3829       su++;
3830       sv++;
3831     }
3832   }
3833 }
3834
3835 static void
3836 pack_A420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3837     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3838     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3839     gint y, gint width)
3840 {
3841   int i;
3842   gint uv = GET_UV_420 (y, flags);
3843   guint16 *restrict da = GET_A_LINE (y);
3844   guint16 *restrict dy = GET_Y_LINE (y);
3845   guint16 *restrict du = GET_U_LINE (uv);
3846   guint16 *restrict dv = GET_V_LINE (uv);
3847   guint16 A0, Y0, A1, Y1, U, V;
3848   const guint16 *restrict s = src;
3849
3850   if (IS_CHROMA_LINE_420 (y, flags)) {
3851     for (i = 0; i < width - 1; i += 2) {
3852       A0 = s[i * 4 + 0] >> 6;
3853       Y0 = s[i * 4 + 1] >> 6;
3854       A1 = s[i * 4 + 4] >> 6;
3855       Y1 = s[i * 4 + 5] >> 6;
3856       U = s[i * 4 + 2] >> 6;
3857       V = s[i * 4 + 3] >> 6;
3858
3859       GST_WRITE_UINT16_LE (da + i + 0, A0);
3860       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3861       GST_WRITE_UINT16_LE (da + i + 1, A1);
3862       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3863       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3864       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3865     }
3866     if (i == width - 1) {
3867       A0 = s[i * 4 + 0] >> 6;
3868       Y0 = s[i * 4 + 1] >> 6;
3869       U = s[i * 4 + 2] >> 6;
3870       V = s[i * 4 + 3] >> 6;
3871
3872       GST_WRITE_UINT16_LE (da + i, A0);
3873       GST_WRITE_UINT16_LE (dy + i, Y0);
3874       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3875       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3876     }
3877   } else {
3878     for (i = 0; i < width; i++) {
3879       A0 = s[i * 4 + 0] >> 6;
3880       Y0 = s[i * 4 + 1] >> 6;
3881       GST_WRITE_UINT16_LE (da + i, A0);
3882       GST_WRITE_UINT16_LE (dy + i, Y0);
3883     }
3884   }
3885 }
3886
3887 #define PACK_A420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A420_10BE, 1, pack_A420_10BE
3888 static void
3889 unpack_A420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3890     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3891     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3892 {
3893   int i;
3894   gint uv = GET_UV_420 (y, flags);
3895   const guint16 *restrict sa = GET_A_LINE (y);
3896   const guint16 *restrict sy = GET_Y_LINE (y);
3897   const guint16 *restrict su = GET_U_LINE (uv);
3898   const guint16 *restrict sv = GET_V_LINE (uv);
3899   guint16 *restrict d = dest, A, Y, U, V;
3900
3901   sa += x;
3902   sy += x;
3903   su += x >> 1;
3904   sv += x >> 1;
3905
3906   for (i = 0; i < width; i++) {
3907     A = GST_READ_UINT16_BE (sa + i) << 6;
3908     Y = GST_READ_UINT16_BE (sy + i) << 6;
3909     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3910     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3911
3912     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3913       A |= (A >> 10);
3914       Y |= (Y >> 10);
3915       U |= (U >> 10);
3916       V |= (V >> 10);
3917     }
3918
3919     d[i * 4 + 0] = A;
3920     d[i * 4 + 1] = Y;
3921     d[i * 4 + 2] = U;
3922     d[i * 4 + 3] = V;
3923
3924     if (x & 1) {
3925       x = 0;
3926       su++;
3927       sv++;
3928     }
3929   }
3930 }
3931
3932 static void
3933 pack_A420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3934     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3935     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3936     gint y, gint width)
3937 {
3938   int i;
3939   gint uv = GET_UV_420 (y, flags);
3940   guint16 *restrict da = GET_A_LINE (y);
3941   guint16 *restrict dy = GET_Y_LINE (y);
3942   guint16 *restrict du = GET_U_LINE (uv);
3943   guint16 *restrict dv = GET_V_LINE (uv);
3944   guint16 A0, Y0, A1, Y1, U, V;
3945   const guint16 *restrict s = src;
3946
3947   if (IS_CHROMA_LINE_420 (y, flags)) {
3948     for (i = 0; i < width - 1; i += 2) {
3949       A0 = s[i * 4 + 0] >> 6;
3950       Y0 = s[i * 4 + 1] >> 6;
3951       A1 = s[i * 4 + 4] >> 6;
3952       Y1 = s[i * 4 + 5] >> 6;
3953       U = s[i * 4 + 2] >> 6;
3954       V = s[i * 4 + 3] >> 6;
3955
3956       GST_WRITE_UINT16_BE (da + i + 0, A0);
3957       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3958       GST_WRITE_UINT16_BE (da + i + 1, A1);
3959       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3960       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3961       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3962     }
3963     if (i == width - 1) {
3964       A0 = s[i * 4 + 0] >> 6;
3965       Y0 = s[i * 4 + 1] >> 6;
3966       U = s[i * 4 + 2] >> 6;
3967       V = s[i * 4 + 3] >> 6;
3968
3969       GST_WRITE_UINT16_BE (da + i, A0);
3970       GST_WRITE_UINT16_BE (dy + i, Y0);
3971       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3972       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3973     }
3974   } else {
3975     for (i = 0; i < width; i++) {
3976       A0 = s[i * 4 + 0] >> 6;
3977       Y0 = s[i * 4 + 1] >> 6;
3978       GST_WRITE_UINT16_BE (da + i, A0);
3979       GST_WRITE_UINT16_BE (dy + i, Y0);
3980     }
3981   }
3982 }
3983
3984 #define PACK_A422_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A422_10LE, 1, pack_A422_10LE
3985 static void
3986 unpack_A422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3987     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3988     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3989 {
3990   int i;
3991   const guint16 *restrict sa = GET_A_LINE (y);
3992   const guint16 *restrict sy = GET_Y_LINE (y);
3993   const guint16 *restrict su = GET_U_LINE (y);
3994   const guint16 *restrict sv = GET_V_LINE (y);
3995   guint16 *restrict d = dest, A, Y, U, V;
3996
3997   sa += x;
3998   sy += x;
3999   su += x >> 1;
4000   sv += x >> 1;
4001
4002   for (i = 0; i < width; i++) {
4003     A = GST_READ_UINT16_LE (sa + i) << 6;
4004     Y = GST_READ_UINT16_LE (sy + i) << 6;
4005     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
4006     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
4007
4008     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4009       A |= (A >> 10);
4010       Y |= (Y >> 10);
4011       U |= (U >> 10);
4012       V |= (V >> 10);
4013     }
4014
4015     d[i * 4 + 0] = A;
4016     d[i * 4 + 1] = Y;
4017     d[i * 4 + 2] = U;
4018     d[i * 4 + 3] = V;
4019
4020     if (x & 1) {
4021       x = 0;
4022       su++;
4023       sv++;
4024     }
4025   }
4026 }
4027
4028 static void
4029 pack_A422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4030     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4031     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4032     gint y, gint width)
4033 {
4034   int i;
4035   guint16 *restrict da = GET_A_LINE (y);
4036   guint16 *restrict dy = GET_Y_LINE (y);
4037   guint16 *restrict du = GET_U_LINE (y);
4038   guint16 *restrict dv = GET_V_LINE (y);
4039   guint16 A0, Y0, A1, Y1, U, V;
4040   const guint16 *restrict s = src;
4041
4042   for (i = 0; i < width - 1; i += 2) {
4043     A0 = s[i * 4 + 0] >> 6;
4044     Y0 = s[i * 4 + 1] >> 6;
4045     A1 = s[i * 4 + 4] >> 6;
4046     Y1 = s[i * 4 + 5] >> 6;
4047     U = s[i * 4 + 2] >> 6;
4048     V = s[i * 4 + 3] >> 6;
4049
4050     GST_WRITE_UINT16_LE (da + i + 0, A0);
4051     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
4052     GST_WRITE_UINT16_LE (da + i + 1, A1);
4053     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
4054     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4055     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4056   }
4057   if (i == width - 1) {
4058     A0 = s[i * 4 + 0] >> 6;
4059     Y0 = s[i * 4 + 1] >> 6;
4060     U = s[i * 4 + 2] >> 6;
4061     V = s[i * 4 + 3] >> 6;
4062
4063     GST_WRITE_UINT16_LE (da + i, A0);
4064     GST_WRITE_UINT16_LE (dy + i, Y0);
4065     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4066     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4067   }
4068 }
4069
4070 #define PACK_A422_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A422_10BE, 1, pack_A422_10BE
4071 static void
4072 unpack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4073     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4074     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4075 {
4076   int i;
4077   const guint16 *restrict sa = GET_A_LINE (y);
4078   const guint16 *restrict sy = GET_Y_LINE (y);
4079   const guint16 *restrict su = GET_U_LINE (y);
4080   const guint16 *restrict sv = GET_V_LINE (y);
4081   guint16 *restrict d = dest, A, Y, U, V;
4082
4083   sa += x;
4084   sy += x;
4085   su += x >> 1;
4086   sv += x >> 1;
4087
4088   for (i = 0; i < width; i++) {
4089     A = GST_READ_UINT16_BE (sa + i) << 6;
4090     Y = GST_READ_UINT16_BE (sy + i) << 6;
4091     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
4092     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
4093
4094     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4095       A |= (A >> 10);
4096       Y |= (Y >> 10);
4097       U |= (U >> 10);
4098       V |= (V >> 10);
4099     }
4100
4101     d[i * 4 + 0] = A;
4102     d[i * 4 + 1] = Y;
4103     d[i * 4 + 2] = U;
4104     d[i * 4 + 3] = V;
4105
4106     if (x & 1) {
4107       x = 0;
4108       su++;
4109       sv++;
4110     }
4111   }
4112 }
4113
4114 static void
4115 pack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4116     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4117     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4118     gint y, gint width)
4119 {
4120   int i;
4121   guint16 *restrict da = GET_A_LINE (y);
4122   guint16 *restrict dy = GET_Y_LINE (y);
4123   guint16 *restrict du = GET_U_LINE (y);
4124   guint16 *restrict dv = GET_V_LINE (y);
4125   guint16 A0, Y0, A1, Y1, U, V;
4126   const guint16 *restrict s = src;
4127
4128   for (i = 0; i < width - 1; i += 2) {
4129     A0 = s[i * 4 + 0] >> 6;
4130     Y0 = s[i * 4 + 1] >> 6;
4131     A1 = s[i * 4 + 4] >> 6;
4132     Y1 = s[i * 4 + 5] >> 6;
4133     U = s[i * 4 + 2] >> 6;
4134     V = s[i * 4 + 3] >> 6;
4135
4136     GST_WRITE_UINT16_BE (da + i + 0, A0);
4137     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
4138     GST_WRITE_UINT16_BE (da + i + 1, A1);
4139     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
4140     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4141     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4142   }
4143   if (i == width - 1) {
4144     A0 = s[i * 4 + 0] >> 6;
4145     Y0 = s[i * 4 + 1] >> 6;
4146     U = s[i * 4 + 2] >> 6;
4147     V = s[i * 4 + 3] >> 6;
4148
4149     GST_WRITE_UINT16_BE (da + i, A0);
4150     GST_WRITE_UINT16_BE (dy + i, Y0);
4151     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4152     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4153   }
4154 }
4155
4156 static void
4157 get_tile_NV12 (gint tile_width, gint ts, gint tx, gint ty,
4158     const gpointer data[GST_VIDEO_MAX_PLANES],
4159     const gint stride[GST_VIDEO_MAX_PLANES],
4160     gpointer tile_data[GST_VIDEO_MAX_PLANES],
4161     gint tile_stride[GST_VIDEO_MAX_PLANES])
4162 {
4163   gsize offset;
4164
4165   /* index of Y tile */
4166   offset = gst_video_tile_get_index (GST_VIDEO_TILE_MODE_ZFLIPZ_2X2,
4167       tx, ty, GST_VIDEO_TILE_X_TILES (stride[0]),
4168       GST_VIDEO_TILE_Y_TILES (stride[0]));
4169   offset <<= ts;
4170   tile_data[0] = ((guint8 *) data[0]) + offset;
4171
4172   /* index of UV tile */
4173   offset = gst_video_tile_get_index (GST_VIDEO_TILE_MODE_ZFLIPZ_2X2,
4174       tx, ty >> 1, GST_VIDEO_TILE_X_TILES (stride[1]),
4175       GST_VIDEO_TILE_Y_TILES (stride[1]));
4176   offset <<= ts;
4177   /* On odd rows we return the second part of the UV tile */
4178   offset |= (ty & 1) << (ts - 1);
4179   tile_data[1] = ((guint8 *) data[1]) + offset;
4180
4181   tile_stride[0] = tile_stride[1] = tile_width;
4182 }
4183
4184 #define PACK_NV12_64Z32 GST_VIDEO_FORMAT_AYUV, unpack_NV12_64Z32, 1, pack_NV12_64Z32
4185 static void
4186 unpack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4187     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4188     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4189 {
4190   const GstVideoFormatInfo *unpack_info, *finfo;
4191   guint8 *line = dest;
4192   gint ws, hs, ts, tile_width;
4193   gint ntx, tx, ty;
4194   gint unpack_pstride;
4195
4196   ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
4197   hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
4198   ts = ws + hs;
4199
4200   tile_width = 1 << ws;
4201
4202   /* we reuse these unpack functions */
4203   finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
4204
4205   /* get pstride of unpacked format */
4206   unpack_info = gst_video_format_get_info (info->unpack_format);
4207   unpack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (unpack_info, 0);
4208
4209   /* first x tile to convert */
4210   tx = x >> ws;
4211   /* Last tile to convert */
4212   ntx = ((x + width - 1) >> ws) + 1;
4213   /* The row we are going to convert */
4214   ty = y >> hs;
4215
4216   /* y position in a tile */
4217   y = y & ((1 << hs) - 1);
4218   /* x position in a tile */
4219   x = x & (tile_width - 1);
4220
4221   for (; tx < ntx; tx++) {
4222     gpointer tdata[GST_VIDEO_MAX_PLANES];
4223     gint tstride[GST_VIDEO_MAX_PLANES];
4224     gint unpack_width;
4225
4226     get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride);
4227
4228     /* the number of bytes left to unpack */
4229     unpack_width = MIN (width - x, tile_width - x);
4230
4231     finfo->unpack_func (finfo, flags, line, tdata, tstride, x, y, unpack_width);
4232
4233     x = 0;
4234     width -= unpack_width;
4235     line += unpack_width * unpack_pstride;
4236   }
4237 }
4238
4239 static void
4240 pack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4241     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4242     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4243     gint y, gint width)
4244 {
4245   const GstVideoFormatInfo *pack_info, *finfo;
4246   guint8 *line = src;
4247   gint ws, hs, ts, tile_width;
4248   gint ntx, tx, ty;
4249   gint pack_pstride;
4250
4251   ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
4252   hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
4253   ts = ws + hs;
4254
4255   tile_width = 1 << ws;
4256
4257   /* we reuse these pack functions */
4258   finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
4259
4260   /* get pstride of packed format */
4261   pack_info = gst_video_format_get_info (info->unpack_format);
4262   pack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (pack_info, 0);
4263
4264   /* Last tile to convert */
4265   ntx = ((width - 1) >> ws) + 1;
4266   /* The row we are going to convert */
4267   ty = y >> hs;
4268
4269   /* y position in a tile */
4270   y = y & ((1 << hs) - 1);
4271
4272   for (tx = 0; tx < ntx; tx++) {
4273     gpointer tdata[GST_VIDEO_MAX_PLANES];
4274     gint tstride[GST_VIDEO_MAX_PLANES];
4275     gint pack_width;
4276
4277     get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride);
4278
4279     /* the number of bytes left to pack */
4280     pack_width = MIN (width, tile_width);
4281
4282     finfo->pack_func (finfo, flags, line, sstride, tdata, tstride,
4283         chroma_site, y, pack_width);
4284
4285     width -= pack_width;
4286     line += pack_width * pack_pstride;
4287   }
4288 }
4289
4290 #define PACK_P010_10BE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10BE, 1, pack_P010_10BE
4291 static void
4292 unpack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4293     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4294     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4295 {
4296   int i;
4297   gint uv = GET_UV_420 (y, flags);
4298   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
4299   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
4300   guint16 *restrict d = dest, Y0, Y1, U, V;
4301
4302   sy += x;
4303   suv += (x & ~1);
4304
4305   if (x & 1) {
4306     Y0 = GST_READ_UINT16_BE (sy);
4307     U = GST_READ_UINT16_BE (suv);
4308     V = GST_READ_UINT16_BE (suv + 1);
4309
4310     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4311       Y0 |= (Y0 >> 10);
4312       U |= (U >> 10);
4313       V |= (V >> 10);
4314     }
4315
4316     d[0] = 0xffff;
4317     d[1] = Y0;
4318     d[2] = U;
4319     d[3] = V;
4320     width--;
4321     d += 4;
4322     sy += 1;
4323     suv += 2;
4324   }
4325
4326   for (i = 0; i < width / 2; i++) {
4327     Y0 = GST_READ_UINT16_BE (sy + 2 * i);
4328     Y1 = GST_READ_UINT16_BE (sy + 2 * i + 1);
4329     U = GST_READ_UINT16_BE (suv + 2 * i);
4330     V = GST_READ_UINT16_BE (suv + 2 * i + 1);
4331
4332     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4333       Y0 |= (Y0 >> 10);
4334       Y1 |= (Y1 >> 10);
4335       U |= (U >> 10);
4336       V |= (V >> 10);
4337     }
4338
4339     d[i * 8 + 0] = 0xffff;
4340     d[i * 8 + 1] = Y0;
4341     d[i * 8 + 2] = U;
4342     d[i * 8 + 3] = V;
4343     d[i * 8 + 4] = 0xffff;
4344     d[i * 8 + 5] = Y1;
4345     d[i * 8 + 6] = U;
4346     d[i * 8 + 7] = V;
4347   }
4348
4349   if (width & 1) {
4350     gint i = width - 1;
4351
4352     Y0 = GST_READ_UINT16_BE (sy + i);
4353     U = GST_READ_UINT16_BE (suv + i);
4354     V = GST_READ_UINT16_BE (suv + i + 1);
4355
4356     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4357       Y0 |= (Y0 >> 10);
4358       U |= (U >> 10);
4359       V |= (V >> 10);
4360     }
4361
4362     d[i * 4 + 0] = 0xffff;
4363     d[i * 4 + 1] = Y0;
4364     d[i * 4 + 2] = U;
4365     d[i * 4 + 3] = V;
4366   }
4367 }
4368
4369 static void
4370 pack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4371     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4372     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4373     gint y, gint width)
4374 {
4375   int i;
4376   gint uv = GET_UV_420 (y, flags);
4377   guint16 *restrict dy = GET_PLANE_LINE (0, y);
4378   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
4379   guint16 Y0, Y1, U, V;
4380   const guint16 *restrict s = src;
4381
4382   if (IS_CHROMA_LINE_420 (y, flags)) {
4383     for (i = 0; i < width / 2; i++) {
4384       Y0 = s[i * 8 + 1] & 0xffc0;
4385       Y1 = s[i * 8 + 5] & 0xffc0;
4386       U = s[i * 8 + 2] & 0xffc0;
4387       V = s[i * 8 + 3] & 0xffc0;
4388
4389       GST_WRITE_UINT16_BE (dy + i * 2 + 0, Y0);
4390       GST_WRITE_UINT16_BE (dy + i * 2 + 1, Y1);
4391       GST_WRITE_UINT16_BE (duv + i * 2 + 0, U);
4392       GST_WRITE_UINT16_BE (duv + i * 2 + 1, V);
4393     }
4394     if (width & 1) {
4395       gint i = width - 1;
4396
4397       Y0 = s[i * 4 + 1] & 0xffc0;
4398       U = s[i * 4 + 2] & 0xffc0;
4399       V = s[i * 4 + 3] & 0xffc0;
4400
4401       GST_WRITE_UINT16_BE (dy + i, Y0);
4402       GST_WRITE_UINT16_BE (duv + i + 0, U);
4403       GST_WRITE_UINT16_BE (duv + i + 1, V);
4404     }
4405   } else {
4406     for (i = 0; i < width; i++) {
4407       Y0 = s[i * 4 + 1] & 0xffc0;
4408       GST_WRITE_UINT16_BE (dy + i, Y0);
4409     }
4410   }
4411 }
4412
4413 #define PACK_P010_10LE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10LE, 1, pack_P010_10LE
4414 static void
4415 unpack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4416     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4417     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4418 {
4419   int i;
4420   gint uv = GET_UV_420 (y, flags);
4421   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
4422   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
4423   guint16 *restrict d = dest, Y0, Y1, U, V;
4424
4425   sy += x;
4426   suv += (x & ~1);
4427
4428   if (x & 1) {
4429     Y0 = GST_READ_UINT16_LE (sy);
4430     U = GST_READ_UINT16_LE (suv);
4431     V = GST_READ_UINT16_LE (suv + 1);
4432
4433     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4434       Y0 |= (Y0 >> 10);
4435       U |= (U >> 10);
4436       V |= (V >> 10);
4437     }
4438
4439     d[0] = 0xffff;
4440     d[1] = Y0;
4441     d[2] = U;
4442     d[3] = V;
4443     width--;
4444     d += 4;
4445     sy += 1;
4446     suv += 2;
4447   }
4448
4449   for (i = 0; i < width / 2; i++) {
4450     Y0 = GST_READ_UINT16_LE (sy + 2 * i);
4451     Y1 = GST_READ_UINT16_LE (sy + 2 * i + 1);
4452     U = GST_READ_UINT16_LE (suv + 2 * i);
4453     V = GST_READ_UINT16_LE (suv + 2 * i + 1);
4454
4455     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4456       Y0 |= (Y0 >> 10);
4457       Y1 |= (Y1 >> 10);
4458       U |= (U >> 10);
4459       V |= (V >> 10);
4460     }
4461
4462     d[i * 8 + 0] = 0xffff;
4463     d[i * 8 + 1] = Y0;
4464     d[i * 8 + 2] = U;
4465     d[i * 8 + 3] = V;
4466     d[i * 8 + 4] = 0xffff;
4467     d[i * 8 + 5] = Y1;
4468     d[i * 8 + 6] = U;
4469     d[i * 8 + 7] = V;
4470   }
4471
4472   if (width & 1) {
4473     gint i = width - 1;
4474
4475     Y0 = GST_READ_UINT16_LE (sy + i);
4476     U = GST_READ_UINT16_LE (suv + i);
4477     V = GST_READ_UINT16_LE (suv + i + 1);
4478
4479     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4480       Y0 |= (Y0 >> 10);
4481       U |= (U >> 10);
4482       V |= (V >> 10);
4483     }
4484
4485     d[i * 4 + 0] = 0xffff;
4486     d[i * 4 + 1] = Y0;
4487     d[i * 4 + 2] = U;
4488     d[i * 4 + 3] = V;
4489   }
4490 }
4491
4492 static void
4493 pack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4494     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4495     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4496     gint y, gint width)
4497 {
4498   int i;
4499   gint uv = GET_UV_420 (y, flags);
4500   guint16 *restrict dy = GET_PLANE_LINE (0, y);
4501   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
4502   guint16 Y0, Y1, U, V;
4503   const guint16 *restrict s = src;
4504
4505   if (IS_CHROMA_LINE_420 (y, flags)) {
4506     for (i = 0; i < width / 2; i++) {
4507       Y0 = s[i * 8 + 1] & 0xffc0;
4508       Y1 = s[i * 8 + 5] & 0xffc0;
4509       U = s[i * 8 + 2] & 0xffc0;
4510       V = s[i * 8 + 3] & 0xffc0;
4511
4512       GST_WRITE_UINT16_LE (dy + i * 2 + 0, Y0);
4513       GST_WRITE_UINT16_LE (dy + i * 2 + 1, Y1);
4514       GST_WRITE_UINT16_LE (duv + i * 2 + 0, U);
4515       GST_WRITE_UINT16_LE (duv + i * 2 + 1, V);
4516     }
4517     if (width & 1) {
4518       gint i = width - 1;
4519
4520       Y0 = s[i * 4 + 1] & 0xffc0;
4521       U = s[i * 4 + 2] & 0xffc0;
4522       V = s[i * 4 + 3] & 0xffc0;
4523
4524       GST_WRITE_UINT16_LE (dy + i, Y0);
4525       GST_WRITE_UINT16_LE (duv + i + 0, U);
4526       GST_WRITE_UINT16_LE (duv + i + 1, V);
4527     }
4528   } else {
4529     for (i = 0; i < width; i++) {
4530       Y0 = s[i * 4 + 1] & 0xffc0;
4531       GST_WRITE_UINT16_LE (dy + i, Y0);
4532     }
4533   }
4534 }
4535
4536 typedef struct
4537 {
4538   guint32 fourcc;
4539   GstVideoFormatInfo info;
4540 } VideoFormat;
4541
4542 /* depths: bits, n_components, shift, depth */
4543 #define DPTH0            0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
4544 #define DPTH8            8, 1, { 0, 0, 0, 0 }, { 8, 0, 0, 0 }
4545 #define DPTH8_32         8, 2, { 0, 0, 0, 0 }, { 8, 32, 0, 0 }
4546 #define DPTH888          8, 3, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
4547 #define DPTH8888         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 8 }
4548 #define DPTH8880         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
4549 #define DPTH10_10_10     10, 3, { 0, 0, 0, 0 }, { 10, 10, 10, 0 }
4550 #define DPTH10_10_10_10  10, 4, { 0, 0, 0, 0 }, { 10, 10, 10, 10 }
4551 #define DPTH10_10_10_HI  16, 3, { 6, 6, 6, 0 }, { 10, 10, 10, 0 }
4552 #define DPTH12_12_12     12, 3, { 0, 0, 0, 0 }, { 12, 12, 12, 0 }
4553 #define DPTH12_12_12_12  12, 4, { 0, 0, 0, 0 }, { 12, 12, 12, 12 }
4554 #define DPTH16           16, 1, { 0, 0, 0, 0 }, { 16, 0, 0, 0 }
4555 #define DPTH16_16_16     16, 3, { 0, 0, 0, 0 }, { 16, 16, 16, 0 }
4556 #define DPTH16_16_16_16  16, 4, { 0, 0, 0, 0 }, { 16, 16, 16, 16 }
4557 #define DPTH555          16, 3, { 10, 5, 0, 0 }, { 5, 5, 5, 0 }
4558 #define DPTH565          16, 3, { 11, 5, 0, 0 }, { 5, 6, 5, 0 }
4559
4560 /* pixel strides */
4561 #define PSTR0             { 0, 0, 0, 0 }
4562 #define PSTR1             { 1, 0, 0, 0 }
4563 #define PSTR14            { 1, 4, 0, 0 }
4564 #define PSTR111           { 1, 1, 1, 0 }
4565 #define PSTR1111          { 1, 1, 1, 1 }
4566 #define PSTR122           { 1, 2, 2, 0 }
4567 #define PSTR2             { 2, 0, 0, 0 }
4568 #define PSTR222           { 2, 2, 2, 0 }
4569 #define PSTR2222          { 2, 2, 2, 2 }
4570 #define PSTR244           { 2, 4, 4, 0 }
4571 #define PSTR444           { 4, 4, 4, 0 }
4572 #define PSTR4444          { 4, 4, 4, 4 }
4573 #define PSTR333           { 3, 3, 3, 0 }
4574 #define PSTR488           { 4, 8, 8, 0 }
4575 #define PSTR8888          { 8, 8, 8, 8 }
4576
4577 /* planes, in what plane do we find component N */
4578 #define PLANE_NA          0, { 0, 0, 0, 0 }
4579 #define PLANE0            1, { 0, 0, 0, 0 }
4580 #define PLANE01           2, { 0, 1, 0, 0 }
4581 #define PLANE011          2, { 0, 1, 1, 0 }
4582 #define PLANE012          3, { 0, 1, 2, 0 }
4583 #define PLANE0123         4, { 0, 1, 2, 3 }
4584 #define PLANE021          3, { 0, 2, 1, 0 }
4585 #define PLANE201          3, { 2, 0, 1, 0 }
4586 #define PLANE2013         4, { 2, 0, 1, 3 }
4587
4588 /* offsets */
4589 #define OFFS0             { 0, 0, 0, 0 }
4590 #define OFFS013           { 0, 1, 3, 0 }
4591 #define OFFS102           { 1, 0, 2, 0 }
4592 #define OFFS1230          { 1, 2, 3, 0 }
4593 #define OFFS012           { 0, 1, 2, 0 }
4594 #define OFFS210           { 2, 1, 0, 0 }
4595 #define OFFS123           { 1, 2, 3, 0 }
4596 #define OFFS321           { 3, 2, 1, 0 }
4597 #define OFFS0123          { 0, 1, 2, 3 }
4598 #define OFFS2103          { 2, 1, 0, 3 }
4599 #define OFFS3210          { 3, 2, 1, 0 }
4600 #define OFFS031           { 0, 3, 1, 0 }
4601 #define OFFS204           { 2, 0, 4, 0 }
4602 #define OFFS001           { 0, 0, 1, 0 }
4603 #define OFFS010           { 0, 1, 0, 0 }
4604 #define OFFS104           { 1, 0, 4, 0 }
4605 #define OFFS2460          { 2, 4, 6, 0 }
4606
4607 /* subsampling, w_sub, h_sub */
4608 #define SUB410            { 0, 2, 2, 0 }, { 0, 2, 2, 0 }
4609 #define SUB411            { 0, 2, 2, 0 }, { 0, 0, 0, 0 }
4610 #define SUB420            { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
4611 #define SUB422            { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
4612 #define SUB4              { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
4613 #define SUB44             { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
4614 #define SUB444            { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
4615 #define SUB4444           { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
4616 #define SUB4204           { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
4617 #define SUB4224           { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
4618
4619 /* tile_mode, tile_width, tile_height */
4620 #define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5
4621
4622 #define MAKE_YUV_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
4623  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV, depth, pstride, plane, offs, sub, pack } }
4624 #define MAKE_YUV_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
4625  { 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 } }
4626 #define MAKE_YUVA_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
4627  { 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 } }
4628 #define MAKE_YUVA_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
4629  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
4630 #define MAKE_YUVA_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
4631  { 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 } }
4632 #define MAKE_YUVA_LE_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
4633  { 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 } }
4634 #define MAKE_YUV_C_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
4635  { 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 } }
4636 #define MAKE_YUV_T_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack, tile) \
4637  { 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 } }
4638
4639 #define MAKE_RGB_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4640  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB, depth, pstride, plane, offs, sub, pack } }
4641 #define MAKE_RGB_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4642  { 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 } }
4643 #define MAKE_RGBA_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4644  { 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 } }
4645 #define MAKE_RGBA_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4646  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
4647 #define MAKE_RGBAP_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4648  { 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 } }
4649 #define MAKE_RGBA_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4650  { 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 } }
4651 #define MAKE_RGBA_LE_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4652  { 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 } }
4653
4654 #define MAKE_GRAY_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4655  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY, depth, pstride, plane, offs, sub, pack } }
4656 #define MAKE_GRAY_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
4657  { 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 } }
4658
4659 static const VideoFormat formats[] = {
4660   {0x00000000, {GST_VIDEO_FORMAT_UNKNOWN, "UNKNOWN", "unknown video", 0, DPTH0,
4661           PSTR0, PLANE_NA, OFFS0}},
4662   {0x00000000, {GST_VIDEO_FORMAT_ENCODED, "ENCODED", "encoded video",
4663           GST_VIDEO_FORMAT_FLAG_COMPLEX, DPTH0, PSTR0, PLANE_NA, OFFS0}},
4664
4665   MAKE_YUV_FORMAT (I420, "raw video", GST_MAKE_FOURCC ('I', '4', '2', '0'),
4666       DPTH888, PSTR111, PLANE012, OFFS0, SUB420, PACK_420),
4667   MAKE_YUV_FORMAT (YV12, "raw video", GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
4668       DPTH888, PSTR111, PLANE021, OFFS0, SUB420, PACK_420),
4669   MAKE_YUV_FORMAT (YUY2, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
4670       DPTH888, PSTR244, PLANE0, OFFS013, SUB422, PACK_YUY2),
4671   MAKE_YUV_FORMAT (UYVY, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
4672       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_UYVY),
4673   MAKE_YUVA_PACK_FORMAT (AYUV, "raw video", GST_MAKE_FOURCC ('A', 'Y', 'U',
4674           'V'), DPTH8888, PSTR4444, PLANE0, OFFS1230, SUB4444, PACK_AYUV),
4675   MAKE_RGB_FORMAT (RGBx, "raw video", DPTH888, PSTR444, PLANE0, OFFS012,
4676       SUB444, PACK_RGBA),
4677   MAKE_RGB_FORMAT (BGRx, "raw video", DPTH888, PSTR444, PLANE0, OFFS210,
4678       SUB444, PACK_BGRA),
4679   MAKE_RGB_FORMAT (xRGB, "raw video", DPTH888, PSTR444, PLANE0, OFFS123,
4680       SUB444, PACK_ARGB),
4681   MAKE_RGB_FORMAT (xBGR, "raw video", DPTH888, PSTR444, PLANE0, OFFS321,
4682       SUB444, PACK_ABGR),
4683   MAKE_RGBA_FORMAT (RGBA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS0123,
4684       SUB4444, PACK_RGBA),
4685   MAKE_RGBA_FORMAT (BGRA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS2103,
4686       SUB4444, PACK_BGRA),
4687   MAKE_RGBA_PACK_FORMAT (ARGB, "raw video", DPTH8888, PSTR4444, PLANE0,
4688       OFFS1230, SUB4444, PACK_ARGB),
4689   MAKE_RGBA_FORMAT (ABGR, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS3210,
4690       SUB4444, PACK_ABGR),
4691   MAKE_RGB_FORMAT (RGB, "raw video", DPTH888, PSTR333, PLANE0, OFFS012, SUB444,
4692       PACK_RGB),
4693   MAKE_RGB_FORMAT (BGR, "raw video", DPTH888, PSTR333, PLANE0, OFFS210, SUB444,
4694       PACK_BGR),
4695
4696   MAKE_YUV_FORMAT (Y41B, "raw video", GST_MAKE_FOURCC ('Y', '4', '1', 'B'),
4697       DPTH888, PSTR111, PLANE012, OFFS0, SUB411, PACK_Y41B),
4698   MAKE_YUV_FORMAT (Y42B, "raw video", GST_MAKE_FOURCC ('Y', '4', '2', 'B'),
4699       DPTH888, PSTR111, PLANE012, OFFS0, SUB422, PACK_Y42B),
4700   MAKE_YUV_FORMAT (YVYU, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'),
4701       DPTH888, PSTR244, PLANE0, OFFS031, SUB422, PACK_YVYU),
4702   MAKE_YUV_FORMAT (Y444, "raw video", GST_MAKE_FOURCC ('Y', '4', '4', '4'),
4703       DPTH888, PSTR111, PLANE012, OFFS0, SUB444, PACK_Y444),
4704   MAKE_YUV_C_FORMAT (v210, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '0'),
4705       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_v210),
4706   MAKE_YUV_FORMAT (v216, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '6'),
4707       DPTH16_16_16, PSTR488, PLANE0, OFFS204, SUB422, PACK_v216),
4708   MAKE_YUV_FORMAT (NV12, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '2'),
4709       DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12),
4710   MAKE_YUV_FORMAT (NV21, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '1'),
4711       DPTH888, PSTR122, PLANE011, OFFS010, SUB420, PACK_NV21),
4712
4713   MAKE_GRAY_FORMAT (GRAY8, "raw video", DPTH8, PSTR1, PLANE0, OFFS0, SUB4,
4714       PACK_GRAY8),
4715   MAKE_GRAY_FORMAT (GRAY16_BE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0, SUB4,
4716       PACK_GRAY16_BE),
4717   MAKE_GRAY_LE_FORMAT (GRAY16_LE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0,
4718       SUB4, PACK_GRAY16_LE),
4719
4720   MAKE_YUV_FORMAT (v308, "raw video", GST_MAKE_FOURCC ('v', '3', '0', '8'),
4721       DPTH888, PSTR333, PLANE0, OFFS012, SUB444, PACK_v308),
4722
4723 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
4724   MAKE_RGB_LE_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
4725       SUB444, PACK_RGB16),
4726   MAKE_RGB_LE_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
4727       SUB444, PACK_BGR16),
4728   MAKE_RGB_LE_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
4729       SUB444, PACK_RGB15),
4730   MAKE_RGB_LE_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
4731       SUB444, PACK_BGR15),
4732 #else
4733   MAKE_RGB_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
4734       PACK_RGB16),
4735   MAKE_RGB_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
4736       PACK_BGR16),
4737   MAKE_RGB_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
4738       PACK_RGB15),
4739   MAKE_RGB_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
4740       PACK_BGR15),
4741 #endif
4742
4743   MAKE_YUV_C_FORMAT (UYVP, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'),
4744       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_UYVP),
4745   MAKE_YUVA_FORMAT (A420, "raw video", GST_MAKE_FOURCC ('A', '4', '2', '0'),
4746       DPTH8888, PSTR1111, PLANE0123, OFFS0, SUB4204, PACK_A420),
4747   MAKE_RGBAP_FORMAT (RGB8P, "raw video", DPTH8_32, PSTR14, PLANE01,
4748       OFFS0, SUB44, PACK_RGB8P),
4749   MAKE_YUV_FORMAT (YUV9, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'V', '9'),
4750       DPTH888, PSTR111, PLANE012, OFFS0, SUB410, PACK_410),
4751   MAKE_YUV_FORMAT (YVU9, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'U', '9'),
4752       DPTH888, PSTR111, PLANE021, OFFS0, SUB410, PACK_410),
4753   MAKE_YUV_FORMAT (IYU1, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '1'),
4754       DPTH888, PSTR0, PLANE0, OFFS104, SUB411, PACK_IYU1),
4755 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
4756   MAKE_RGBA_LE_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888,
4757       PLANE0,
4758       OFFS2460, SUB444, PACK_ARGB64),
4759   MAKE_YUVA_LE_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
4760       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
4761 #else
4762   MAKE_RGBA_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
4763       OFFS2460, SUB444, PACK_ARGB64),
4764   MAKE_YUVA_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
4765       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
4766 #endif
4767   MAKE_RGB_FORMAT (r210, "raw video", DPTH10_10_10, PSTR444, PLANE0, OFFS0,
4768       SUB444, PACK_r210),
4769   MAKE_YUV_FORMAT (I420_10BE, "raw video", 0x00000000, DPTH10_10_10,
4770       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10BE),
4771   MAKE_YUV_LE_FORMAT (I420_10LE, "raw video", 0x00000000, DPTH10_10_10,
4772       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10LE),
4773   MAKE_YUV_FORMAT (I422_10BE, "raw video", 0x00000000, DPTH10_10_10,
4774       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10BE),
4775   MAKE_YUV_LE_FORMAT (I422_10LE, "raw video", 0x00000000, DPTH10_10_10,
4776       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10LE),
4777   MAKE_YUV_FORMAT (Y444_10BE, "raw video", 0x00000000, DPTH10_10_10,
4778       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10BE),
4779   MAKE_YUV_LE_FORMAT (Y444_10LE, "raw video", 0x00000000, DPTH10_10_10,
4780       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10LE),
4781   MAKE_RGB_FORMAT (GBR, "raw video", DPTH888, PSTR111, PLANE201, OFFS0, SUB444,
4782       PACK_GBR),
4783   MAKE_RGB_FORMAT (GBR_10BE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
4784       OFFS0, SUB444, PACK_GBR_10BE),
4785   MAKE_RGB_LE_FORMAT (GBR_10LE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
4786       OFFS0, SUB444, PACK_GBR_10LE),
4787   MAKE_YUV_FORMAT (NV16, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '6'),
4788       DPTH888, PSTR122, PLANE011, OFFS001, SUB422, PACK_NV16),
4789   MAKE_YUV_FORMAT (NV24, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '4'),
4790       DPTH888, PSTR122, PLANE011, OFFS001, SUB444, PACK_NV24),
4791   MAKE_YUV_T_FORMAT (NV12_64Z32, "raw video",
4792       GST_MAKE_FOURCC ('T', 'M', '1', '2'), DPTH8880, PSTR122, PLANE011,
4793       OFFS001, SUB420, PACK_NV12_64Z32, TILE_64x32 (ZFLIPZ_2X2)),
4794   MAKE_YUVA_FORMAT (A420_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
4795       PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_10BE),
4796   MAKE_YUVA_LE_FORMAT (A420_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
4797       PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_10LE),
4798   MAKE_YUVA_FORMAT (A422_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
4799       PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_10BE),
4800   MAKE_YUVA_LE_FORMAT (A422_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
4801       PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_10LE),
4802   MAKE_YUVA_FORMAT (A444_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
4803       PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_10BE),
4804   MAKE_YUVA_LE_FORMAT (A444_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
4805       PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_10LE),
4806   MAKE_YUV_FORMAT (NV61, "raw video", GST_MAKE_FOURCC ('N', 'V', '6', '1'),
4807       DPTH888, PSTR122, PLANE011, OFFS010, SUB422, PACK_NV61),
4808   MAKE_YUV_FORMAT (P010_10BE, "raw video", 0x00000000, DPTH10_10_10_HI,
4809       PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10BE),
4810   MAKE_YUV_LE_FORMAT (P010_10LE, "raw video", 0x00000000, DPTH10_10_10_HI,
4811       PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10LE),
4812   MAKE_YUV_FORMAT (IYU2, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '2'),
4813       DPTH888, PSTR333, PLANE0, OFFS102, SUB444, PACK_IYU2),
4814   MAKE_YUV_FORMAT (VYUY, "raw video", GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y'),
4815       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_VYUY),
4816   MAKE_RGBA_FORMAT (GBRA, "raw video", DPTH8888, PSTR1111, PLANE2013,
4817       OFFS0, SUB4444, PACK_GBRA),
4818   MAKE_RGBA_FORMAT (GBRA_10BE, "raw video", DPTH10_10_10_10, PSTR222, PLANE2013,
4819       OFFS0, SUB4444, PACK_GBRA_10BE),
4820   MAKE_RGBA_LE_FORMAT (GBRA_10LE, "raw video", DPTH10_10_10_10, PSTR222,
4821       PLANE2013,
4822       OFFS0, SUB4444, PACK_GBRA_10LE),
4823   MAKE_RGB_FORMAT (GBR_12BE, "raw video", DPTH12_12_12, PSTR222, PLANE201,
4824       OFFS0, SUB444, PACK_GBR_12BE),
4825   MAKE_RGB_LE_FORMAT (GBR_12LE, "raw video", DPTH12_12_12, PSTR222, PLANE201,
4826       OFFS0, SUB444, PACK_GBR_12LE),
4827   MAKE_RGBA_FORMAT (GBRA_12BE, "raw video", DPTH12_12_12_12, PSTR222, PLANE2013,
4828       OFFS0, SUB4444, PACK_GBRA_12BE),
4829   MAKE_RGBA_LE_PACK_FORMAT (GBRA_12LE, "raw video", DPTH12_12_12_12, PSTR222,
4830       PLANE2013, OFFS0, SUB4444, PACK_GBRA_12LE),
4831   MAKE_YUV_FORMAT (I420_12BE, "raw video", 0x00000000, DPTH12_12_12,
4832       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_12BE),
4833   MAKE_YUV_LE_FORMAT (I420_12LE, "raw video", 0x00000000, DPTH12_12_12,
4834       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_12LE),
4835   MAKE_YUV_FORMAT (I422_12BE, "raw video", 0x00000000, DPTH12_12_12,
4836       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_12BE),
4837   MAKE_YUV_LE_FORMAT (I422_12LE, "raw video", 0x00000000, DPTH12_12_12,
4838       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_12LE),
4839   MAKE_YUV_FORMAT (Y444_12BE, "raw video", 0x00000000, DPTH12_12_12,
4840       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_12BE),
4841   MAKE_YUV_LE_FORMAT (Y444_12LE, "raw video", 0x00000000, DPTH12_12_12,
4842       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_12LE),
4843 };
4844
4845 static GstVideoFormat
4846 gst_video_format_from_rgb32_masks (int red_mask, int green_mask, int blue_mask)
4847 {
4848   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
4849       blue_mask == 0x0000ff00) {
4850     return GST_VIDEO_FORMAT_RGBx;
4851   }
4852   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
4853       blue_mask == 0xff000000) {
4854     return GST_VIDEO_FORMAT_BGRx;
4855   }
4856   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
4857       blue_mask == 0x000000ff) {
4858     return GST_VIDEO_FORMAT_xRGB;
4859   }
4860   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
4861       blue_mask == 0x00ff0000) {
4862     return GST_VIDEO_FORMAT_xBGR;
4863   }
4864
4865   return GST_VIDEO_FORMAT_UNKNOWN;
4866 }
4867
4868 static GstVideoFormat
4869 gst_video_format_from_rgba32_masks (int red_mask, int green_mask,
4870     int blue_mask, int alpha_mask)
4871 {
4872   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
4873       blue_mask == 0x0000ff00 && alpha_mask == 0x000000ff) {
4874     return GST_VIDEO_FORMAT_RGBA;
4875   }
4876   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
4877       blue_mask == 0xff000000 && alpha_mask == 0x000000ff) {
4878     return GST_VIDEO_FORMAT_BGRA;
4879   }
4880   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
4881       blue_mask == 0x000000ff && alpha_mask == 0xff000000) {
4882     return GST_VIDEO_FORMAT_ARGB;
4883   }
4884   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
4885       blue_mask == 0x00ff0000 && alpha_mask == 0xff000000) {
4886     return GST_VIDEO_FORMAT_ABGR;
4887   }
4888   return GST_VIDEO_FORMAT_UNKNOWN;
4889 }
4890
4891 static GstVideoFormat
4892 gst_video_format_from_rgb24_masks (int red_mask, int green_mask, int blue_mask)
4893 {
4894   if (red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff) {
4895     return GST_VIDEO_FORMAT_RGB;
4896   }
4897   if (red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000) {
4898     return GST_VIDEO_FORMAT_BGR;
4899   }
4900
4901   return GST_VIDEO_FORMAT_UNKNOWN;
4902 }
4903
4904 #define GST_VIDEO_COMP1_MASK_16_INT 0xf800
4905 #define GST_VIDEO_COMP2_MASK_16_INT 0x07e0
4906 #define GST_VIDEO_COMP3_MASK_16_INT 0x001f
4907
4908 #define GST_VIDEO_COMP1_MASK_15_INT 0x7c00
4909 #define GST_VIDEO_COMP2_MASK_15_INT 0x03e0
4910 #define GST_VIDEO_COMP3_MASK_15_INT 0x001f
4911
4912 static GstVideoFormat
4913 gst_video_format_from_rgb16_masks (int red_mask, int green_mask, int blue_mask)
4914 {
4915   if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
4916       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
4917       && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
4918     return GST_VIDEO_FORMAT_RGB16;
4919   }
4920   if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
4921       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
4922       && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
4923     return GST_VIDEO_FORMAT_BGR16;
4924   }
4925   if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
4926       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
4927       && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
4928     return GST_VIDEO_FORMAT_RGB15;
4929   }
4930   if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
4931       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
4932       && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
4933     return GST_VIDEO_FORMAT_BGR15;
4934   }
4935   return GST_VIDEO_FORMAT_UNKNOWN;
4936 }
4937
4938 /**
4939  * gst_video_format_from_masks:
4940  * @depth: the amount of bits used for a pixel
4941  * @bpp: the amount of bits used to store a pixel. This value is bigger than
4942  *   @depth
4943  * @endianness: the endianness of the masks, #G_LITTLE_ENDIAN or #G_BIG_ENDIAN
4944  * @red_mask: the red mask
4945  * @green_mask: the green mask
4946  * @blue_mask: the blue mask
4947  * @alpha_mask: the alpha mask, or 0 if no alpha mask
4948  *
4949  * Find the #GstVideoFormat for the given parameters.
4950  *
4951  * Returns: a #GstVideoFormat or GST_VIDEO_FORMAT_UNKNOWN when the parameters to
4952  * not specify a known format.
4953  */
4954 GstVideoFormat
4955 gst_video_format_from_masks (gint depth, gint bpp, gint endianness,
4956     guint red_mask, guint green_mask, guint blue_mask, guint alpha_mask)
4957 {
4958   GstVideoFormat format;
4959
4960   /* our caps system handles 24/32bpp RGB as big-endian. */
4961   if ((bpp == 24 || bpp == 32) && endianness == G_LITTLE_ENDIAN) {
4962     red_mask = GUINT32_TO_BE (red_mask);
4963     green_mask = GUINT32_TO_BE (green_mask);
4964     blue_mask = GUINT32_TO_BE (blue_mask);
4965     alpha_mask = GUINT32_TO_BE (alpha_mask);
4966     endianness = G_BIG_ENDIAN;
4967     if (bpp == 24) {
4968       red_mask >>= 8;
4969       green_mask >>= 8;
4970       blue_mask >>= 8;
4971     }
4972   }
4973
4974   if (depth == 30 && bpp == 32) {
4975     format = GST_VIDEO_FORMAT_r210;
4976   } else if (depth == 24 && bpp == 32) {
4977     format = gst_video_format_from_rgb32_masks (red_mask, green_mask,
4978         blue_mask);
4979   } else if (depth == 32 && bpp == 32 && alpha_mask) {
4980     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
4981         blue_mask, alpha_mask);
4982   } else if (depth == 24 && bpp == 24) {
4983     format = gst_video_format_from_rgb24_masks (red_mask, green_mask,
4984         blue_mask);
4985   } else if ((depth == 15 || depth == 16) && bpp == 16 &&
4986       endianness == G_BYTE_ORDER) {
4987     format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
4988         blue_mask);
4989   } else if (depth == 8 && bpp == 8) {
4990     format = GST_VIDEO_FORMAT_RGB8P;
4991   } else if (depth == 64 && bpp == 64) {
4992     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
4993         blue_mask, alpha_mask);
4994     if (format == GST_VIDEO_FORMAT_ARGB) {
4995       format = GST_VIDEO_FORMAT_ARGB64;
4996     } else {
4997       format = GST_VIDEO_FORMAT_UNKNOWN;
4998     }
4999   } else {
5000     format = GST_VIDEO_FORMAT_UNKNOWN;
5001   }
5002   return format;
5003 }
5004
5005 /**
5006  * gst_video_format_from_fourcc:
5007  * @fourcc: a FOURCC value representing raw YUV video
5008  *
5009  * Converts a FOURCC value into the corresponding #GstVideoFormat.
5010  * If the FOURCC cannot be represented by #GstVideoFormat,
5011  * #GST_VIDEO_FORMAT_UNKNOWN is returned.
5012  *
5013  * Returns: the #GstVideoFormat describing the FOURCC value
5014  */
5015 GstVideoFormat
5016 gst_video_format_from_fourcc (guint32 fourcc)
5017 {
5018   switch (fourcc) {
5019     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5020       return GST_VIDEO_FORMAT_I420;
5021     case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5022       return GST_VIDEO_FORMAT_YV12;
5023     case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5024       return GST_VIDEO_FORMAT_YUY2;
5025     case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
5026       return GST_VIDEO_FORMAT_YVYU;
5027     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5028       return GST_VIDEO_FORMAT_UYVY;
5029     case GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y'):
5030       return GST_VIDEO_FORMAT_VYUY;
5031     case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5032       return GST_VIDEO_FORMAT_AYUV;
5033     case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
5034       return GST_VIDEO_FORMAT_Y41B;
5035     case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
5036       return GST_VIDEO_FORMAT_Y42B;
5037     case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
5038       return GST_VIDEO_FORMAT_Y444;
5039     case GST_MAKE_FOURCC ('v', '2', '1', '0'):
5040       return GST_VIDEO_FORMAT_v210;
5041     case GST_MAKE_FOURCC ('v', '2', '1', '6'):
5042       return GST_VIDEO_FORMAT_v216;
5043     case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
5044       return GST_VIDEO_FORMAT_NV12;
5045     case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
5046       return GST_VIDEO_FORMAT_NV21;
5047     case GST_MAKE_FOURCC ('N', 'V', '1', '6'):
5048       return GST_VIDEO_FORMAT_NV16;
5049     case GST_MAKE_FOURCC ('N', 'V', '6', '1'):
5050       return GST_VIDEO_FORMAT_NV61;
5051     case GST_MAKE_FOURCC ('N', 'V', '2', '4'):
5052       return GST_VIDEO_FORMAT_NV24;
5053     case GST_MAKE_FOURCC ('v', '3', '0', '8'):
5054       return GST_VIDEO_FORMAT_v308;
5055     case GST_MAKE_FOURCC ('I', 'Y', 'U', '2'):
5056       return GST_VIDEO_FORMAT_IYU2;
5057     case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5058     case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5059     case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
5060       return GST_VIDEO_FORMAT_GRAY8;
5061     case GST_MAKE_FOURCC ('Y', '1', '6', ' '):
5062       return GST_VIDEO_FORMAT_GRAY16_LE;
5063     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'):
5064       return GST_VIDEO_FORMAT_UYVP;
5065     case GST_MAKE_FOURCC ('A', '4', '2', '0'):
5066       return GST_VIDEO_FORMAT_A420;
5067     case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
5068       return GST_VIDEO_FORMAT_YUV9;
5069     case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
5070       return GST_VIDEO_FORMAT_YVU9;
5071     case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
5072       return GST_VIDEO_FORMAT_IYU1;
5073     case GST_MAKE_FOURCC ('A', 'Y', '6', '4'):
5074       return GST_VIDEO_FORMAT_AYUV64;
5075     default:
5076       return GST_VIDEO_FORMAT_UNKNOWN;
5077   }
5078 }
5079
5080 /**
5081  * gst_video_format_from_string:
5082  * @format: a format string
5083  *
5084  * Convert the @format string to its #GstVideoFormat.
5085  *
5086  * Returns: the #GstVideoFormat for @format or GST_VIDEO_FORMAT_UNKNOWN when the
5087  * string is not a known format.
5088  */
5089 GstVideoFormat
5090 gst_video_format_from_string (const gchar * format)
5091 {
5092   guint i;
5093
5094   g_return_val_if_fail (format != NULL, GST_VIDEO_FORMAT_UNKNOWN);
5095
5096   for (i = 0; i < G_N_ELEMENTS (formats); i++) {
5097     if (strcmp (GST_VIDEO_FORMAT_INFO_NAME (&formats[i].info), format) == 0)
5098       return GST_VIDEO_FORMAT_INFO_FORMAT (&formats[i].info);
5099   }
5100   return GST_VIDEO_FORMAT_UNKNOWN;
5101 }
5102
5103
5104 /**
5105  * gst_video_format_to_fourcc:
5106  * @format: a #GstVideoFormat video format
5107  *
5108  * Converts a #GstVideoFormat value into the corresponding FOURCC.  Only
5109  * a few YUV formats have corresponding FOURCC values.  If @format has
5110  * no corresponding FOURCC value, 0 is returned.
5111  *
5112  * Returns: the FOURCC corresponding to @format
5113  */
5114 guint32
5115 gst_video_format_to_fourcc (GstVideoFormat format)
5116 {
5117   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
5118
5119   if ((gint) format >= G_N_ELEMENTS (formats))
5120     return 0;
5121
5122   return formats[format].fourcc;
5123 }
5124
5125 /**
5126  * gst_video_format_to_string:
5127  * @format: a #GstVideoFormat video format
5128  *
5129  * Returns a string containing a descriptive name for
5130  * the #GstVideoFormat if there is one, or NULL otherwise.
5131  *
5132  * Returns: the name corresponding to @format
5133  */
5134 const gchar *
5135 gst_video_format_to_string (GstVideoFormat format)
5136 {
5137   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
5138
5139   if ((gint) format >= G_N_ELEMENTS (formats))
5140     return NULL;
5141
5142   return GST_VIDEO_FORMAT_INFO_NAME (&formats[format].info);
5143 }
5144
5145 /**
5146  * gst_video_format_get_info:
5147  * @format: a #GstVideoFormat
5148  *
5149  * Get the #GstVideoFormatInfo for @format
5150  *
5151  * Returns: The #GstVideoFormatInfo for @format.
5152  */
5153 const GstVideoFormatInfo *
5154 gst_video_format_get_info (GstVideoFormat format)
5155 {
5156   g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
5157
5158   return &formats[format].info;
5159 }
5160
5161 /**
5162  * gst_video_format_get_palette:
5163  * @format: a #GstVideoFormat
5164  * @size: (out): size of the palette in bytes
5165  *
5166  * Get the default palette of @format. This the palette used in the pack
5167  * function for paletted formats.
5168  *
5169  * Returns: (transfer none): the default palette of @format or %NULL when
5170  * @format does not have a palette.
5171  *
5172  * Since: 1.2
5173  */
5174 gconstpointer
5175 gst_video_format_get_palette (GstVideoFormat format, gsize * size)
5176 {
5177   g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
5178   g_return_val_if_fail (size != NULL, NULL);
5179
5180   switch (format) {
5181     case GST_VIDEO_FORMAT_RGB8P:
5182       *size = sizeof (std_palette_RGB8P);
5183       return std_palette_RGB8P;
5184     default:
5185       return NULL;
5186   }
5187 }