4589e2f883031245fd37e7f077af8319d1118dfb
[platform/upstream/gstreamer.git] / gst-libs / gst / video / video-format.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Library       <2002> Ronald Bultje <rbultje@ronald.bitfreak.net>
4  * Copyright (C) 2007 David A. Schleef <ds@schleef.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28
29 #include "video-format.h"
30 #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 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1332   video_orc_unpack_ABGR_le (dest, s, width);
1333 #else
1334   video_orc_unpack_ABGR_be (dest, s, width);
1335 #endif
1336 }
1337
1338 static void
1339 pack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1340     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1341     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1342     gint y, gint width)
1343 {
1344   guint8 *restrict d = GET_LINE (y);
1345
1346 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1347   video_orc_pack_ABGR_le (d, src, width);
1348 #else
1349   video_orc_pack_ABGR_be (d, src, width);
1350 #endif
1351 }
1352
1353 #define PACK_RGBA GST_VIDEO_FORMAT_ARGB, unpack_RGBA, 1, pack_RGBA
1354 static void
1355 unpack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1356     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1357     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1358 {
1359   const guint8 *restrict s = GET_LINE (y);
1360
1361   s += x * 4;
1362
1363 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1364   video_orc_unpack_RGBA_le (dest, s, width);
1365 #else
1366   video_orc_unpack_RGBA_be (dest, s, width);
1367 #endif
1368 }
1369
1370 static void
1371 pack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1372     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1373     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1374     gint y, gint width)
1375 {
1376   guint8 *restrict d = GET_LINE (y);
1377
1378 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1379   video_orc_pack_RGBA_le (d, src, width);
1380 #else
1381   video_orc_pack_RGBA_be (d, src, width);
1382 #endif
1383 }
1384
1385 #define PACK_RGB GST_VIDEO_FORMAT_ARGB, unpack_RGB, 1, pack_RGB
1386 static void
1387 unpack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1388     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1389     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1390 {
1391   int i;
1392   const guint8 *restrict s = GET_LINE (y);
1393   guint8 *restrict d = dest;
1394
1395   s += x * 3;
1396
1397   for (i = 0; i < width; i++) {
1398     d[i * 4 + 0] = 0xff;
1399     d[i * 4 + 1] = s[i * 3 + 0];
1400     d[i * 4 + 2] = s[i * 3 + 1];
1401     d[i * 4 + 3] = s[i * 3 + 2];
1402   }
1403 }
1404
1405 static void
1406 pack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1407     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1408     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1409     gint y, gint width)
1410 {
1411   int i;
1412   guint8 *restrict d = GET_LINE (y);
1413   const guint8 *restrict s = src;
1414
1415   for (i = 0; i < width; i++) {
1416     d[i * 3 + 0] = s[i * 4 + 1];
1417     d[i * 3 + 1] = s[i * 4 + 2];
1418     d[i * 3 + 2] = s[i * 4 + 3];
1419   }
1420 }
1421
1422 #define PACK_BGR GST_VIDEO_FORMAT_ARGB, unpack_BGR, 1, pack_BGR
1423 static void
1424 unpack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1425     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1426     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1427 {
1428   int i;
1429   const guint8 *restrict s = GET_LINE (y);
1430   guint8 *restrict d = dest;
1431
1432   s += x * 3;
1433
1434   for (i = 0; i < width; i++) {
1435     d[i * 4 + 0] = 0xff;
1436     d[i * 4 + 1] = s[i * 3 + 2];
1437     d[i * 4 + 2] = s[i * 3 + 1];
1438     d[i * 4 + 3] = s[i * 3 + 0];
1439   }
1440 }
1441
1442 static void
1443 pack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1444     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1445     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1446     gint y, gint width)
1447 {
1448   int i;
1449   guint8 *restrict d = GET_LINE (y);
1450   const guint8 *restrict s = src;
1451
1452   for (i = 0; i < width; i++) {
1453     d[i * 3 + 0] = s[i * 4 + 3];
1454     d[i * 3 + 1] = s[i * 4 + 2];
1455     d[i * 3 + 2] = s[i * 4 + 1];
1456   }
1457 }
1458
1459 #define PACK_NV12 GST_VIDEO_FORMAT_AYUV, unpack_NV12, 1, pack_NV12
1460 static void
1461 unpack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1462     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1463     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1464 {
1465   gint uv = GET_UV_420 (y, flags);
1466   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1467   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
1468   guint8 *restrict d = dest;
1469
1470   sy += x;
1471   suv += (x & ~1);
1472
1473   if (x & 1) {
1474     d[0] = 0xff;
1475     d[1] = *sy++;
1476     d[2] = suv[0];
1477     d[3] = suv[1];
1478     width--;
1479     d += 4;
1480     suv += 2;
1481   }
1482
1483   if (IS_ALIGNED (d, 8))
1484     video_orc_unpack_NV12 (d, sy, suv, width / 2);
1485   else {
1486     gint i;
1487     for (i = 0; i < width / 2; i++) {
1488       d[i * 8 + 0] = 0xff;
1489       d[i * 8 + 1] = sy[i * 2 + 0];
1490       d[i * 8 + 2] = suv[i * 2 + 0];
1491       d[i * 8 + 3] = suv[i * 2 + 1];
1492       d[i * 8 + 4] = 0xff;
1493       d[i * 8 + 5] = sy[i * 2 + 1];
1494       d[i * 8 + 6] = suv[i * 2 + 0];
1495       d[i * 8 + 7] = suv[i * 2 + 1];
1496     }
1497   }
1498
1499   if (width & 1) {
1500     gint i = width - 1;
1501
1502     d[i * 4 + 0] = 0xff;
1503     d[i * 4 + 1] = sy[i];
1504     d[i * 4 + 2] = suv[i + 0];
1505     d[i * 4 + 3] = suv[i + 1];
1506   }
1507 }
1508
1509 static void
1510 pack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1511     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1512     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1513     gint y, gint width)
1514 {
1515   gint uv = GET_UV_420 (y, flags);
1516   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1517   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
1518   const guint8 *restrict s = src;
1519
1520   if (IS_CHROMA_LINE_420 (y, flags)) {
1521     if (IS_ALIGNED (s, 8))
1522       video_orc_pack_NV12 (dy, duv, s, width / 2);
1523     else {
1524       gint i;
1525       for (i = 0; i < width / 2; i++) {
1526         dy[i * 2 + 0] = s[i * 8 + 1];
1527         dy[i * 2 + 1] = s[i * 8 + 5];
1528         duv[i * 2 + 0] = s[i * 8 + 2];
1529         duv[i * 2 + 1] = s[i * 8 + 3];
1530       }
1531     }
1532     if (width & 1) {
1533       gint i = width - 1;
1534
1535       dy[i] = s[i * 4 + 1];
1536       duv[i + 0] = s[i * 4 + 2];
1537       duv[i + 1] = s[i * 4 + 3];
1538     }
1539   } else
1540     video_orc_pack_Y (dy, s, width);
1541 }
1542
1543 #define PACK_NV21 GST_VIDEO_FORMAT_AYUV, unpack_NV21, 1, pack_NV21
1544 static void
1545 unpack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1546     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1547     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1548 {
1549   gint uv = GET_UV_420 (y, flags);
1550   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1551   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
1552   guint8 *restrict d = dest;
1553
1554   sy += x;
1555   suv += (x & ~1);
1556
1557   if (x & 1) {
1558     d[0] = 0xff;
1559     d[1] = *sy++;
1560     d[2] = suv[1];
1561     d[3] = suv[0];
1562     width--;
1563     d += 4;
1564     suv += 2;
1565   }
1566
1567   if (IS_ALIGNED (d, 8))
1568     video_orc_unpack_NV21 (d, sy, suv, width / 2);
1569   else {
1570     gint i;
1571     for (i = 0; i < width / 2; i++) {
1572       d[i * 8 + 0] = 0xff;
1573       d[i * 8 + 1] = sy[i * 2 + 0];
1574       d[i * 8 + 2] = suv[i * 2 + 1];
1575       d[i * 8 + 3] = suv[i * 2 + 0];
1576       d[i * 8 + 4] = 0xff;
1577       d[i * 8 + 5] = sy[i * 2 + 1];
1578       d[i * 8 + 6] = suv[i * 2 + 1];
1579       d[i * 8 + 7] = suv[i * 2 + 0];
1580     }
1581   }
1582
1583   if (width & 1) {
1584     gint i = width - 1;
1585
1586     d[i * 4 + 0] = 0xff;
1587     d[i * 4 + 1] = sy[i];
1588     d[i * 4 + 2] = suv[i + 1];
1589     d[i * 4 + 3] = suv[i + 0];
1590   }
1591 }
1592
1593 static void
1594 pack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1595     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1596     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1597     gint y, gint width)
1598 {
1599   gint uv = GET_UV_420 (y, flags);
1600   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1601   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
1602   const guint8 *restrict s = src;
1603
1604   if (IS_CHROMA_LINE_420 (y, flags)) {
1605     if (IS_ALIGNED (s, 8))
1606       video_orc_pack_NV21 (dy, duv, s, width / 2);
1607     else {
1608       gint i;
1609       for (i = 0; i < width / 2; i++) {
1610         dy[i * 2 + 0] = s[i * 8 + 1];
1611         dy[i * 2 + 1] = s[i * 8 + 5];
1612         duv[i * 2 + 0] = s[i * 8 + 3];
1613         duv[i * 2 + 1] = s[i * 8 + 2];
1614       }
1615     }
1616     if (width & 1) {
1617       gint i = width - 1;
1618
1619       dy[i] = s[i * 4 + 1];
1620       duv[i + 0] = s[i * 4 + 3];
1621       duv[i + 1] = s[i * 4 + 2];
1622     }
1623   } else
1624     video_orc_pack_Y (dy, s, width);
1625 }
1626
1627 #define PACK_NV16 GST_VIDEO_FORMAT_AYUV, unpack_NV16, 1, pack_NV16
1628 static void
1629 unpack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1630     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1631     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1632 {
1633   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1634   const guint8 *restrict suv = GET_PLANE_LINE (1, y);
1635   guint8 *restrict d = dest;
1636
1637   sy += x;
1638   suv += (x & ~1);
1639
1640   if (x & 1) {
1641     d[0] = 0xff;
1642     d[1] = *sy++;
1643     d[2] = suv[0];
1644     d[3] = suv[1];
1645     width--;
1646     d += 4;
1647     suv += 2;
1648   }
1649
1650   if (IS_ALIGNED (d, 8))
1651     video_orc_unpack_NV12 (d, sy, suv, width / 2);
1652   else {
1653     gint i;
1654     for (i = 0; i < width / 2; i++) {
1655       d[i * 8 + 0] = 0xff;
1656       d[i * 8 + 1] = sy[i * 2 + 0];
1657       d[i * 8 + 2] = suv[i * 2 + 0];
1658       d[i * 8 + 3] = suv[i * 2 + 1];
1659       d[i * 8 + 4] = 0xff;
1660       d[i * 8 + 5] = sy[i * 2 + 1];
1661       d[i * 8 + 6] = suv[i * 2 + 0];
1662       d[i * 8 + 7] = suv[i * 2 + 1];
1663     }
1664   }
1665
1666   if (width & 1) {
1667     gint i = width - 1;
1668
1669     d[i * 4 + 0] = 0xff;
1670     d[i * 4 + 1] = sy[i];
1671     d[i * 4 + 2] = suv[i + 0];
1672     d[i * 4 + 3] = suv[i + 1];
1673   }
1674 }
1675
1676 static void
1677 pack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1678     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1679     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1680     gint y, gint width)
1681 {
1682   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1683   guint8 *restrict duv = GET_PLANE_LINE (1, y);
1684   const guint8 *restrict s = src;
1685
1686   if (IS_ALIGNED (s, 8))
1687     video_orc_pack_NV12 (dy, duv, s, width / 2);
1688   else {
1689     gint i;
1690     for (i = 0; i < width / 2; i++) {
1691       dy[i * 2 + 0] = s[i * 8 + 1];
1692       dy[i * 2 + 1] = s[i * 8 + 5];
1693       duv[i * 2 + 0] = s[i * 8 + 2];
1694       duv[i * 2 + 1] = s[i * 8 + 3];
1695     }
1696   }
1697
1698   if (width & 1) {
1699     gint i = width - 1;
1700
1701     dy[i] = s[i * 4 + 1];
1702     duv[i + 0] = s[i * 4 + 2];
1703     duv[i + 1] = s[i * 4 + 3];
1704   }
1705 }
1706
1707 #define PACK_NV61 GST_VIDEO_FORMAT_AYUV, unpack_NV61, 1, pack_NV61
1708 static void
1709 unpack_NV61 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1710     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1711     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1712 {
1713   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1714   const guint8 *restrict svu = GET_PLANE_LINE (1, y);
1715   guint8 *restrict d = dest;
1716
1717   sy += x;
1718   svu += (x & ~1);
1719
1720   if (x & 1) {
1721     d[0] = 0xff;
1722     d[1] = *sy++;
1723     d[2] = svu[1];
1724     d[3] = svu[0];
1725     width--;
1726     d += 4;
1727     svu += 2;
1728   }
1729
1730   if (IS_ALIGNED (d, 8)) {
1731     video_orc_unpack_NV21 (d, sy, svu, width / 2);
1732   } else {
1733     gint i;
1734
1735     for (i = 0; i < width / 2; i++) {
1736       d[i * 8 + 0] = 0xff;
1737       d[i * 8 + 1] = sy[i * 2 + 0];
1738       d[i * 8 + 2] = svu[i * 2 + 1];
1739       d[i * 8 + 3] = svu[i * 2 + 0];
1740       d[i * 8 + 4] = 0xff;
1741       d[i * 8 + 5] = sy[i * 2 + 1];
1742       d[i * 8 + 6] = svu[i * 2 + 1];
1743       d[i * 8 + 7] = svu[i * 2 + 0];
1744     }
1745   }
1746
1747   if (width & 1) {
1748     gint i = width - 1;
1749
1750     d[i * 4 + 0] = 0xff;
1751     d[i * 4 + 1] = sy[i];
1752     d[i * 4 + 2] = svu[i + 1];
1753     d[i * 4 + 3] = svu[i + 0];
1754   }
1755 }
1756
1757 static void
1758 pack_NV61 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1759     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1760     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1761     gint y, gint width)
1762 {
1763   const guint8 *restrict s = src;
1764   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1765   guint8 *restrict dvu = GET_PLANE_LINE (1, y);
1766
1767   if (IS_ALIGNED (s, 8)) {
1768     video_orc_pack_NV21 (dy, dvu, s, width / 2);
1769   } else {
1770     gint i;
1771
1772     for (i = 0; i < width / 2; i++) {
1773       dy[i * 2 + 0] = s[i * 8 + 1];
1774       dy[i * 2 + 1] = s[i * 8 + 5];
1775       dvu[i * 2 + 0] = s[i * 8 + 3];
1776       dvu[i * 2 + 1] = s[i * 8 + 2];
1777     }
1778   }
1779
1780   if (width & 1) {
1781     gint i = width - 1;
1782
1783     dy[i] = s[i * 4 + 1];
1784     dvu[i + 0] = s[i * 4 + 2];
1785     dvu[i + 1] = s[i * 4 + 3];
1786   }
1787 }
1788
1789 #define PACK_NV24 GST_VIDEO_FORMAT_AYUV, unpack_NV24, 1, pack_NV24
1790 static void
1791 unpack_NV24 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1792     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1793     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1794 {
1795   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1796   const guint8 *restrict suv = GET_PLANE_LINE (1, y);
1797
1798   sy += x;
1799   suv += x << 1;
1800
1801   video_orc_unpack_NV24 (dest, sy, suv, width);
1802 }
1803
1804 static void
1805 pack_NV24 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1806     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1807     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1808     gint y, gint width)
1809 {
1810   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1811   guint8 *restrict duv = GET_PLANE_LINE (1, y);
1812
1813   video_orc_pack_NV24 (dy, duv, src, width);
1814 }
1815
1816 #define PACK_UYVP GST_VIDEO_FORMAT_AYUV64, unpack_UYVP, 1, pack_UYVP
1817 static void
1818 unpack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1819     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1820     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1821 {
1822   int i;
1823   const guint8 *restrict s = GET_LINE (y);
1824   guint16 *restrict d = dest;
1825
1826   /* FIXME */
1827   s += x << 1;
1828
1829   for (i = 0; i < width; i += 2) {
1830     guint16 y0, y1;
1831     guint16 u0;
1832     guint16 v0;
1833
1834     u0 = ((s[(i / 2) * 5 + 0] << 2) | (s[(i / 2) * 5 + 1] >> 6)) << 6;
1835     y0 = (((s[(i / 2) * 5 + 1] & 0x3f) << 4) | (s[(i / 2) * 5 + 2] >> 4)) << 6;
1836     v0 = (((s[(i / 2) * 5 + 2] & 0x0f) << 6) | (s[(i / 2) * 5 + 3] >> 2)) << 6;
1837     y1 = (((s[(i / 2) * 5 + 3] & 0x03) << 8) | s[(i / 2) * 5 + 4]) << 6;
1838
1839     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
1840       y0 |= (y0 >> 10);
1841       y1 |= (y1 >> 10);
1842       u0 |= (u0 >> 10);
1843       v0 |= (v0 >> 10);
1844     }
1845
1846     d[i * 4 + 0] = 0xffff;
1847     d[i * 4 + 1] = y0;
1848     d[i * 4 + 2] = u0;
1849     d[i * 4 + 3] = v0;
1850
1851     if (i < width - 1) {
1852       d[i * 4 + 4] = 0xffff;
1853       d[i * 4 + 5] = y1;
1854       d[i * 4 + 6] = u0;
1855       d[i * 4 + 7] = v0;
1856     }
1857   }
1858 }
1859
1860 static void
1861 pack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1862     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1863     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1864     gint y, gint width)
1865 {
1866   int i;
1867   guint8 *restrict d = GET_LINE (y);
1868   const guint16 *restrict s = src;
1869
1870   for (i = 0; i < width; i += 2) {
1871     guint16 y0, y1;
1872     guint16 u0;
1873     guint16 v0;
1874
1875     y0 = s[4 * (i + 0) + 1];
1876     if (i < width - 1)
1877       y1 = s[4 * (i + 1) + 1];
1878     else
1879       y1 = y0;
1880
1881     u0 = s[4 * (i + 0) + 2];
1882     v0 = s[4 * (i + 0) + 3];
1883
1884     d[(i / 2) * 5 + 0] = u0 >> 8;
1885     d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10;
1886     d[(i / 2) * 5 + 2] = ((y0 & 0x3c0) >> 2) | (v0 >> 12);
1887     d[(i / 2) * 5 + 3] = ((v0 & 0xfc0) >> 4) | (y1 >> 14);
1888     d[(i / 2) * 5 + 4] = (y1 >> 6);
1889   }
1890 }
1891
1892 #define PACK_A420 GST_VIDEO_FORMAT_AYUV, unpack_A420, 1, pack_A420
1893 static void
1894 unpack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1895     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1896     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1897 {
1898   gint uv = GET_UV_420 (y, flags);
1899   const guint8 *restrict sy = GET_Y_LINE (y);
1900   const guint8 *restrict su = GET_U_LINE (uv);
1901   const guint8 *restrict sv = GET_V_LINE (uv);
1902   const guint8 *restrict sa = GET_A_LINE (y);
1903   guint8 *restrict d = dest;
1904
1905   sy += x;
1906   su += x >> 1;
1907   sv += x >> 1;
1908   sa += x;
1909
1910   if (x & 1) {
1911     d[0] = *sa++;
1912     d[1] = *sy++;
1913     d[2] = *su++;
1914     d[3] = *sv++;
1915     width--;
1916     d += 4;
1917   }
1918   video_orc_unpack_A420 (d, sy, su, sv, sa, width);
1919 }
1920
1921 static void
1922 pack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1923     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1924     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1925     gint y, gint width)
1926 {
1927   gint uv = GET_UV_420 (y, flags);
1928   guint8 *restrict dy = GET_Y_LINE (y);
1929   guint8 *restrict du = GET_U_LINE (uv);
1930   guint8 *restrict dv = GET_V_LINE (uv);
1931   guint8 *restrict da = GET_A_LINE (y);
1932   const guint8 *restrict s = src;
1933
1934   if (IS_CHROMA_LINE_420 (y, flags)) {
1935     if (IS_ALIGNED (s, 8))
1936       video_orc_pack_A420 (dy, du, dv, da, s, width / 2);
1937     else {
1938       gint i;
1939       for (i = 0; i < width / 2; i++) {
1940         da[i * 2 + 0] = s[i * 8 + 0];
1941         dy[i * 2 + 0] = s[i * 8 + 1];
1942         da[i * 2 + 1] = s[i * 8 + 4];
1943         dy[i * 2 + 1] = s[i * 8 + 5];
1944         du[i] = s[i * 8 + 2];
1945         dv[i] = s[i * 8 + 3];
1946       }
1947     }
1948
1949     if (width & 1) {
1950       gint i = width - 1;
1951
1952       da[i] = s[i * 4 + 0];
1953       dy[i] = s[i * 4 + 1];
1954       du[i >> 1] = s[i * 4 + 2];
1955       dv[i >> 1] = s[i * 4 + 3];
1956     }
1957   } else
1958     video_orc_pack_AY (dy, da, s, width);
1959 }
1960
1961 #define PACK_RGB8P GST_VIDEO_FORMAT_ARGB, unpack_RGB8P, 1, pack_RGB8P
1962 static void
1963 unpack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1964     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1965     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1966 {
1967   int i;
1968   const guint8 *restrict s = GET_LINE (y);
1969   const guint32 *restrict p = data[1];
1970   guint8 *restrict d = dest;
1971
1972   s += x;
1973
1974   for (i = 0; i < width; i++) {
1975     guint32 v = p[s[i]];
1976     d[i * 4 + 0] = (v >> 24) & 0xff;
1977     d[i * 4 + 1] = (v >> 16) & 0xff;
1978     d[i * 4 + 2] = (v >> 8) & 0xff;
1979     d[i * 4 + 3] = (v) & 0xff;
1980   }
1981 }
1982
1983 static const guint32 std_palette_RGB8P[] = {
1984   0xff000000, 0xff000033, 0xff000066, 0xff000099, 0xff0000cc, 0xff0000ff,
1985   0xff003300, 0xff003333, 0xff003366, 0xff003399, 0xff0033cc, 0xff0033ff,
1986   0xff006600, 0xff006633, 0xff006666, 0xff006699, 0xff0066cc, 0xff0066ff,
1987   0xff009900, 0xff009933, 0xff009966, 0xff009999, 0xff0099cc, 0xff0099ff,
1988   0xff00cc00, 0xff00cc33, 0xff00cc66, 0xff00cc99, 0xff00cccc, 0xff00ccff,
1989   0xff00ff00, 0xff00ff33, 0xff00ff66, 0xff00ff99, 0xff00ffcc, 0xff00ffff,
1990   0xff330000, 0xff330033, 0xff330066, 0xff330099, 0xff3300cc, 0xff3300ff,
1991   0xff333300, 0xff333333, 0xff333366, 0xff333399, 0xff3333cc, 0xff3333ff,
1992   0xff336600, 0xff336633, 0xff336666, 0xff336699, 0xff3366cc, 0xff3366ff,
1993   0xff339900, 0xff339933, 0xff339966, 0xff339999, 0xff3399cc, 0xff3399ff,
1994   0xff33cc00, 0xff33cc33, 0xff33cc66, 0xff33cc99, 0xff33cccc, 0xff33ccff,
1995   0xff33ff00, 0xff33ff33, 0xff33ff66, 0xff33ff99, 0xff33ffcc, 0xff33ffff,
1996   0xff660000, 0xff660033, 0xff660066, 0xff660099, 0xff6600cc, 0xff6600ff,
1997   0xff663300, 0xff663333, 0xff663366, 0xff663399, 0xff6633cc, 0xff6633ff,
1998   0xff666600, 0xff666633, 0xff666666, 0xff666699, 0xff6666cc, 0xff6666ff,
1999   0xff669900, 0xff669933, 0xff669966, 0xff669999, 0xff6699cc, 0xff6699ff,
2000   0xff66cc00, 0xff66cc33, 0xff66cc66, 0xff66cc99, 0xff66cccc, 0xff66ccff,
2001   0xff66ff00, 0xff66ff33, 0xff66ff66, 0xff66ff99, 0xff66ffcc, 0xff66ffff,
2002   0xff990000, 0xff990033, 0xff990066, 0xff990099, 0xff9900cc, 0xff9900ff,
2003   0xff993300, 0xff993333, 0xff993366, 0xff993399, 0xff9933cc, 0xff9933ff,
2004   0xff996600, 0xff996633, 0xff996666, 0xff996699, 0xff9966cc, 0xff9966ff,
2005   0xff999900, 0xff999933, 0xff999966, 0xff999999, 0xff9999cc, 0xff9999ff,
2006   0xff99cc00, 0xff99cc33, 0xff99cc66, 0xff99cc99, 0xff99cccc, 0xff99ccff,
2007   0xff99ff00, 0xff99ff33, 0xff99ff66, 0xff99ff99, 0xff99ffcc, 0xff99ffff,
2008   0xffcc0000, 0xffcc0033, 0xffcc0066, 0xffcc0099, 0xffcc00cc, 0xffcc00ff,
2009   0xffcc3300, 0xffcc3333, 0xffcc3366, 0xffcc3399, 0xffcc33cc, 0xffcc33ff,
2010   0xffcc6600, 0xffcc6633, 0xffcc6666, 0xffcc6699, 0xffcc66cc, 0xffcc66ff,
2011   0xffcc9900, 0xffcc9933, 0xffcc9966, 0xffcc9999, 0xffcc99cc, 0xffcc99ff,
2012   0xffcccc00, 0xffcccc33, 0xffcccc66, 0xffcccc99, 0xffcccccc, 0xffccccff,
2013   0xffccff00, 0xffccff33, 0xffccff66, 0xffccff99, 0xffccffcc, 0xffccffff,
2014   0xffff0000, 0xffff0033, 0xffff0066, 0xffff0099, 0xffff00cc, 0xffff00ff,
2015   0xffff3300, 0xffff3333, 0xffff3366, 0xffff3399, 0xffff33cc, 0xffff33ff,
2016   0xffff6600, 0xffff6633, 0xffff6666, 0xffff6699, 0xffff66cc, 0xffff66ff,
2017   0xffff9900, 0xffff9933, 0xffff9966, 0xffff9999, 0xffff99cc, 0xffff99ff,
2018   0xffffcc00, 0xffffcc33, 0xffffcc66, 0xffffcc99, 0xffffcccc, 0xffffccff,
2019   0xffffff00, 0xffffff33, 0xffffff66, 0xffffff99, 0xffffffcc, 0xffffffff,
2020   0x00000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2021   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2022   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2023   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2024   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2025   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2026   0xff000000, 0xff000000, 0xff000000, 0xff000000
2027 };
2028
2029 static void
2030 pack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2031     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2032     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2033     gint y, gint width)
2034 {
2035   int i;
2036   guint8 *restrict d = GET_LINE (y);
2037   const guint8 *restrict s = src;
2038
2039   /* Use our poor man's palette, taken from ffmpegcolorspace too */
2040   for (i = 0; i < width; i++) {
2041     /* crude approximation for alpha ! */
2042     if (s[i * 4 + 0] < 0x80)
2043       d[i] = 6 * 6 * 6;
2044     else
2045       d[i] =
2046           ((((s[i * 4 + 1]) / 47) % 6) * 6 * 6 + (((s[i * 4 +
2047                           2]) / 47) % 6) * 6 + (((s[i * 4 + 3]) / 47) % 6));
2048   }
2049 }
2050
2051 #define PACK_410 GST_VIDEO_FORMAT_AYUV, unpack_410, 1, pack_410
2052 static void
2053 unpack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2054     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2055     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2056 {
2057   gint uv = GET_UV_410 (y, flags);
2058   const guint8 *restrict sy = GET_Y_LINE (y);
2059   const guint8 *restrict su = GET_U_LINE (uv);
2060   const guint8 *restrict sv = GET_V_LINE (uv);
2061   guint8 *restrict d = dest;
2062
2063   sy += x;
2064   su += x >> 2;
2065   sv += x >> 2;
2066
2067   if (x & 3) {
2068     for (; x & 3; x++) {
2069       d[0] = 0xff;
2070       d[1] = *sy++;
2071       d[2] = *su;
2072       d[3] = *sv;
2073       width--;
2074       d += 4;
2075     }
2076     su++;
2077     sy++;
2078   }
2079
2080   if (IS_ALIGNED (d, 8))
2081     video_orc_unpack_YUV9 (d, sy, su, sv, width / 2);
2082   else {
2083     gint i;
2084     for (i = 0; i < width / 2; i++) {
2085       d[i * 8 + 0] = 0xff;
2086       d[i * 8 + 1] = sy[i * 2 + 0];
2087       d[i * 8 + 2] = su[i >> 1];
2088       d[i * 8 + 3] = sv[i >> 1];
2089       d[i * 8 + 4] = 0xff;
2090       d[i * 8 + 5] = sy[i * 2 + 1];
2091       d[i * 8 + 6] = su[i >> 1];
2092       d[i * 8 + 7] = sv[i >> 1];
2093     }
2094   }
2095
2096   if (width & 1) {
2097     gint i = width - 1;
2098
2099     d[i * 4 + 0] = 0xff;
2100     d[i * 4 + 1] = sy[i];
2101     d[i * 4 + 2] = su[i >> 2];
2102     d[i * 4 + 3] = sv[i >> 2];
2103   }
2104 }
2105
2106 static void
2107 pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2108     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2109     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2110     gint y, gint width)
2111 {
2112   int i;
2113   gint uv = GET_UV_410 (y, flags);
2114   guint8 *restrict dy = GET_Y_LINE (y);
2115   guint8 *restrict du = GET_U_LINE (uv);
2116   guint8 *restrict dv = GET_V_LINE (uv);
2117   const guint8 *restrict s = src;
2118
2119   for (i = 0; i < width - 3; i += 4) {
2120     dy[i] = s[i * 4 + 1];
2121     dy[i + 1] = s[i * 4 + 5];
2122     dy[i + 2] = s[i * 4 + 9];
2123     dy[i + 3] = s[i * 4 + 13];
2124     if (IS_CHROMA_LINE_410 (y, flags)) {
2125       du[i >> 2] = s[i * 4 + 2];
2126       dv[i >> 2] = s[i * 4 + 3];
2127     }
2128   }
2129   if (i < width) {
2130     dy[i] = s[i * 4 + 1];
2131     if (IS_CHROMA_LINE_410 (y, flags)) {
2132       du[i >> 2] = s[i * 4 + 2];
2133       dv[i >> 2] = s[i * 4 + 3];
2134     }
2135     if (i < width - 1)
2136       dy[i + 1] = s[i * 4 + 5];
2137     if (i < width - 2)
2138       dy[i + 2] = s[i * 4 + 9];
2139   }
2140 }
2141
2142 #define PACK_IYU1 GST_VIDEO_FORMAT_AYUV, unpack_IYU1, 1, pack_IYU1
2143 static void
2144 unpack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2145     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2146     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2147 {
2148   int i;
2149   const guint8 *restrict s = GET_LINE (y);
2150   guint8 *restrict d = dest;
2151   guint8 y0, y1, y2, y3;
2152   guint8 u0;
2153   guint8 v0;
2154
2155   /* FIXME */
2156   s += x * 4;
2157
2158   for (i = 0; i < width - 3; i += 4) {
2159     y0 = s[(i >> 2) * 6 + 1];
2160     y1 = s[(i >> 2) * 6 + 2];
2161     y2 = s[(i >> 2) * 6 + 4];
2162     y3 = s[(i >> 2) * 6 + 5];
2163
2164     u0 = s[(i >> 2) * 6 + 0];
2165     v0 = s[(i >> 2) * 6 + 3];
2166
2167     d[i * 4 + 0] = 0xff;
2168     d[i * 4 + 1] = y0;
2169     d[i * 4 + 2] = u0;
2170     d[i * 4 + 3] = v0;
2171
2172     d[i * 4 + 4] = 0xff;
2173     d[i * 4 + 5] = y1;
2174     d[i * 4 + 6] = u0;
2175     d[i * 4 + 7] = v0;
2176
2177     d[i * 4 + 8] = 0xff;
2178     d[i * 4 + 9] = y2;
2179     d[i * 4 + 10] = u0;
2180     d[i * 4 + 11] = v0;
2181
2182     d[i * 4 + 12] = 0xff;
2183     d[i * 4 + 13] = y3;
2184     d[i * 4 + 14] = u0;
2185     d[i * 4 + 15] = v0;
2186   }
2187   if (i < width) {
2188     u0 = s[(i >> 2) * 6 + 0];
2189     v0 = s[(i >> 2) * 6 + 3];
2190
2191     d[i * 4 + 0] = 0xff;
2192     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
2193     d[i * 4 + 2] = u0;
2194     d[i * 4 + 3] = v0;
2195
2196     if (i < width - 1) {
2197       d[i * 4 + 4] = 0xff;
2198       d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
2199       d[i * 4 + 6] = u0;
2200       d[i * 4 + 7] = v0;
2201     }
2202     if (i < width - 2) {
2203       d[i * 4 + 8] = 0xff;
2204       d[i * 4 + 9] = s[(i >> 2) * 6 + 4];
2205       d[i * 4 + 10] = u0;
2206       d[i * 4 + 11] = v0;
2207     }
2208   }
2209 }
2210
2211 static void
2212 pack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2213     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2214     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2215     gint y, gint width)
2216 {
2217   int i;
2218   guint8 *restrict d = GET_LINE (y);
2219   const guint8 *restrict s = src;
2220
2221   for (i = 0; i < width - 3; i += 4) {
2222     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
2223     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
2224     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
2225     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
2226     d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
2227     d[(i >> 2) * 6 + 5] = s[i * 4 + 13];
2228   }
2229   if (i < width) {
2230     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
2231     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
2232     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
2233     if (i < width - 1)
2234       d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
2235     if (i < width - 2)
2236       d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
2237   }
2238 }
2239
2240 #define PACK_ARGB64 GST_VIDEO_FORMAT_ARGB64, unpack_copy8, 1, pack_copy8
2241 #define PACK_AYUV64 GST_VIDEO_FORMAT_AYUV64, unpack_copy8, 1, pack_copy8
2242 static void
2243 unpack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2244     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2245     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2246 {
2247   const guint8 *s = GET_LINE (y);
2248
2249   s += x * 8;
2250
2251   memcpy (dest, s, width * 8);
2252 }
2253
2254 static void
2255 pack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2256     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2257     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2258     gint y, gint width)
2259 {
2260   guint8 *restrict d = GET_LINE (y);
2261
2262   memcpy (d, src, width * 8);
2263 }
2264
2265 #define PACK_r210 GST_VIDEO_FORMAT_ARGB64, unpack_r210, 1, pack_r210
2266 static void
2267 unpack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2268     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2269     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2270 {
2271   int i;
2272   const guint8 *restrict s = GET_LINE (y);
2273   guint16 *restrict d = dest, R, G, B;
2274
2275   s += x * 4;
2276
2277   for (i = 0; i < width; i++) {
2278     guint32 x = GST_READ_UINT32_BE (s + i * 4);
2279
2280     R = ((x >> 14) & 0xffc0);
2281     G = ((x >> 4) & 0xffc0);
2282     B = ((x << 6) & 0xffc0);
2283
2284     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2285       R |= (R >> 10);
2286       G |= (G >> 10);
2287       B |= (B >> 10);
2288     }
2289
2290     d[i * 4 + 0] = 0xffff;
2291     d[i * 4 + 1] = R;
2292     d[i * 4 + 2] = G;
2293     d[i * 4 + 3] = B;
2294   }
2295 }
2296
2297 static void
2298 pack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2299     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2300     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2301     gint y, gint width)
2302 {
2303   int i;
2304   guint8 *restrict d = GET_LINE (y);
2305   const guint16 *restrict s = src;
2306
2307   for (i = 0; i < width; i++) {
2308     guint32 x = 0;
2309     x |= (s[i * 4 + 1] & 0xffc0) << 14;
2310     x |= (s[i * 4 + 2] & 0xffc0) << 4;
2311     x |= (s[i * 4 + 3] & 0xffc0) >> 6;
2312     GST_WRITE_UINT32_BE (d + i * 4, x);
2313   }
2314 }
2315
2316 #define PACK_GBR_10LE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10LE, 1, pack_GBR_10LE
2317 static void
2318 unpack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2319     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2320     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2321 {
2322   int i;
2323   const guint16 *sg = GET_G_LINE (y);
2324   const guint16 *sb = GET_B_LINE (y);
2325   const guint16 *sr = GET_R_LINE (y);
2326   guint16 *d = dest, G, B, R;
2327
2328   sg += x;
2329   sb += x;
2330   sr += x;
2331
2332   for (i = 0; i < width; i++) {
2333     G = GST_READ_UINT16_LE (sg + i) << 6;
2334     B = GST_READ_UINT16_LE (sb + i) << 6;
2335     R = GST_READ_UINT16_LE (sr + i) << 6;
2336
2337     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2338       R |= (R >> 10);
2339       G |= (G >> 10);
2340       B |= (B >> 10);
2341     }
2342
2343     d[i * 4 + 0] = 0xffff;
2344     d[i * 4 + 1] = R;
2345     d[i * 4 + 2] = G;
2346     d[i * 4 + 3] = B;
2347   }
2348 }
2349
2350 static void
2351 pack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2352     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2353     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2354     gint y, gint width)
2355 {
2356   int i;
2357   guint16 *restrict dg = GET_G_LINE (y);
2358   guint16 *restrict db = GET_B_LINE (y);
2359   guint16 *restrict dr = GET_R_LINE (y);
2360   guint16 G, B, R;
2361   const guint16 *restrict s = src;
2362
2363   for (i = 0; i < width; i++) {
2364     G = (s[i * 4 + 2]) >> 6;
2365     B = (s[i * 4 + 3]) >> 6;
2366     R = (s[i * 4 + 1]) >> 6;
2367
2368     GST_WRITE_UINT16_LE (dg + i, G);
2369     GST_WRITE_UINT16_LE (db + i, B);
2370     GST_WRITE_UINT16_LE (dr + i, R);
2371   }
2372 }
2373
2374 #define PACK_GBR_10BE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10BE, 1, pack_GBR_10BE
2375 static void
2376 unpack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2377     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2378     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2379 {
2380   int i;
2381   const guint16 *restrict sg = GET_G_LINE (y);
2382   const guint16 *restrict sb = GET_B_LINE (y);
2383   const guint16 *restrict sr = GET_R_LINE (y);
2384   guint16 *restrict d = dest, G, B, R;
2385
2386   sg += x;
2387   sb += x;
2388   sr += x;
2389
2390   for (i = 0; i < width; i++) {
2391     G = GST_READ_UINT16_BE (sg + i) << 6;
2392     B = GST_READ_UINT16_BE (sb + i) << 6;
2393     R = GST_READ_UINT16_BE (sr + i) << 6;
2394
2395     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2396       R |= (R >> 10);
2397       G |= (G >> 10);
2398       B |= (B >> 10);
2399     }
2400
2401     d[i * 4 + 0] = 0xffff;
2402     d[i * 4 + 1] = R;
2403     d[i * 4 + 2] = G;
2404     d[i * 4 + 3] = B;
2405   }
2406 }
2407
2408 static void
2409 pack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2410     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2411     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2412     gint y, gint width)
2413 {
2414   int i;
2415   guint16 *restrict dg = GET_G_LINE (y);
2416   guint16 *restrict db = GET_B_LINE (y);
2417   guint16 *restrict dr = GET_R_LINE (y);
2418   guint16 G, B, R;
2419   const guint16 *restrict s = src;
2420
2421   for (i = 0; i < width; i++) {
2422     G = s[i * 4 + 2] >> 6;
2423     B = s[i * 4 + 3] >> 6;
2424     R = s[i * 4 + 1] >> 6;
2425
2426     GST_WRITE_UINT16_BE (dg + i, G);
2427     GST_WRITE_UINT16_BE (db + i, B);
2428     GST_WRITE_UINT16_BE (dr + i, R);
2429   }
2430 }
2431
2432 #define PACK_GBRA_10LE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_10LE, 1, pack_GBRA_10LE
2433 static void
2434 unpack_GBRA_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2435     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2436     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2437 {
2438   int i;
2439   const guint16 *sg = GET_G_LINE (y);
2440   const guint16 *sb = GET_B_LINE (y);
2441   const guint16 *sr = GET_R_LINE (y);
2442   const guint16 *sa = GET_A_LINE (y);
2443   guint16 *d = dest, G, B, R, A;
2444
2445   sg += x;
2446   sb += x;
2447   sr += x;
2448   sa += x;
2449
2450   for (i = 0; i < width; i++) {
2451     G = GST_READ_UINT16_LE (sg + i) << 6;
2452     B = GST_READ_UINT16_LE (sb + i) << 6;
2453     R = GST_READ_UINT16_LE (sr + i) << 6;
2454     A = GST_READ_UINT16_LE (sa + i) << 6;
2455
2456     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2457       R |= (R >> 10);
2458       G |= (G >> 10);
2459       B |= (B >> 10);
2460       A |= (A >> 10);
2461     }
2462
2463     d[i * 4 + 0] = A;
2464     d[i * 4 + 1] = R;
2465     d[i * 4 + 2] = G;
2466     d[i * 4 + 3] = B;
2467   }
2468 }
2469
2470 static void
2471 pack_GBRA_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2472     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2473     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2474     gint y, gint width)
2475 {
2476   int i;
2477   guint16 *restrict dg = GET_G_LINE (y);
2478   guint16 *restrict db = GET_B_LINE (y);
2479   guint16 *restrict dr = GET_R_LINE (y);
2480   guint16 *restrict da = GET_A_LINE (y);
2481   guint16 G, B, R, A;
2482   const guint16 *restrict s = src;
2483
2484   for (i = 0; i < width; i++) {
2485     G = (s[i * 4 + 2]) >> 6;
2486     B = (s[i * 4 + 3]) >> 6;
2487     R = (s[i * 4 + 1]) >> 6;
2488     A = (s[i * 4 + 0]) >> 6;
2489
2490     GST_WRITE_UINT16_LE (dg + i, G);
2491     GST_WRITE_UINT16_LE (db + i, B);
2492     GST_WRITE_UINT16_LE (dr + i, R);
2493     GST_WRITE_UINT16_LE (da + i, A);
2494   }
2495 }
2496
2497 #define PACK_GBRA_10BE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_10BE, 1, pack_GBRA_10BE
2498 static void
2499 unpack_GBRA_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2500     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2501     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2502 {
2503   int i;
2504   const guint16 *restrict sg = GET_G_LINE (y);
2505   const guint16 *restrict sb = GET_B_LINE (y);
2506   const guint16 *restrict sr = GET_R_LINE (y);
2507   const guint16 *restrict sa = GET_A_LINE (y);
2508   guint16 *restrict d = dest, G, B, R, A;
2509
2510   sg += x;
2511   sb += x;
2512   sr += x;
2513   sa += x;
2514
2515   for (i = 0; i < width; i++) {
2516     G = GST_READ_UINT16_BE (sg + i) << 6;
2517     B = GST_READ_UINT16_BE (sb + i) << 6;
2518     R = GST_READ_UINT16_BE (sr + i) << 6;
2519     A = GST_READ_UINT16_BE (sa + i) << 6;
2520
2521     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2522       R |= (R >> 10);
2523       G |= (G >> 10);
2524       B |= (B >> 10);
2525       A |= (A >> 10);
2526     }
2527
2528     d[i * 4 + 0] = A;
2529     d[i * 4 + 1] = R;
2530     d[i * 4 + 2] = G;
2531     d[i * 4 + 3] = B;
2532   }
2533 }
2534
2535 static void
2536 pack_GBRA_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2537     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2538     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2539     gint y, gint width)
2540 {
2541   int i;
2542   guint16 *restrict dg = GET_G_LINE (y);
2543   guint16 *restrict db = GET_B_LINE (y);
2544   guint16 *restrict dr = GET_R_LINE (y);
2545   guint16 *restrict da = GET_A_LINE (y);
2546   guint16 G, B, R, A;
2547   const guint16 *restrict s = src;
2548
2549   for (i = 0; i < width; i++) {
2550     G = s[i * 4 + 2] >> 6;
2551     B = s[i * 4 + 3] >> 6;
2552     R = s[i * 4 + 1] >> 6;
2553     A = s[i * 4 + 0] >> 6;
2554
2555     GST_WRITE_UINT16_BE (dg + i, G);
2556     GST_WRITE_UINT16_BE (db + i, B);
2557     GST_WRITE_UINT16_BE (dr + i, R);
2558     GST_WRITE_UINT16_BE (da + i, A);
2559   }
2560 }
2561
2562 #define PACK_GBR_12LE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_12LE, 1, pack_GBR_12LE
2563 static void
2564 unpack_GBR_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2565     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2566     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2567 {
2568   int i;
2569   const guint16 *sg = GET_G_LINE (y);
2570   const guint16 *sb = GET_B_LINE (y);
2571   const guint16 *sr = GET_R_LINE (y);
2572   guint16 *d = dest, G, B, R;
2573
2574   sg += x;
2575   sb += x;
2576   sr += x;
2577
2578   for (i = 0; i < width; i++) {
2579     G = GST_READ_UINT16_LE (sg + i) << 4;
2580     B = GST_READ_UINT16_LE (sb + i) << 4;
2581     R = GST_READ_UINT16_LE (sr + i) << 4;
2582
2583     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2584       R |= (R >> 12);
2585       G |= (G >> 12);
2586       B |= (B >> 12);
2587     }
2588
2589     d[i * 4 + 0] = 0xffff;
2590     d[i * 4 + 1] = R;
2591     d[i * 4 + 2] = G;
2592     d[i * 4 + 3] = B;
2593   }
2594 }
2595
2596 static void
2597 pack_GBR_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2598     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2599     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2600     gint y, gint width)
2601 {
2602   int i;
2603   guint16 *restrict dg = GET_G_LINE (y);
2604   guint16 *restrict db = GET_B_LINE (y);
2605   guint16 *restrict dr = GET_R_LINE (y);
2606   guint16 G, B, R;
2607   const guint16 *restrict s = src;
2608
2609   for (i = 0; i < width; i++) {
2610     G = (s[i * 4 + 2]) >> 4;
2611     B = (s[i * 4 + 3]) >> 4;
2612     R = (s[i * 4 + 1]) >> 4;
2613
2614     GST_WRITE_UINT16_LE (dg + i, G);
2615     GST_WRITE_UINT16_LE (db + i, B);
2616     GST_WRITE_UINT16_LE (dr + i, R);
2617   }
2618 }
2619
2620 #define PACK_GBR_12BE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_12BE, 1, pack_GBR_12BE
2621 static void
2622 unpack_GBR_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2623     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2624     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2625 {
2626   int i;
2627   const guint16 *restrict sg = GET_G_LINE (y);
2628   const guint16 *restrict sb = GET_B_LINE (y);
2629   const guint16 *restrict sr = GET_R_LINE (y);
2630   guint16 *restrict d = dest, G, B, R;
2631
2632   sg += x;
2633   sb += x;
2634   sr += x;
2635
2636   for (i = 0; i < width; i++) {
2637     G = GST_READ_UINT16_BE (sg + i) << 4;
2638     B = GST_READ_UINT16_BE (sb + i) << 4;
2639     R = GST_READ_UINT16_BE (sr + i) << 4;
2640
2641     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2642       R |= (R >> 12);
2643       G |= (G >> 12);
2644       B |= (B >> 12);
2645     }
2646
2647     d[i * 4 + 0] = 0xffff;
2648     d[i * 4 + 1] = R;
2649     d[i * 4 + 2] = G;
2650     d[i * 4 + 3] = B;
2651   }
2652 }
2653
2654 static void
2655 pack_GBR_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2656     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2657     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2658     gint y, gint width)
2659 {
2660   int i;
2661   guint16 *restrict dg = GET_G_LINE (y);
2662   guint16 *restrict db = GET_B_LINE (y);
2663   guint16 *restrict dr = GET_R_LINE (y);
2664   guint16 G, B, R;
2665   const guint16 *restrict s = src;
2666
2667   for (i = 0; i < width; i++) {
2668     G = s[i * 4 + 2] >> 4;
2669     B = s[i * 4 + 3] >> 4;
2670     R = s[i * 4 + 1] >> 4;
2671
2672     GST_WRITE_UINT16_BE (dg + i, G);
2673     GST_WRITE_UINT16_BE (db + i, B);
2674     GST_WRITE_UINT16_BE (dr + i, R);
2675   }
2676 }
2677
2678 #define PACK_GBRA_12LE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_12LE, 1, pack_GBRA_12LE
2679 static void
2680 unpack_GBRA_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2681     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2682     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2683 {
2684   int i;
2685   const guint16 *sg = GET_G_LINE (y);
2686   const guint16 *sb = GET_B_LINE (y);
2687   const guint16 *sr = GET_R_LINE (y);
2688   const guint16 *sa = GET_A_LINE (y);
2689   guint16 *d = dest, G, B, R, A;
2690
2691   sg += x;
2692   sb += x;
2693   sr += x;
2694   sa += x;
2695
2696   for (i = 0; i < width; i++) {
2697     G = GST_READ_UINT16_LE (sg + i) << 4;
2698     B = GST_READ_UINT16_LE (sb + i) << 4;
2699     R = GST_READ_UINT16_LE (sr + i) << 4;
2700     A = GST_READ_UINT16_LE (sa + i) << 4;
2701
2702     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2703       A |= (A >> 12);
2704       R |= (R >> 12);
2705       G |= (G >> 12);
2706       B |= (B >> 12);
2707     }
2708
2709     d[i * 4 + 0] = A;
2710     d[i * 4 + 1] = R;
2711     d[i * 4 + 2] = G;
2712     d[i * 4 + 3] = B;
2713   }
2714 }
2715
2716 static void
2717 pack_GBRA_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2718     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2719     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2720     gint y, gint width)
2721 {
2722   int i;
2723   guint16 *restrict dg = GET_G_LINE (y);
2724   guint16 *restrict db = GET_B_LINE (y);
2725   guint16 *restrict dr = GET_R_LINE (y);
2726   guint16 *restrict da = GET_A_LINE (y);
2727   guint16 G, B, R, A;
2728   const guint16 *restrict s = src;
2729
2730   for (i = 0; i < width; i++) {
2731     G = (s[i * 4 + 2]) >> 4;
2732     B = (s[i * 4 + 3]) >> 4;
2733     R = (s[i * 4 + 1]) >> 4;
2734     A = (s[i * 4 + 0]) >> 4;
2735
2736     GST_WRITE_UINT16_LE (dg + i, G);
2737     GST_WRITE_UINT16_LE (db + i, B);
2738     GST_WRITE_UINT16_LE (dr + i, R);
2739     GST_WRITE_UINT16_LE (da + i, A);
2740   }
2741 }
2742
2743 #define PACK_GBRA_12BE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_12BE, 1, pack_GBRA_12BE
2744 static void
2745 unpack_GBRA_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2746     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2747     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2748 {
2749   int i;
2750   const guint16 *restrict sg = GET_G_LINE (y);
2751   const guint16 *restrict sb = GET_B_LINE (y);
2752   const guint16 *restrict sr = GET_R_LINE (y);
2753   const guint16 *restrict sa = GET_A_LINE (y);
2754   guint16 *restrict d = dest, G, B, R, A;
2755
2756   sg += x;
2757   sb += x;
2758   sr += x;
2759   sa += x;
2760
2761   for (i = 0; i < width; i++) {
2762     G = GST_READ_UINT16_BE (sg + i) << 4;
2763     B = GST_READ_UINT16_BE (sb + i) << 4;
2764     R = GST_READ_UINT16_BE (sr + i) << 4;
2765     A = GST_READ_UINT16_BE (sa + i) << 4;
2766
2767     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2768       R |= (R >> 12);
2769       G |= (G >> 12);
2770       B |= (B >> 12);
2771       A |= (A >> 12);
2772     }
2773
2774     d[i * 4 + 0] = A;
2775     d[i * 4 + 1] = R;
2776     d[i * 4 + 2] = G;
2777     d[i * 4 + 3] = B;
2778   }
2779 }
2780
2781 static void
2782 pack_GBRA_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2783     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2784     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2785     gint y, gint width)
2786 {
2787   int i;
2788   guint16 *restrict dg = GET_G_LINE (y);
2789   guint16 *restrict db = GET_B_LINE (y);
2790   guint16 *restrict dr = GET_R_LINE (y);
2791   guint16 *restrict da = GET_A_LINE (y);
2792   guint16 G, B, R, A;
2793   const guint16 *restrict s = src;
2794
2795   for (i = 0; i < width; i++) {
2796     G = s[i * 4 + 2] >> 4;
2797     B = s[i * 4 + 3] >> 4;
2798     R = s[i * 4 + 1] >> 4;
2799     A = s[i * 4 + 0] >> 4;
2800
2801     GST_WRITE_UINT16_BE (dg + i, G);
2802     GST_WRITE_UINT16_BE (db + i, B);
2803     GST_WRITE_UINT16_BE (dr + i, R);
2804     GST_WRITE_UINT16_BE (da + i, A);
2805   }
2806 }
2807
2808 #define PACK_Y444_10LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10LE, 1, pack_Y444_10LE
2809 static void
2810 unpack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2811     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2812     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2813 {
2814   int i;
2815   guint16 *restrict sy = GET_Y_LINE (y);
2816   guint16 *restrict su = GET_U_LINE (y);
2817   guint16 *restrict sv = GET_V_LINE (y);
2818   guint16 *restrict d = dest, Y, U, V;
2819
2820   sy += x;
2821   su += x;
2822   sv += x;
2823
2824   for (i = 0; i < width; i++) {
2825     Y = GST_READ_UINT16_LE (sy + i) << 6;
2826     U = GST_READ_UINT16_LE (su + i) << 6;
2827     V = GST_READ_UINT16_LE (sv + i) << 6;
2828
2829     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2830       Y |= (Y >> 10);
2831       U |= (U >> 10);
2832       V |= (V >> 10);
2833     }
2834
2835     d[i * 4 + 0] = 0xffff;
2836     d[i * 4 + 1] = Y;
2837     d[i * 4 + 2] = U;
2838     d[i * 4 + 3] = V;
2839   }
2840 }
2841
2842 static void
2843 pack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2844     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2845     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2846     gint y, gint width)
2847 {
2848   int i;
2849   guint16 *restrict dy = GET_Y_LINE (y);
2850   guint16 *restrict du = GET_U_LINE (y);
2851   guint16 *restrict dv = GET_V_LINE (y);
2852   guint16 Y, U, V;
2853   const guint16 *restrict s = src;
2854
2855   for (i = 0; i < width; i++) {
2856     Y = (s[i * 4 + 1]) >> 6;
2857     U = (s[i * 4 + 2]) >> 6;
2858     V = (s[i * 4 + 3]) >> 6;
2859
2860     GST_WRITE_UINT16_LE (dy + i, Y);
2861     GST_WRITE_UINT16_LE (du + i, U);
2862     GST_WRITE_UINT16_LE (dv + i, V);
2863   }
2864 }
2865
2866 #define PACK_Y444_10BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10BE, 1, pack_Y444_10BE
2867 static void
2868 unpack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2869     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2870     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2871 {
2872   int i;
2873   const guint16 *restrict sy = GET_Y_LINE (y);
2874   const guint16 *restrict su = GET_U_LINE (y);
2875   const guint16 *restrict sv = GET_V_LINE (y);
2876   guint16 *restrict d = dest, Y, U, V;
2877
2878   sy += x;
2879   su += x;
2880   sv += x;
2881
2882   for (i = 0; i < width; i++) {
2883     Y = GST_READ_UINT16_BE (sy + i) << 6;
2884     U = GST_READ_UINT16_BE (su + i) << 6;
2885     V = GST_READ_UINT16_BE (sv + i) << 6;
2886
2887     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2888       Y |= (Y >> 10);
2889       U |= (U >> 10);
2890       V |= (V >> 10);
2891     }
2892
2893     d[i * 4 + 0] = 0xffff;
2894     d[i * 4 + 1] = Y;
2895     d[i * 4 + 2] = U;
2896     d[i * 4 + 3] = V;
2897   }
2898 }
2899
2900 static void
2901 pack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2902     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2903     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2904     gint y, gint width)
2905 {
2906   int i;
2907   guint16 *restrict dy = GET_Y_LINE (y);
2908   guint16 *restrict du = GET_U_LINE (y);
2909   guint16 *restrict dv = GET_V_LINE (y);
2910   guint16 Y, U, V;
2911   const guint16 *restrict s = src;
2912
2913   for (i = 0; i < width; i++) {
2914     Y = s[i * 4 + 1] >> 6;
2915     U = s[i * 4 + 2] >> 6;
2916     V = s[i * 4 + 3] >> 6;
2917
2918     GST_WRITE_UINT16_BE (dy + i, Y);
2919     GST_WRITE_UINT16_BE (du + i, U);
2920     GST_WRITE_UINT16_BE (dv + i, V);
2921   }
2922 }
2923
2924 #define PACK_I420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10LE, 1, pack_I420_10LE
2925 static void
2926 unpack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2927     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2928     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2929 {
2930   int i;
2931   gint uv = GET_UV_420 (y, flags);
2932   const guint16 *restrict sy = GET_Y_LINE (y);
2933   const guint16 *restrict su = GET_U_LINE (uv);
2934   const guint16 *restrict sv = GET_V_LINE (uv);
2935   guint16 *restrict d = dest, Y, U, V;
2936
2937   sy += x;
2938   su += x >> 1;
2939   sv += x >> 1;
2940
2941   for (i = 0; i < width; i++) {
2942     Y = GST_READ_UINT16_LE (sy + i) << 6;
2943     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
2944     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
2945
2946     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2947       Y |= (Y >> 10);
2948       U |= (U >> 10);
2949       V |= (V >> 10);
2950     }
2951
2952     d[i * 4 + 0] = 0xffff;
2953     d[i * 4 + 1] = Y;
2954     d[i * 4 + 2] = U;
2955     d[i * 4 + 3] = V;
2956
2957     if (x & 1) {
2958       x = 0;
2959       su++;
2960       sv++;
2961     }
2962   }
2963 }
2964
2965 static void
2966 pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2967     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2968     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2969     gint y, gint width)
2970 {
2971   int i;
2972   gint uv = GET_UV_420 (y, flags);
2973   guint16 *restrict dy = GET_Y_LINE (y);
2974   guint16 *restrict du = GET_U_LINE (uv);
2975   guint16 *restrict dv = GET_V_LINE (uv);
2976   guint16 Y0, Y1, U, V;
2977   const guint16 *restrict s = src;
2978
2979   if (IS_CHROMA_LINE_420 (y, flags)) {
2980     for (i = 0; i < width - 1; i += 2) {
2981       Y0 = s[i * 4 + 1] >> 6;
2982       Y1 = s[i * 4 + 5] >> 6;
2983       U = s[i * 4 + 2] >> 6;
2984       V = s[i * 4 + 3] >> 6;
2985
2986       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
2987       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
2988       GST_WRITE_UINT16_LE (du + (i >> 1), U);
2989       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
2990     }
2991     if (i == width - 1) {
2992       Y0 = s[i * 4 + 1] >> 6;
2993       U = s[i * 4 + 2] >> 6;
2994       V = s[i * 4 + 3] >> 6;
2995
2996       GST_WRITE_UINT16_LE (dy + i, Y0);
2997       GST_WRITE_UINT16_LE (du + (i >> 1), U);
2998       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
2999     }
3000   } else {
3001     for (i = 0; i < width; i++) {
3002       Y0 = s[i * 4 + 1] >> 6;
3003       GST_WRITE_UINT16_LE (dy + i, Y0);
3004     }
3005   }
3006 }
3007
3008 #define PACK_I420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10BE, 1, pack_I420_10BE
3009 static void
3010 unpack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3011     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3012     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3013 {
3014   int i;
3015   gint uv = GET_UV_420 (y, flags);
3016   const guint16 *restrict sy = GET_Y_LINE (y);
3017   const guint16 *restrict su = GET_U_LINE (uv);
3018   const guint16 *restrict sv = GET_V_LINE (uv);
3019   guint16 *restrict d = dest, Y, U, V;
3020
3021   sy += x;
3022   su += x >> 1;
3023   sv += x >> 1;
3024
3025   for (i = 0; i < width; i++) {
3026     Y = GST_READ_UINT16_BE (sy + i) << 6;
3027     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3028     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3029
3030     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3031       Y |= (Y >> 10);
3032       U |= (U >> 10);
3033       V |= (V >> 10);
3034     }
3035
3036     d[i * 4 + 0] = 0xffff;
3037     d[i * 4 + 1] = Y;
3038     d[i * 4 + 2] = U;
3039     d[i * 4 + 3] = V;
3040
3041     if (x & 1) {
3042       x = 0;
3043       su++;
3044       sv++;
3045     }
3046   }
3047 }
3048
3049 static void
3050 pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3051     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3052     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3053     gint y, gint width)
3054 {
3055   int i;
3056   gint uv = GET_UV_420 (y, flags);
3057   guint16 *restrict dy = GET_Y_LINE (y);
3058   guint16 *restrict du = GET_U_LINE (uv);
3059   guint16 *restrict dv = GET_V_LINE (uv);
3060   guint16 Y0, Y1, U, V;
3061   const guint16 *restrict s = src;
3062
3063   if (IS_CHROMA_LINE_420 (y, flags)) {
3064     for (i = 0; i < width - 1; i += 2) {
3065       Y0 = s[i * 4 + 1] >> 6;
3066       Y1 = s[i * 4 + 5] >> 6;
3067       U = s[i * 4 + 2] >> 6;
3068       V = s[i * 4 + 3] >> 6;
3069
3070       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3071       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3072       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3073       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3074     }
3075     if (i == width - 1) {
3076       Y0 = s[i * 4 + 1] >> 6;
3077       U = s[i * 4 + 2] >> 6;
3078       V = s[i * 4 + 3] >> 6;
3079
3080       GST_WRITE_UINT16_BE (dy + i, Y0);
3081       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3082       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3083     }
3084   } else {
3085     for (i = 0; i < width; i++) {
3086       Y0 = s[i * 4 + 1] >> 6;
3087       GST_WRITE_UINT16_BE (dy + i, Y0);
3088     }
3089   }
3090 }
3091
3092 #define PACK_I422_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10LE, 1, pack_I422_10LE
3093 static void
3094 unpack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3095     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3096     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3097 {
3098   int i;
3099   const guint16 *restrict sy = GET_Y_LINE (y);
3100   const guint16 *restrict su = GET_U_LINE (y);
3101   const guint16 *restrict sv = GET_V_LINE (y);
3102   guint16 *restrict d = dest, Y, U, V;
3103
3104   sy += x;
3105   su += x >> 1;
3106   sv += x >> 1;
3107
3108   for (i = 0; i < width; i++) {
3109     Y = GST_READ_UINT16_LE (sy + i) << 6;
3110     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
3111     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
3112
3113     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3114       Y |= (Y >> 10);
3115       U |= (U >> 10);
3116       V |= (V >> 10);
3117     }
3118
3119     d[i * 4 + 0] = 0xffff;
3120     d[i * 4 + 1] = Y;
3121     d[i * 4 + 2] = U;
3122     d[i * 4 + 3] = V;
3123
3124     if (x & 1) {
3125       x = 0;
3126       su++;
3127       sv++;
3128     }
3129   }
3130 }
3131
3132 static void
3133 pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3134     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3135     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3136     gint y, gint width)
3137 {
3138   int i;
3139   guint16 *restrict dy = GET_Y_LINE (y);
3140   guint16 *restrict du = GET_U_LINE (y);
3141   guint16 *restrict dv = GET_V_LINE (y);
3142   guint16 Y0, Y1, U, V;
3143   const guint16 *restrict s = src;
3144
3145   for (i = 0; i < width - 1; i += 2) {
3146     Y0 = s[i * 4 + 1] >> 6;
3147     Y1 = s[i * 4 + 5] >> 6;
3148     U = s[i * 4 + 2] >> 6;
3149     V = s[i * 4 + 3] >> 6;
3150
3151     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3152     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3153     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3154     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3155   }
3156   if (i == width - 1) {
3157     Y0 = s[i * 4 + 1] >> 6;
3158     U = s[i * 4 + 2] >> 6;
3159     V = s[i * 4 + 3] >> 6;
3160
3161     GST_WRITE_UINT16_LE (dy + i, Y0);
3162     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3163     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3164   }
3165 }
3166
3167 #define PACK_I422_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10BE, 1, pack_I422_10BE
3168 static void
3169 unpack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3170     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3171     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3172 {
3173   int i;
3174   const guint16 *restrict sy = GET_Y_LINE (y);
3175   const guint16 *restrict su = GET_U_LINE (y);
3176   const guint16 *restrict sv = GET_V_LINE (y);
3177   guint16 *restrict d = dest, Y, U, V;
3178
3179   sy += x;
3180   su += x >> 1;
3181   sv += x >> 1;
3182
3183   for (i = 0; i < width; i++) {
3184     Y = GST_READ_UINT16_BE (sy + i) << 6;
3185     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3186     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3187
3188     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3189       Y |= (Y >> 10);
3190       U |= (U >> 10);
3191       V |= (V >> 10);
3192     }
3193
3194     d[i * 4 + 0] = 0xffff;
3195     d[i * 4 + 1] = Y;
3196     d[i * 4 + 2] = U;
3197     d[i * 4 + 3] = V;
3198
3199     if (x & 1) {
3200       x = 0;
3201       su++;
3202       sv++;
3203     }
3204   }
3205 }
3206
3207 static void
3208 pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3209     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3210     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3211     gint y, gint width)
3212 {
3213   int i;
3214   guint16 *restrict dy = GET_Y_LINE (y);
3215   guint16 *restrict du = GET_U_LINE (y);
3216   guint16 *restrict dv = GET_V_LINE (y);
3217   guint16 Y0, Y1, U, V;
3218   const guint16 *restrict s = src;
3219
3220   for (i = 0; i < width - 1; i += 2) {
3221     Y0 = s[i * 4 + 1] >> 6;
3222     Y1 = s[i * 4 + 5] >> 6;
3223     U = s[i * 4 + 2] >> 6;
3224     V = s[i * 4 + 3] >> 6;
3225
3226     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3227     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3228     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3229     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3230   }
3231   if (i == width - 1) {
3232     Y0 = s[i * 4 + 1] >> 6;
3233     U = s[i * 4 + 2] >> 6;
3234     V = s[i * 4 + 3] >> 6;
3235
3236     GST_WRITE_UINT16_BE (dy + i, Y0);
3237     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3238     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3239   }
3240 }
3241
3242 #define PACK_Y444_12LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_12LE, 1, pack_Y444_12LE
3243 static void
3244 unpack_Y444_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3245     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3246     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3247 {
3248   int i;
3249   guint16 *restrict sy = GET_Y_LINE (y);
3250   guint16 *restrict su = GET_U_LINE (y);
3251   guint16 *restrict sv = GET_V_LINE (y);
3252   guint16 *restrict d = dest, Y, U, V;
3253
3254   sy += x;
3255   su += x;
3256   sv += x;
3257
3258   for (i = 0; i < width; i++) {
3259     Y = GST_READ_UINT16_LE (sy + i) << 4;
3260     U = GST_READ_UINT16_LE (su + i) << 4;
3261     V = GST_READ_UINT16_LE (sv + i) << 4;
3262
3263     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3264       Y |= (Y >> 12);
3265       U |= (U >> 12);
3266       V |= (V >> 12);
3267     }
3268
3269     d[i * 4 + 0] = 0xffff;
3270     d[i * 4 + 1] = Y;
3271     d[i * 4 + 2] = U;
3272     d[i * 4 + 3] = V;
3273   }
3274 }
3275
3276 static void
3277 pack_Y444_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3278     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3279     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3280     gint y, gint width)
3281 {
3282   int i;
3283   guint16 *restrict dy = GET_Y_LINE (y);
3284   guint16 *restrict du = GET_U_LINE (y);
3285   guint16 *restrict dv = GET_V_LINE (y);
3286   guint16 Y, U, V;
3287   const guint16 *restrict s = src;
3288
3289   for (i = 0; i < width; i++) {
3290     Y = (s[i * 4 + 1]) >> 4;
3291     U = (s[i * 4 + 2]) >> 4;
3292     V = (s[i * 4 + 3]) >> 4;
3293
3294     GST_WRITE_UINT16_LE (dy + i, Y);
3295     GST_WRITE_UINT16_LE (du + i, U);
3296     GST_WRITE_UINT16_LE (dv + i, V);
3297   }
3298 }
3299
3300 #define PACK_Y444_12BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_12BE, 1, pack_Y444_12BE
3301 static void
3302 unpack_Y444_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3303     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3304     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3305 {
3306   int i;
3307   const guint16 *restrict sy = GET_Y_LINE (y);
3308   const guint16 *restrict su = GET_U_LINE (y);
3309   const guint16 *restrict sv = GET_V_LINE (y);
3310   guint16 *restrict d = dest, Y, U, V;
3311
3312   sy += x;
3313   su += x;
3314   sv += x;
3315
3316   for (i = 0; i < width; i++) {
3317     Y = GST_READ_UINT16_BE (sy + i) << 4;
3318     U = GST_READ_UINT16_BE (su + i) << 4;
3319     V = GST_READ_UINT16_BE (sv + i) << 4;
3320
3321     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3322       Y |= (Y >> 12);
3323       U |= (U >> 12);
3324       V |= (V >> 12);
3325     }
3326
3327     d[i * 4 + 0] = 0xffff;
3328     d[i * 4 + 1] = Y;
3329     d[i * 4 + 2] = U;
3330     d[i * 4 + 3] = V;
3331   }
3332 }
3333
3334 static void
3335 pack_Y444_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3336     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3337     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3338     gint y, gint width)
3339 {
3340   int i;
3341   guint16 *restrict dy = GET_Y_LINE (y);
3342   guint16 *restrict du = GET_U_LINE (y);
3343   guint16 *restrict dv = GET_V_LINE (y);
3344   guint16 Y, U, V;
3345   const guint16 *restrict s = src;
3346
3347   for (i = 0; i < width; i++) {
3348     Y = s[i * 4 + 1] >> 4;
3349     U = s[i * 4 + 2] >> 4;
3350     V = s[i * 4 + 3] >> 4;
3351
3352     GST_WRITE_UINT16_BE (dy + i, Y);
3353     GST_WRITE_UINT16_BE (du + i, U);
3354     GST_WRITE_UINT16_BE (dv + i, V);
3355   }
3356 }
3357
3358 #define PACK_I420_12LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_12LE, 1, pack_I420_12LE
3359 static void
3360 unpack_I420_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3361     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3362     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3363 {
3364   int i;
3365   gint uv = GET_UV_420 (y, flags);
3366   const guint16 *restrict sy = GET_Y_LINE (y);
3367   const guint16 *restrict su = GET_U_LINE (uv);
3368   const guint16 *restrict sv = GET_V_LINE (uv);
3369   guint16 *restrict d = dest, Y, U, V;
3370
3371   sy += x;
3372   su += x >> 1;
3373   sv += x >> 1;
3374
3375   for (i = 0; i < width; i++) {
3376     Y = GST_READ_UINT16_LE (sy + i) << 4;
3377     U = GST_READ_UINT16_LE (su + (i >> 1)) << 4;
3378     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 4;
3379
3380     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3381       Y |= (Y >> 12);
3382       U |= (U >> 12);
3383       V |= (V >> 12);
3384     }
3385
3386     d[i * 4 + 0] = 0xffff;
3387     d[i * 4 + 1] = Y;
3388     d[i * 4 + 2] = U;
3389     d[i * 4 + 3] = V;
3390
3391     if (x & 1) {
3392       x = 0;
3393       su++;
3394       sv++;
3395     }
3396   }
3397 }
3398
3399 static void
3400 pack_I420_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3401     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3402     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3403     gint y, gint width)
3404 {
3405   int i;
3406   gint uv = GET_UV_420 (y, flags);
3407   guint16 *restrict dy = GET_Y_LINE (y);
3408   guint16 *restrict du = GET_U_LINE (uv);
3409   guint16 *restrict dv = GET_V_LINE (uv);
3410   guint16 Y0, Y1, U, V;
3411   const guint16 *restrict s = src;
3412
3413   if (IS_CHROMA_LINE_420 (y, flags)) {
3414     for (i = 0; i < width - 1; i += 2) {
3415       Y0 = s[i * 4 + 1] >> 4;
3416       Y1 = s[i * 4 + 5] >> 4;
3417       U = s[i * 4 + 2] >> 4;
3418       V = s[i * 4 + 3] >> 4;
3419
3420       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3421       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3422       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3423       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3424     }
3425     if (i == width - 1) {
3426       Y0 = s[i * 4 + 1] >> 4;
3427       U = s[i * 4 + 2] >> 4;
3428       V = s[i * 4 + 3] >> 4;
3429
3430       GST_WRITE_UINT16_LE (dy + i, Y0);
3431       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3432       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3433     }
3434   } else {
3435     for (i = 0; i < width; i++) {
3436       Y0 = s[i * 4 + 1] >> 4;
3437       GST_WRITE_UINT16_LE (dy + i, Y0);
3438     }
3439   }
3440 }
3441
3442 #define PACK_I420_12BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_12BE, 1, pack_I420_12BE
3443 static void
3444 unpack_I420_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3445     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3446     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3447 {
3448   int i;
3449   gint uv = GET_UV_420 (y, flags);
3450   const guint16 *restrict sy = GET_Y_LINE (y);
3451   const guint16 *restrict su = GET_U_LINE (uv);
3452   const guint16 *restrict sv = GET_V_LINE (uv);
3453   guint16 *restrict d = dest, Y, U, V;
3454
3455   sy += x;
3456   su += x >> 1;
3457   sv += x >> 1;
3458
3459   for (i = 0; i < width; i++) {
3460     Y = GST_READ_UINT16_BE (sy + i) << 4;
3461     U = GST_READ_UINT16_BE (su + (i >> 1)) << 4;
3462     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 4;
3463
3464     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3465       Y |= (Y >> 12);
3466       U |= (U >> 12);
3467       V |= (V >> 12);
3468     }
3469
3470     d[i * 4 + 0] = 0xffff;
3471     d[i * 4 + 1] = Y;
3472     d[i * 4 + 2] = U;
3473     d[i * 4 + 3] = V;
3474
3475     if (x & 1) {
3476       x = 0;
3477       su++;
3478       sv++;
3479     }
3480   }
3481 }
3482
3483 static void
3484 pack_I420_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3485     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3486     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3487     gint y, gint width)
3488 {
3489   int i;
3490   gint uv = GET_UV_420 (y, flags);
3491   guint16 *restrict dy = GET_Y_LINE (y);
3492   guint16 *restrict du = GET_U_LINE (uv);
3493   guint16 *restrict dv = GET_V_LINE (uv);
3494   guint16 Y0, Y1, U, V;
3495   const guint16 *restrict s = src;
3496
3497   if (IS_CHROMA_LINE_420 (y, flags)) {
3498     for (i = 0; i < width - 1; i += 2) {
3499       Y0 = s[i * 4 + 1] >> 4;
3500       Y1 = s[i * 4 + 5] >> 4;
3501       U = s[i * 4 + 2] >> 4;
3502       V = s[i * 4 + 3] >> 4;
3503
3504       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3505       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3506       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3507       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3508     }
3509     if (i == width - 1) {
3510       Y0 = s[i * 4 + 1] >> 4;
3511       U = s[i * 4 + 2] >> 4;
3512       V = s[i * 4 + 3] >> 4;
3513
3514       GST_WRITE_UINT16_BE (dy + i, Y0);
3515       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3516       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3517     }
3518   } else {
3519     for (i = 0; i < width; i++) {
3520       Y0 = s[i * 4 + 1] >> 4;
3521       GST_WRITE_UINT16_BE (dy + i, Y0);
3522     }
3523   }
3524 }
3525
3526 #define PACK_I422_12LE GST_VIDEO_FORMAT_AYUV64, unpack_I422_12LE, 1, pack_I422_12LE
3527 static void
3528 unpack_I422_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3529     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3530     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3531 {
3532   int i;
3533   const guint16 *restrict sy = GET_Y_LINE (y);
3534   const guint16 *restrict su = GET_U_LINE (y);
3535   const guint16 *restrict sv = GET_V_LINE (y);
3536   guint16 *restrict d = dest, Y, U, V;
3537
3538   sy += x;
3539   su += x >> 1;
3540   sv += x >> 1;
3541
3542   for (i = 0; i < width; i++) {
3543     Y = GST_READ_UINT16_LE (sy + i) << 4;
3544     U = GST_READ_UINT16_LE (su + (i >> 1)) << 4;
3545     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 4;
3546
3547     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3548       Y |= (Y >> 12);
3549       U |= (U >> 12);
3550       V |= (V >> 12);
3551     }
3552
3553     d[i * 4 + 0] = 0xffff;
3554     d[i * 4 + 1] = Y;
3555     d[i * 4 + 2] = U;
3556     d[i * 4 + 3] = V;
3557
3558     if (x & 1) {
3559       x = 0;
3560       su++;
3561       sv++;
3562     }
3563   }
3564 }
3565
3566 static void
3567 pack_I422_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3568     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3569     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3570     gint y, gint width)
3571 {
3572   int i;
3573   guint16 *restrict dy = GET_Y_LINE (y);
3574   guint16 *restrict du = GET_U_LINE (y);
3575   guint16 *restrict dv = GET_V_LINE (y);
3576   guint16 Y0, Y1, U, V;
3577   const guint16 *restrict s = src;
3578
3579   for (i = 0; i < width - 1; i += 2) {
3580     Y0 = s[i * 4 + 1] >> 4;
3581     Y1 = s[i * 4 + 5] >> 4;
3582     U = s[i * 4 + 2] >> 4;
3583     V = s[i * 4 + 3] >> 4;
3584
3585     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3586     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3587     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3588     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3589   }
3590   if (i == width - 1) {
3591     Y0 = s[i * 4 + 1] >> 4;
3592     U = s[i * 4 + 2] >> 4;
3593     V = s[i * 4 + 3] >> 4;
3594
3595     GST_WRITE_UINT16_LE (dy + i, Y0);
3596     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3597     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3598   }
3599 }
3600
3601 #define PACK_I422_12BE GST_VIDEO_FORMAT_AYUV64, unpack_I422_12BE, 1, pack_I422_12BE
3602 static void
3603 unpack_I422_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3604     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3605     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3606 {
3607   int i;
3608   const guint16 *restrict sy = GET_Y_LINE (y);
3609   const guint16 *restrict su = GET_U_LINE (y);
3610   const guint16 *restrict sv = GET_V_LINE (y);
3611   guint16 *restrict d = dest, Y, U, V;
3612
3613   sy += x;
3614   su += x >> 1;
3615   sv += x >> 1;
3616
3617   for (i = 0; i < width; i++) {
3618     Y = GST_READ_UINT16_BE (sy + i) << 4;
3619     U = GST_READ_UINT16_BE (su + (i >> 1)) << 4;
3620     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 4;
3621
3622     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3623       Y |= (Y >> 12);
3624       U |= (U >> 12);
3625       V |= (V >> 12);
3626     }
3627
3628     d[i * 4 + 0] = 0xffff;
3629     d[i * 4 + 1] = Y;
3630     d[i * 4 + 2] = U;
3631     d[i * 4 + 3] = V;
3632
3633     if (x & 1) {
3634       x = 0;
3635       su++;
3636       sv++;
3637     }
3638   }
3639 }
3640
3641 static void
3642 pack_I422_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3643     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3644     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3645     gint y, gint width)
3646 {
3647   int i;
3648   guint16 *restrict dy = GET_Y_LINE (y);
3649   guint16 *restrict du = GET_U_LINE (y);
3650   guint16 *restrict dv = GET_V_LINE (y);
3651   guint16 Y0, Y1, U, V;
3652   const guint16 *restrict s = src;
3653
3654   for (i = 0; i < width - 1; i += 2) {
3655     Y0 = s[i * 4 + 1] >> 4;
3656     Y1 = s[i * 4 + 5] >> 4;
3657     U = s[i * 4 + 2] >> 4;
3658     V = s[i * 4 + 3] >> 4;
3659
3660     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3661     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3662     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3663     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3664   }
3665   if (i == width - 1) {
3666     Y0 = s[i * 4 + 1] >> 4;
3667     U = s[i * 4 + 2] >> 4;
3668     V = s[i * 4 + 3] >> 4;
3669
3670     GST_WRITE_UINT16_BE (dy + i, Y0);
3671     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3672     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3673   }
3674 }
3675
3676 #define PACK_A444_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A444_10LE, 1, pack_A444_10LE
3677 static void
3678 unpack_A444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3679     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3680     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3681 {
3682   int i;
3683   guint16 *restrict sa = GET_A_LINE (y);
3684   guint16 *restrict sy = GET_Y_LINE (y);
3685   guint16 *restrict su = GET_U_LINE (y);
3686   guint16 *restrict sv = GET_V_LINE (y);
3687   guint16 *restrict d = dest, A, Y, U, V;
3688
3689   sa += x;
3690   sy += x;
3691   su += x;
3692   sv += x;
3693
3694   for (i = 0; i < width; i++) {
3695     A = GST_READ_UINT16_LE (sa + i) << 6;
3696     Y = GST_READ_UINT16_LE (sy + i) << 6;
3697     U = GST_READ_UINT16_LE (su + i) << 6;
3698     V = GST_READ_UINT16_LE (sv + i) << 6;
3699
3700     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3701       A |= (A >> 10);
3702       Y |= (Y >> 10);
3703       U |= (U >> 10);
3704       V |= (V >> 10);
3705     }
3706
3707     d[i * 4 + 0] = A;
3708     d[i * 4 + 1] = Y;
3709     d[i * 4 + 2] = U;
3710     d[i * 4 + 3] = V;
3711   }
3712 }
3713
3714 static void
3715 pack_A444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3716     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3717     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3718     gint y, gint width)
3719 {
3720   int i;
3721   guint16 *restrict da = GET_A_LINE (y);
3722   guint16 *restrict dy = GET_Y_LINE (y);
3723   guint16 *restrict du = GET_U_LINE (y);
3724   guint16 *restrict dv = GET_V_LINE (y);
3725   guint16 A, Y, U, V;
3726   const guint16 *restrict s = src;
3727
3728   for (i = 0; i < width; i++) {
3729     A = (s[i * 4 + 0]) >> 6;
3730     Y = (s[i * 4 + 1]) >> 6;
3731     U = (s[i * 4 + 2]) >> 6;
3732     V = (s[i * 4 + 3]) >> 6;
3733
3734     GST_WRITE_UINT16_LE (da + i, A);
3735     GST_WRITE_UINT16_LE (dy + i, Y);
3736     GST_WRITE_UINT16_LE (du + i, U);
3737     GST_WRITE_UINT16_LE (dv + i, V);
3738   }
3739 }
3740
3741 #define PACK_A444_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A444_10BE, 1, pack_A444_10BE
3742 static void
3743 unpack_A444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3744     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3745     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3746 {
3747   int i;
3748   const guint16 *restrict sa = GET_A_LINE (y);
3749   const guint16 *restrict sy = GET_Y_LINE (y);
3750   const guint16 *restrict su = GET_U_LINE (y);
3751   const guint16 *restrict sv = GET_V_LINE (y);
3752   guint16 *restrict d = dest, A, Y, U, V;
3753
3754   sa += x;
3755   sy += x;
3756   su += x;
3757   sv += x;
3758
3759   for (i = 0; i < width; i++) {
3760     A = GST_READ_UINT16_BE (sa + i) << 6;
3761     Y = GST_READ_UINT16_BE (sy + i) << 6;
3762     U = GST_READ_UINT16_BE (su + i) << 6;
3763     V = GST_READ_UINT16_BE (sv + i) << 6;
3764
3765     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3766       A |= (A >> 10);
3767       Y |= (Y >> 10);
3768       U |= (U >> 10);
3769       V |= (V >> 10);
3770     }
3771
3772     d[i * 4 + 0] = A;
3773     d[i * 4 + 1] = Y;
3774     d[i * 4 + 2] = U;
3775     d[i * 4 + 3] = V;
3776   }
3777 }
3778
3779 static void
3780 pack_A444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3781     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3782     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3783     gint y, gint width)
3784 {
3785   int i;
3786   guint16 *restrict da = GET_A_LINE (y);
3787   guint16 *restrict dy = GET_Y_LINE (y);
3788   guint16 *restrict du = GET_U_LINE (y);
3789   guint16 *restrict dv = GET_V_LINE (y);
3790   guint16 A, Y, U, V;
3791   const guint16 *restrict s = src;
3792
3793   for (i = 0; i < width; i++) {
3794     A = s[i * 4 + 0] >> 6;
3795     Y = s[i * 4 + 1] >> 6;
3796     U = s[i * 4 + 2] >> 6;
3797     V = s[i * 4 + 3] >> 6;
3798
3799     GST_WRITE_UINT16_BE (da + i, A);
3800     GST_WRITE_UINT16_BE (dy + i, Y);
3801     GST_WRITE_UINT16_BE (du + i, U);
3802     GST_WRITE_UINT16_BE (dv + i, V);
3803   }
3804 }
3805
3806 #define PACK_A420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A420_10LE, 1, pack_A420_10LE
3807 static void
3808 unpack_A420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3809     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3810     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3811 {
3812   int i;
3813   gint uv = GET_UV_420 (y, flags);
3814   const guint16 *restrict sa = GET_A_LINE (y);
3815   const guint16 *restrict sy = GET_Y_LINE (y);
3816   const guint16 *restrict su = GET_U_LINE (uv);
3817   const guint16 *restrict sv = GET_V_LINE (uv);
3818   guint16 *restrict d = dest, A, Y, U, V;
3819
3820   sa += x;
3821   sy += x;
3822   su += x >> 1;
3823   sv += x >> 1;
3824
3825   for (i = 0; i < width; i++) {
3826     A = GST_READ_UINT16_LE (sa + i) << 6;
3827     Y = GST_READ_UINT16_LE (sy + i) << 6;
3828     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
3829     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
3830
3831     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3832       A |= (A >> 10);
3833       Y |= (Y >> 10);
3834       U |= (U >> 10);
3835       V |= (V >> 10);
3836     }
3837
3838     d[i * 4 + 0] = A;
3839     d[i * 4 + 1] = Y;
3840     d[i * 4 + 2] = U;
3841     d[i * 4 + 3] = V;
3842
3843     if (x & 1) {
3844       x = 0;
3845       su++;
3846       sv++;
3847     }
3848   }
3849 }
3850
3851 static void
3852 pack_A420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3853     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3854     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3855     gint y, gint width)
3856 {
3857   int i;
3858   gint uv = GET_UV_420 (y, flags);
3859   guint16 *restrict da = GET_A_LINE (y);
3860   guint16 *restrict dy = GET_Y_LINE (y);
3861   guint16 *restrict du = GET_U_LINE (uv);
3862   guint16 *restrict dv = GET_V_LINE (uv);
3863   guint16 A0, Y0, A1, Y1, U, V;
3864   const guint16 *restrict s = src;
3865
3866   if (IS_CHROMA_LINE_420 (y, flags)) {
3867     for (i = 0; i < width - 1; i += 2) {
3868       A0 = s[i * 4 + 0] >> 6;
3869       Y0 = s[i * 4 + 1] >> 6;
3870       A1 = s[i * 4 + 4] >> 6;
3871       Y1 = s[i * 4 + 5] >> 6;
3872       U = s[i * 4 + 2] >> 6;
3873       V = s[i * 4 + 3] >> 6;
3874
3875       GST_WRITE_UINT16_LE (da + i + 0, A0);
3876       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3877       GST_WRITE_UINT16_LE (da + i + 1, A1);
3878       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3879       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3880       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3881     }
3882     if (i == width - 1) {
3883       A0 = s[i * 4 + 0] >> 6;
3884       Y0 = s[i * 4 + 1] >> 6;
3885       U = s[i * 4 + 2] >> 6;
3886       V = s[i * 4 + 3] >> 6;
3887
3888       GST_WRITE_UINT16_LE (da + i, A0);
3889       GST_WRITE_UINT16_LE (dy + i, Y0);
3890       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3891       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3892     }
3893   } else {
3894     for (i = 0; i < width; i++) {
3895       A0 = s[i * 4 + 0] >> 6;
3896       Y0 = s[i * 4 + 1] >> 6;
3897       GST_WRITE_UINT16_LE (da + i, A0);
3898       GST_WRITE_UINT16_LE (dy + i, Y0);
3899     }
3900   }
3901 }
3902
3903 #define PACK_A420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A420_10BE, 1, pack_A420_10BE
3904 static void
3905 unpack_A420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3906     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3907     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3908 {
3909   int i;
3910   gint uv = GET_UV_420 (y, flags);
3911   const guint16 *restrict sa = GET_A_LINE (y);
3912   const guint16 *restrict sy = GET_Y_LINE (y);
3913   const guint16 *restrict su = GET_U_LINE (uv);
3914   const guint16 *restrict sv = GET_V_LINE (uv);
3915   guint16 *restrict d = dest, A, Y, U, V;
3916
3917   sa += x;
3918   sy += x;
3919   su += x >> 1;
3920   sv += x >> 1;
3921
3922   for (i = 0; i < width; i++) {
3923     A = GST_READ_UINT16_BE (sa + i) << 6;
3924     Y = GST_READ_UINT16_BE (sy + i) << 6;
3925     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3926     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3927
3928     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3929       A |= (A >> 10);
3930       Y |= (Y >> 10);
3931       U |= (U >> 10);
3932       V |= (V >> 10);
3933     }
3934
3935     d[i * 4 + 0] = A;
3936     d[i * 4 + 1] = Y;
3937     d[i * 4 + 2] = U;
3938     d[i * 4 + 3] = V;
3939
3940     if (x & 1) {
3941       x = 0;
3942       su++;
3943       sv++;
3944     }
3945   }
3946 }
3947
3948 static void
3949 pack_A420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3950     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3951     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3952     gint y, gint width)
3953 {
3954   int i;
3955   gint uv = GET_UV_420 (y, flags);
3956   guint16 *restrict da = GET_A_LINE (y);
3957   guint16 *restrict dy = GET_Y_LINE (y);
3958   guint16 *restrict du = GET_U_LINE (uv);
3959   guint16 *restrict dv = GET_V_LINE (uv);
3960   guint16 A0, Y0, A1, Y1, U, V;
3961   const guint16 *restrict s = src;
3962
3963   if (IS_CHROMA_LINE_420 (y, flags)) {
3964     for (i = 0; i < width - 1; i += 2) {
3965       A0 = s[i * 4 + 0] >> 6;
3966       Y0 = s[i * 4 + 1] >> 6;
3967       A1 = s[i * 4 + 4] >> 6;
3968       Y1 = s[i * 4 + 5] >> 6;
3969       U = s[i * 4 + 2] >> 6;
3970       V = s[i * 4 + 3] >> 6;
3971
3972       GST_WRITE_UINT16_BE (da + i + 0, A0);
3973       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3974       GST_WRITE_UINT16_BE (da + i + 1, A1);
3975       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3976       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3977       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3978     }
3979     if (i == width - 1) {
3980       A0 = s[i * 4 + 0] >> 6;
3981       Y0 = s[i * 4 + 1] >> 6;
3982       U = s[i * 4 + 2] >> 6;
3983       V = s[i * 4 + 3] >> 6;
3984
3985       GST_WRITE_UINT16_BE (da + i, A0);
3986       GST_WRITE_UINT16_BE (dy + i, Y0);
3987       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3988       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3989     }
3990   } else {
3991     for (i = 0; i < width; i++) {
3992       A0 = s[i * 4 + 0] >> 6;
3993       Y0 = s[i * 4 + 1] >> 6;
3994       GST_WRITE_UINT16_BE (da + i, A0);
3995       GST_WRITE_UINT16_BE (dy + i, Y0);
3996     }
3997   }
3998 }
3999
4000 #define PACK_A422_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A422_10LE, 1, pack_A422_10LE
4001 static void
4002 unpack_A422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4003     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4004     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4005 {
4006   int i;
4007   const guint16 *restrict sa = GET_A_LINE (y);
4008   const guint16 *restrict sy = GET_Y_LINE (y);
4009   const guint16 *restrict su = GET_U_LINE (y);
4010   const guint16 *restrict sv = GET_V_LINE (y);
4011   guint16 *restrict d = dest, A, Y, U, V;
4012
4013   sa += x;
4014   sy += x;
4015   su += x >> 1;
4016   sv += x >> 1;
4017
4018   for (i = 0; i < width; i++) {
4019     A = GST_READ_UINT16_LE (sa + i) << 6;
4020     Y = GST_READ_UINT16_LE (sy + i) << 6;
4021     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
4022     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
4023
4024     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4025       A |= (A >> 10);
4026       Y |= (Y >> 10);
4027       U |= (U >> 10);
4028       V |= (V >> 10);
4029     }
4030
4031     d[i * 4 + 0] = A;
4032     d[i * 4 + 1] = Y;
4033     d[i * 4 + 2] = U;
4034     d[i * 4 + 3] = V;
4035
4036     if (x & 1) {
4037       x = 0;
4038       su++;
4039       sv++;
4040     }
4041   }
4042 }
4043
4044 static void
4045 pack_A422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4046     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4047     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4048     gint y, gint width)
4049 {
4050   int i;
4051   guint16 *restrict da = GET_A_LINE (y);
4052   guint16 *restrict dy = GET_Y_LINE (y);
4053   guint16 *restrict du = GET_U_LINE (y);
4054   guint16 *restrict dv = GET_V_LINE (y);
4055   guint16 A0, Y0, A1, Y1, U, V;
4056   const guint16 *restrict s = src;
4057
4058   for (i = 0; i < width - 1; i += 2) {
4059     A0 = s[i * 4 + 0] >> 6;
4060     Y0 = s[i * 4 + 1] >> 6;
4061     A1 = s[i * 4 + 4] >> 6;
4062     Y1 = s[i * 4 + 5] >> 6;
4063     U = s[i * 4 + 2] >> 6;
4064     V = s[i * 4 + 3] >> 6;
4065
4066     GST_WRITE_UINT16_LE (da + i + 0, A0);
4067     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
4068     GST_WRITE_UINT16_LE (da + i + 1, A1);
4069     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
4070     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4071     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4072   }
4073   if (i == width - 1) {
4074     A0 = s[i * 4 + 0] >> 6;
4075     Y0 = s[i * 4 + 1] >> 6;
4076     U = s[i * 4 + 2] >> 6;
4077     V = s[i * 4 + 3] >> 6;
4078
4079     GST_WRITE_UINT16_LE (da + i, A0);
4080     GST_WRITE_UINT16_LE (dy + i, Y0);
4081     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4082     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4083   }
4084 }
4085
4086 #define PACK_A422_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A422_10BE, 1, pack_A422_10BE
4087 static void
4088 unpack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4089     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4090     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4091 {
4092   int i;
4093   const guint16 *restrict sa = GET_A_LINE (y);
4094   const guint16 *restrict sy = GET_Y_LINE (y);
4095   const guint16 *restrict su = GET_U_LINE (y);
4096   const guint16 *restrict sv = GET_V_LINE (y);
4097   guint16 *restrict d = dest, A, Y, U, V;
4098
4099   sa += x;
4100   sy += x;
4101   su += x >> 1;
4102   sv += x >> 1;
4103
4104   for (i = 0; i < width; i++) {
4105     A = GST_READ_UINT16_BE (sa + i) << 6;
4106     Y = GST_READ_UINT16_BE (sy + i) << 6;
4107     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
4108     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
4109
4110     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4111       A |= (A >> 10);
4112       Y |= (Y >> 10);
4113       U |= (U >> 10);
4114       V |= (V >> 10);
4115     }
4116
4117     d[i * 4 + 0] = A;
4118     d[i * 4 + 1] = Y;
4119     d[i * 4 + 2] = U;
4120     d[i * 4 + 3] = V;
4121
4122     if (x & 1) {
4123       x = 0;
4124       su++;
4125       sv++;
4126     }
4127   }
4128 }
4129
4130 static void
4131 pack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4132     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4133     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4134     gint y, gint width)
4135 {
4136   int i;
4137   guint16 *restrict da = GET_A_LINE (y);
4138   guint16 *restrict dy = GET_Y_LINE (y);
4139   guint16 *restrict du = GET_U_LINE (y);
4140   guint16 *restrict dv = GET_V_LINE (y);
4141   guint16 A0, Y0, A1, Y1, U, V;
4142   const guint16 *restrict s = src;
4143
4144   for (i = 0; i < width - 1; i += 2) {
4145     A0 = s[i * 4 + 0] >> 6;
4146     Y0 = s[i * 4 + 1] >> 6;
4147     A1 = s[i * 4 + 4] >> 6;
4148     Y1 = s[i * 4 + 5] >> 6;
4149     U = s[i * 4 + 2] >> 6;
4150     V = s[i * 4 + 3] >> 6;
4151
4152     GST_WRITE_UINT16_BE (da + i + 0, A0);
4153     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
4154     GST_WRITE_UINT16_BE (da + i + 1, A1);
4155     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
4156     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4157     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4158   }
4159   if (i == width - 1) {
4160     A0 = s[i * 4 + 0] >> 6;
4161     Y0 = s[i * 4 + 1] >> 6;
4162     U = s[i * 4 + 2] >> 6;
4163     V = s[i * 4 + 3] >> 6;
4164
4165     GST_WRITE_UINT16_BE (da + i, A0);
4166     GST_WRITE_UINT16_BE (dy + i, Y0);
4167     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4168     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4169   }
4170 }
4171
4172 static void
4173 get_tile_NV12 (gint tile_width, gint ts, gint tx, gint ty,
4174     const gpointer data[GST_VIDEO_MAX_PLANES],
4175     const gint stride[GST_VIDEO_MAX_PLANES],
4176     gpointer tile_data[GST_VIDEO_MAX_PLANES],
4177     gint tile_stride[GST_VIDEO_MAX_PLANES])
4178 {
4179   gsize offset;
4180
4181   /* index of Y tile */
4182   offset = gst_video_tile_get_index (GST_VIDEO_TILE_MODE_ZFLIPZ_2X2,
4183       tx, ty, GST_VIDEO_TILE_X_TILES (stride[0]),
4184       GST_VIDEO_TILE_Y_TILES (stride[0]));
4185   offset <<= ts;
4186   tile_data[0] = ((guint8 *) data[0]) + offset;
4187
4188   /* index of UV tile */
4189   offset = gst_video_tile_get_index (GST_VIDEO_TILE_MODE_ZFLIPZ_2X2,
4190       tx, ty >> 1, GST_VIDEO_TILE_X_TILES (stride[1]),
4191       GST_VIDEO_TILE_Y_TILES (stride[1]));
4192   offset <<= ts;
4193   /* On odd rows we return the second part of the UV tile */
4194   offset |= (ty & 1) << (ts - 1);
4195   tile_data[1] = ((guint8 *) data[1]) + offset;
4196
4197   tile_stride[0] = tile_stride[1] = tile_width;
4198 }
4199
4200 #define PACK_NV12_64Z32 GST_VIDEO_FORMAT_AYUV, unpack_NV12_64Z32, 1, pack_NV12_64Z32
4201 static void
4202 unpack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4203     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4204     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4205 {
4206   const GstVideoFormatInfo *unpack_info, *finfo;
4207   guint8 *line = dest;
4208   gint ws, hs, ts, tile_width;
4209   gint ntx, tx, ty;
4210   gint unpack_pstride;
4211
4212   ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
4213   hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
4214   ts = ws + hs;
4215
4216   tile_width = 1 << ws;
4217
4218   /* we reuse these unpack functions */
4219   finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
4220
4221   /* get pstride of unpacked format */
4222   unpack_info = gst_video_format_get_info (info->unpack_format);
4223   unpack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (unpack_info, 0);
4224
4225   /* first x tile to convert */
4226   tx = x >> ws;
4227   /* Last tile to convert */
4228   ntx = ((x + width - 1) >> ws) + 1;
4229   /* The row we are going to convert */
4230   ty = y >> hs;
4231
4232   /* y position in a tile */
4233   y = y & ((1 << hs) - 1);
4234   /* x position in a tile */
4235   x = x & (tile_width - 1);
4236
4237   for (; tx < ntx; tx++) {
4238     gpointer tdata[GST_VIDEO_MAX_PLANES];
4239     gint tstride[GST_VIDEO_MAX_PLANES];
4240     gint unpack_width;
4241
4242     get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride);
4243
4244     /* the number of bytes left to unpack */
4245     unpack_width = MIN (width - x, tile_width - x);
4246
4247     finfo->unpack_func (finfo, flags, line, tdata, tstride, x, y, unpack_width);
4248
4249     x = 0;
4250     width -= unpack_width;
4251     line += unpack_width * unpack_pstride;
4252   }
4253 }
4254
4255 static void
4256 pack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4257     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4258     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4259     gint y, gint width)
4260 {
4261   const GstVideoFormatInfo *pack_info, *finfo;
4262   guint8 *line = src;
4263   gint ws, hs, ts, tile_width;
4264   gint ntx, tx, ty;
4265   gint pack_pstride;
4266
4267   ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
4268   hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
4269   ts = ws + hs;
4270
4271   tile_width = 1 << ws;
4272
4273   /* we reuse these pack functions */
4274   finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
4275
4276   /* get pstride of packed format */
4277   pack_info = gst_video_format_get_info (info->unpack_format);
4278   pack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (pack_info, 0);
4279
4280   /* Last tile to convert */
4281   ntx = ((width - 1) >> ws) + 1;
4282   /* The row we are going to convert */
4283   ty = y >> hs;
4284
4285   /* y position in a tile */
4286   y = y & ((1 << hs) - 1);
4287
4288   for (tx = 0; tx < ntx; tx++) {
4289     gpointer tdata[GST_VIDEO_MAX_PLANES];
4290     gint tstride[GST_VIDEO_MAX_PLANES];
4291     gint pack_width;
4292
4293     get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride);
4294
4295     /* the number of bytes left to pack */
4296     pack_width = MIN (width, tile_width);
4297
4298     finfo->pack_func (finfo, flags, line, sstride, tdata, tstride,
4299         chroma_site, y, pack_width);
4300
4301     width -= pack_width;
4302     line += pack_width * pack_pstride;
4303   }
4304 }
4305
4306 #define PACK_P010_10BE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10BE, 1, pack_P010_10BE
4307 static void
4308 unpack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4309     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4310     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4311 {
4312   int i;
4313   gint uv = GET_UV_420 (y, flags);
4314   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
4315   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
4316   guint16 *restrict d = dest, Y0, Y1, U, V;
4317
4318   sy += x;
4319   suv += (x & ~1);
4320
4321   if (x & 1) {
4322     Y0 = GST_READ_UINT16_BE (sy);
4323     U = GST_READ_UINT16_BE (suv);
4324     V = GST_READ_UINT16_BE (suv + 1);
4325
4326     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4327       Y0 |= (Y0 >> 10);
4328       U |= (U >> 10);
4329       V |= (V >> 10);
4330     }
4331
4332     d[0] = 0xffff;
4333     d[1] = Y0;
4334     d[2] = U;
4335     d[3] = V;
4336     width--;
4337     d += 4;
4338     sy += 1;
4339     suv += 2;
4340   }
4341
4342   for (i = 0; i < width / 2; i++) {
4343     Y0 = GST_READ_UINT16_BE (sy + 2 * i);
4344     Y1 = GST_READ_UINT16_BE (sy + 2 * i + 1);
4345     U = GST_READ_UINT16_BE (suv + 2 * i);
4346     V = GST_READ_UINT16_BE (suv + 2 * i + 1);
4347
4348     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4349       Y0 |= (Y0 >> 10);
4350       Y1 |= (Y1 >> 10);
4351       U |= (U >> 10);
4352       V |= (V >> 10);
4353     }
4354
4355     d[i * 8 + 0] = 0xffff;
4356     d[i * 8 + 1] = Y0;
4357     d[i * 8 + 2] = U;
4358     d[i * 8 + 3] = V;
4359     d[i * 8 + 4] = 0xffff;
4360     d[i * 8 + 5] = Y1;
4361     d[i * 8 + 6] = U;
4362     d[i * 8 + 7] = V;
4363   }
4364
4365   if (width & 1) {
4366     gint i = width - 1;
4367
4368     Y0 = GST_READ_UINT16_BE (sy + i);
4369     U = GST_READ_UINT16_BE (suv + i);
4370     V = GST_READ_UINT16_BE (suv + i + 1);
4371
4372     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4373       Y0 |= (Y0 >> 10);
4374       U |= (U >> 10);
4375       V |= (V >> 10);
4376     }
4377
4378     d[i * 4 + 0] = 0xffff;
4379     d[i * 4 + 1] = Y0;
4380     d[i * 4 + 2] = U;
4381     d[i * 4 + 3] = V;
4382   }
4383 }
4384
4385 static void
4386 pack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4387     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4388     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4389     gint y, gint width)
4390 {
4391   int i;
4392   gint uv = GET_UV_420 (y, flags);
4393   guint16 *restrict dy = GET_PLANE_LINE (0, y);
4394   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
4395   guint16 Y0, Y1, U, V;
4396   const guint16 *restrict s = src;
4397
4398   if (IS_CHROMA_LINE_420 (y, flags)) {
4399     for (i = 0; i < width / 2; i++) {
4400       Y0 = s[i * 8 + 1] & 0xffc0;
4401       Y1 = s[i * 8 + 5] & 0xffc0;
4402       U = s[i * 8 + 2] & 0xffc0;
4403       V = s[i * 8 + 3] & 0xffc0;
4404
4405       GST_WRITE_UINT16_BE (dy + i * 2 + 0, Y0);
4406       GST_WRITE_UINT16_BE (dy + i * 2 + 1, Y1);
4407       GST_WRITE_UINT16_BE (duv + i * 2 + 0, U);
4408       GST_WRITE_UINT16_BE (duv + i * 2 + 1, V);
4409     }
4410     if (width & 1) {
4411       gint i = width - 1;
4412
4413       Y0 = s[i * 4 + 1] & 0xffc0;
4414       U = s[i * 4 + 2] & 0xffc0;
4415       V = s[i * 4 + 3] & 0xffc0;
4416
4417       GST_WRITE_UINT16_BE (dy + i, Y0);
4418       GST_WRITE_UINT16_BE (duv + i + 0, U);
4419       GST_WRITE_UINT16_BE (duv + i + 1, V);
4420     }
4421   } else {
4422     for (i = 0; i < width; i++) {
4423       Y0 = s[i * 4 + 1] & 0xffc0;
4424       GST_WRITE_UINT16_BE (dy + i, Y0);
4425     }
4426   }
4427 }
4428
4429 #define PACK_P010_10LE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10LE, 1, pack_P010_10LE
4430 static void
4431 unpack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4432     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4433     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4434 {
4435   int i;
4436   gint uv = GET_UV_420 (y, flags);
4437   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
4438   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
4439   guint16 *restrict d = dest, Y0, Y1, U, V;
4440
4441   sy += x;
4442   suv += (x & ~1);
4443
4444   if (x & 1) {
4445     Y0 = GST_READ_UINT16_LE (sy);
4446     U = GST_READ_UINT16_LE (suv);
4447     V = GST_READ_UINT16_LE (suv + 1);
4448
4449     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4450       Y0 |= (Y0 >> 10);
4451       U |= (U >> 10);
4452       V |= (V >> 10);
4453     }
4454
4455     d[0] = 0xffff;
4456     d[1] = Y0;
4457     d[2] = U;
4458     d[3] = V;
4459     width--;
4460     d += 4;
4461     sy += 1;
4462     suv += 2;
4463   }
4464
4465   for (i = 0; i < width / 2; i++) {
4466     Y0 = GST_READ_UINT16_LE (sy + 2 * i);
4467     Y1 = GST_READ_UINT16_LE (sy + 2 * i + 1);
4468     U = GST_READ_UINT16_LE (suv + 2 * i);
4469     V = GST_READ_UINT16_LE (suv + 2 * i + 1);
4470
4471     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4472       Y0 |= (Y0 >> 10);
4473       Y1 |= (Y1 >> 10);
4474       U |= (U >> 10);
4475       V |= (V >> 10);
4476     }
4477
4478     d[i * 8 + 0] = 0xffff;
4479     d[i * 8 + 1] = Y0;
4480     d[i * 8 + 2] = U;
4481     d[i * 8 + 3] = V;
4482     d[i * 8 + 4] = 0xffff;
4483     d[i * 8 + 5] = Y1;
4484     d[i * 8 + 6] = U;
4485     d[i * 8 + 7] = V;
4486   }
4487
4488   if (width & 1) {
4489     gint i = width - 1;
4490
4491     Y0 = GST_READ_UINT16_LE (sy + i);
4492     U = GST_READ_UINT16_LE (suv + i);
4493     V = GST_READ_UINT16_LE (suv + i + 1);
4494
4495     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4496       Y0 |= (Y0 >> 10);
4497       U |= (U >> 10);
4498       V |= (V >> 10);
4499     }
4500
4501     d[i * 4 + 0] = 0xffff;
4502     d[i * 4 + 1] = Y0;
4503     d[i * 4 + 2] = U;
4504     d[i * 4 + 3] = V;
4505   }
4506 }
4507
4508 static void
4509 pack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4510     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4511     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4512     gint y, gint width)
4513 {
4514   int i;
4515   gint uv = GET_UV_420 (y, flags);
4516   guint16 *restrict dy = GET_PLANE_LINE (0, y);
4517   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
4518   guint16 Y0, Y1, U, V;
4519   const guint16 *restrict s = src;
4520
4521   if (IS_CHROMA_LINE_420 (y, flags)) {
4522     for (i = 0; i < width / 2; i++) {
4523       Y0 = s[i * 8 + 1] & 0xffc0;
4524       Y1 = s[i * 8 + 5] & 0xffc0;
4525       U = s[i * 8 + 2] & 0xffc0;
4526       V = s[i * 8 + 3] & 0xffc0;
4527
4528       GST_WRITE_UINT16_LE (dy + i * 2 + 0, Y0);
4529       GST_WRITE_UINT16_LE (dy + i * 2 + 1, Y1);
4530       GST_WRITE_UINT16_LE (duv + i * 2 + 0, U);
4531       GST_WRITE_UINT16_LE (duv + i * 2 + 1, V);
4532     }
4533     if (width & 1) {
4534       gint i = width - 1;
4535
4536       Y0 = s[i * 4 + 1] & 0xffc0;
4537       U = s[i * 4 + 2] & 0xffc0;
4538       V = s[i * 4 + 3] & 0xffc0;
4539
4540       GST_WRITE_UINT16_LE (dy + i, Y0);
4541       GST_WRITE_UINT16_LE (duv + i + 0, U);
4542       GST_WRITE_UINT16_LE (duv + i + 1, V);
4543     }
4544   } else {
4545     for (i = 0; i < width; i++) {
4546       Y0 = s[i * 4 + 1] & 0xffc0;
4547       GST_WRITE_UINT16_LE (dy + i, Y0);
4548     }
4549   }
4550 }
4551
4552 #define PACK_GRAY10_LE32 GST_VIDEO_FORMAT_AYUV64, unpack_GRAY10_LE32, 1, pack_GRAY10_LE32
4553 static void
4554 unpack_GRAY10_LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4555     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4556     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4557 {
4558   gint i;
4559   const guint32 *restrict sy = GET_PLANE_LINE (0, y);
4560   guint16 *restrict d = dest;
4561   gint num_words = (width + 2) / 3;
4562
4563   /* Y data is packed into little endian 32bit words, with the 2 MSB being
4564    * padding. There is only 1 pattern.
4565    * -> padding | Y1 | Y2 | Y3
4566    */
4567
4568   for (i = 0; i < num_words; i++) {
4569     gint num_comps = MIN (3, width - i * 3);
4570     guint pix = i * 3;
4571     gsize doff = pix * 4;
4572     gint c;
4573     guint32 Y;
4574
4575     Y = GST_READ_UINT32_LE (sy + i);
4576
4577     for (c = 0; c < num_comps; c++) {
4578       guint16 Yn;
4579
4580       /* For Y, we simply read 10 bit and shift it out */
4581       Yn = (Y & 0x03ff) << 6;
4582       Y >>= 10;
4583
4584       if (G_UNLIKELY (pix + c < x))
4585         continue;
4586
4587       if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE))
4588         Yn |= Yn >> 10;
4589
4590       d[doff + 0] = 0xffff;
4591       d[doff + 1] = Yn;
4592       d[doff + 2] = 0x8000;
4593       d[doff + 3] = 0x8000;
4594
4595       doff += 4;
4596     }
4597   }
4598 }
4599
4600 static void
4601 pack_GRAY10_LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4602     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4603     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4604     gint y, gint width)
4605 {
4606   gint i;
4607   guint32 *restrict dy = GET_PLANE_LINE (0, y);
4608   const guint16 *restrict s = src;
4609   gint num_words = (width + 2) / 3;
4610
4611   for (i = 0; i < num_words; i++) {
4612     gint num_comps = MIN (3, width - i * 3);
4613     guint pix = i * 3;
4614     gsize soff = pix * 4;
4615     gint c;
4616     guint32 Y = 0;
4617
4618     for (c = 0; c < num_comps; c++) {
4619       Y |= s[soff + 1] >> 6 << (10 * c);
4620       soff += 4;
4621     }
4622
4623     GST_WRITE_UINT32_LE (dy + i, Y);
4624   }
4625 }
4626
4627 #define PACK_NV12_10LE32 GST_VIDEO_FORMAT_AYUV64, unpack_NV12_10LE32, 1, pack_NV12_10LE32
4628 static void
4629 unpack_NV12_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4630     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4631     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4632 {
4633   gint i;
4634   gint uv = GET_UV_420 (y, flags);
4635   const guint32 *restrict sy = GET_PLANE_LINE (0, y);
4636   const guint32 *restrict suv = GET_PLANE_LINE (1, uv);
4637   guint16 *restrict d = dest;
4638   gint num_words = (width + 2) / 3;
4639   guint32 UV = 0;
4640   guint16 Un = 0, Vn = 0;
4641
4642   /* Y data is packed into little endian 32bit words, with the 2 MSB being
4643    * padding. There is only 1 pattern.
4644    * -> padding | Y1 | Y2 | Y3
4645    *
4646    * UV is packed the same way, though we end up with 2 patterns:
4647    * -> U | V | U | padding
4648    * -> V | U | V | padding
4649    */
4650
4651   /* FIXME unroll the 6 states ? */
4652
4653   for (i = 0; i < num_words; i++) {
4654     gint num_comps = MIN (3, width - i * 3);
4655     guint pix = i * 3;
4656     gsize doff = pix * 4;
4657     gint c;
4658     guint32 Y;
4659
4660     Y = GST_READ_UINT32_LE (sy + i);
4661
4662     for (c = 0; c < num_comps; c++) {
4663       guint16 Yn;
4664
4665       /* For Y, we simply read 10 bit and shift it out */
4666       Yn = (Y & 0x03ff) << 6;
4667       Y >>= 10;
4668
4669       /* Unpacking UV has been reduced to a cycle of 6 states. The following
4670        * code is a reduce version of:
4671        * 0: - Read first UV word (UVU)
4672        *      Unpack U and V
4673        * 1: - Resued U/V from 1 (sub-sampling)
4674        * 2: - Unpack remaining U value
4675        *    - Read following UV word (VUV)
4676        *    - Unpack V value
4677        * 3: - Reuse U/V from 2 (sub-sampling)
4678        * 4: - Unpack remaining U
4679        *    - Unpack remaining V
4680        * 5: - Reuse UV/V from 4 (sub-sampling)
4681        */
4682       switch ((pix + c) % 6) {
4683         case 0:
4684           UV = GST_READ_UINT32_LE (suv + i);
4685           /* fallthrough */
4686         case 4:
4687           Un = (UV & 0x03ff) << 6;
4688           UV >>= 10;
4689           Vn = (UV & 0x03ff) << 6;
4690           UV >>= 10;
4691           break;
4692         case 2:
4693           Un = (UV & 0x03ff) << 6;
4694           UV = GST_READ_UINT32_LE (suv + i + 1);
4695           Vn = (UV & 0x03ff) << 6;
4696           UV >>= 10;
4697           break;
4698         default:
4699           /* keep value */
4700           break;
4701       }
4702
4703       if (G_UNLIKELY (pix + c < x))
4704         continue;
4705
4706       if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4707         Yn |= Yn >> 10;
4708         Un |= Un >> 10;
4709         Vn |= Vn >> 10;
4710       }
4711
4712       d[doff + 0] = 0xffff;
4713       d[doff + 1] = Yn;
4714       d[doff + 2] = Un;
4715       d[doff + 3] = Vn;
4716
4717       doff += 4;
4718     }
4719   }
4720 }
4721
4722 static void
4723 pack_NV12_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4724     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4725     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4726     gint y, gint width)
4727 {
4728   gint i;
4729   gint uv = GET_UV_420 (y, flags);
4730   guint32 *restrict dy = GET_PLANE_LINE (0, y);
4731   guint32 *restrict duv = GET_PLANE_LINE (1, uv);
4732   const guint16 *restrict s = src;
4733   gint num_words = (width + 2) / 3;
4734   guint32 UV = 0;
4735
4736   /* FIXME unroll the 6 states ? */
4737
4738   for (i = 0; i < num_words; i++) {
4739     gint num_comps = MIN (3, width - i * 3);
4740     guint pix = i * 3;
4741     gsize soff = pix * 4;
4742     gint c;
4743     guint32 Y = 0;
4744
4745     for (c = 0; c < num_comps; c++) {
4746       Y |= s[soff + 1] >> 6 << (10 * c);
4747
4748       if (IS_CHROMA_LINE_420 (y, flags)) {
4749         switch ((pix + c) % 6) {
4750           case 0:
4751             UV = s[soff + 2] >> 6;
4752             UV |= s[soff + 3] >> 6 << 10;
4753             break;
4754           case 2:
4755             UV |= s[soff + 2] >> 6 << 20;
4756             GST_WRITE_UINT32_LE (duv + i, UV);
4757             UV = s[soff + 3] >> 6;
4758             break;
4759           case 4:
4760             UV |= s[soff + 2] >> 6 << 10;
4761             UV |= s[soff + 3] >> 6 << 20;
4762             GST_WRITE_UINT32_LE (duv + i, UV);
4763             break;
4764           default:
4765             /* keep value */
4766             break;
4767         }
4768       }
4769
4770       soff += 4;
4771     }
4772
4773     GST_WRITE_UINT32_LE (dy + i, Y);
4774
4775     if (IS_CHROMA_LINE_420 (y, flags) && num_comps < 3)
4776       GST_WRITE_UINT32_LE (duv + i, UV);
4777
4778   }
4779 }
4780
4781 #define PACK_NV16_10LE32 GST_VIDEO_FORMAT_AYUV64, unpack_NV16_10LE32, 1, pack_NV16_10LE32
4782 static void
4783 unpack_NV16_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4784     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4785     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4786 {
4787   gint i;
4788   const guint32 *restrict sy = GET_PLANE_LINE (0, y);
4789   const guint32 *restrict suv = GET_PLANE_LINE (1, y);
4790   guint16 *restrict d = dest;
4791   gint num_words = (width + 2) / 3;
4792   guint32 UV = 0;
4793   guint16 Un = 0, Vn = 0;
4794
4795   /* Y data is packed into little endian 32bit words, with the 2 MSB being
4796    * padding. There is only 1 pattern.
4797    * -> padding | Y1 | Y2 | Y3
4798    *
4799    * UV is packed the same way, though we end up with 2 patterns:
4800    * -> U | V | U | padding
4801    * -> V | U | V | padding
4802    */
4803
4804   /* FIXME unroll the 6 states ? */
4805
4806   for (i = 0; i < num_words; i++) {
4807     gint num_comps = MIN (3, width - i * 3);
4808     guint pix = i * 3;
4809     gsize doff = pix * 4;
4810     gint c;
4811     guint32 Y;
4812
4813     Y = GST_READ_UINT32_LE (sy + i);
4814
4815     for (c = 0; c < num_comps; c++) {
4816       guint16 Yn;
4817
4818       /* For Y, we simply read 10 bit and shift it out */
4819       Yn = (Y & 0x03ff) << 6;
4820       Y >>= 10;
4821
4822       /* Unpacking UV has been reduced to a cycle of 6 states. The following
4823        * code is a reduce version of:
4824        * 0: - Read first UV word (UVU)
4825        *      Unpack U and V
4826        * 1: - Resued U/V from 1 (sub-sampling)
4827        * 2: - Unpack remaining U value
4828        *    - Read following UV word (VUV)
4829        *    - Unpack V value
4830        * 3: - Reuse U/V from 2 (sub-sampling)
4831        * 4: - Unpack remaining U
4832        *    - Unpack remaining V
4833        * 5: - Reuse UV/V from 4 (sub-sampling)
4834        */
4835       switch ((pix + c) % 6) {
4836         case 0:
4837           UV = GST_READ_UINT32_LE (suv + i);
4838           /* fallthrough */
4839         case 4:
4840           Un = (UV & 0x03ff) << 6;
4841           UV >>= 10;
4842           Vn = (UV & 0x03ff) << 6;
4843           UV >>= 10;
4844           break;
4845         case 2:
4846           Un = (UV & 0x03ff) << 6;
4847           UV = GST_READ_UINT32_LE (suv + i + 1);
4848           Vn = (UV & 0x03ff) << 6;
4849           UV >>= 10;
4850           break;
4851         default:
4852           /* keep value */
4853           break;
4854       }
4855
4856       if (G_UNLIKELY (pix + c < x))
4857         continue;
4858
4859       if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4860         Yn |= Yn >> 10;
4861         Un |= Un >> 10;
4862         Vn |= Vn >> 10;
4863       }
4864
4865       d[doff + 0] = 0xffff;
4866       d[doff + 1] = Yn;
4867       d[doff + 2] = Un;
4868       d[doff + 3] = Vn;
4869
4870       doff += 4;
4871     }
4872   }
4873 }
4874
4875 static void
4876 pack_NV16_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4877     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4878     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4879     gint y, gint width)
4880 {
4881   gint i;
4882   guint32 *restrict dy = GET_PLANE_LINE (0, y);
4883   guint32 *restrict duv = GET_PLANE_LINE (1, y);
4884   const guint16 *restrict s = src;
4885   gint num_words = (width + 2) / 3;
4886   guint32 UV = 0;
4887
4888   /* FIXME unroll the 6 states ? */
4889
4890   for (i = 0; i < num_words; i++) {
4891     gint num_comps = MIN (3, width - i * 3);
4892     guint pix = i * 3;
4893     gsize soff = pix * 4;
4894     gint c;
4895     guint32 Y = 0;
4896
4897     for (c = 0; c < num_comps; c++) {
4898       Y |= s[soff + 1] >> 6 << (10 * c);
4899
4900       switch ((pix + c) % 6) {
4901         case 0:
4902           UV = s[soff + 2] >> 6;
4903           UV |= s[soff + 3] >> 6 << 10;
4904           break;
4905         case 2:
4906           UV |= s[soff + 2] >> 6 << 20;
4907           GST_WRITE_UINT32_LE (duv + i, UV);
4908           UV = s[soff + 3] >> 6;
4909           break;
4910         case 4:
4911           UV |= s[soff + 2] >> 6 << 10;
4912           UV |= s[soff + 3] >> 6 << 20;
4913           GST_WRITE_UINT32_LE (duv + i, UV);
4914           break;
4915         default:
4916           /* keep value */
4917           break;
4918       }
4919
4920       soff += 4;
4921     }
4922
4923     GST_WRITE_UINT32_LE (dy + i, Y);
4924
4925     if (num_comps < 3)
4926       GST_WRITE_UINT32_LE (duv + i, UV);
4927   }
4928 }
4929
4930 #define PACK_NV12_10LE40 GST_VIDEO_FORMAT_AYUV64, unpack_NV12_10LE40, 1, pack_NV12_10LE40
4931 static void
4932 unpack_NV12_10LE40 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4933     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4934     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4935 {
4936   gint i;
4937   gint uv = GET_UV_420 (y, flags);
4938   guint16 *restrict d = dest;
4939   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
4940   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
4941   guint16 Y0 = 0, Y1 = 0, Yn = 0, Un = 0, Vn = 0;
4942   guint32 UV = 0;
4943
4944   for (i = 0; i < width; i++) {
4945     gboolean update_c = FALSE;
4946
4947     switch (i & 3) {
4948       case 0:
4949         Y0 = GST_READ_UINT16_LE (sy);
4950         Yn = Y0 & 0x3ff;
4951         sy += 2;
4952
4953         UV = GST_READ_UINT32_LE (suv);
4954         Un = UV & 0x3ff;
4955         Vn = (UV >> 10) & 0x3ff;
4956         suv += 4;
4957
4958         Yn <<= 6;
4959         Un <<= 6;
4960         Vn <<= 6;
4961         update_c = TRUE;
4962         break;
4963       case 1:
4964         Y1 = GST_READ_UINT16_LE (sy);
4965         Yn = (Y0 >> 10) | ((Y1 & 0xf) << 6);
4966         sy += 2;
4967
4968         Yn <<= 6;
4969         break;
4970       case 2:
4971         Yn = (Y1 >> 4) & 0x3ff;
4972
4973         Un = (UV >> 20) & 0x3ff;
4974         Vn = (UV >> 30);
4975         UV = GST_READ_UINT8 (suv);
4976         Vn |= (UV << 2);
4977         suv++;
4978
4979         Yn <<= 6;
4980         Un <<= 6;
4981         Vn <<= 6;
4982         update_c = TRUE;
4983         break;
4984       case 3:
4985         Y0 = GST_READ_UINT8 (sy);
4986         Yn = (Y1 >> 14) | (Y0 << 2);
4987         sy++;
4988
4989         Yn <<= 6;
4990         break;
4991     }
4992
4993     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4994       Yn |= Yn >> 10;
4995       if (update_c) {
4996         Un |= Un >> 10;
4997         Vn |= Vn >> 10;
4998       }
4999     }
5000
5001     d[i * 4 + 0] = 0xffff;
5002     d[i * 4 + 1] = Yn;
5003     d[i * 4 + 2] = Un;
5004     d[i * 4 + 3] = Vn;
5005   }
5006 }
5007
5008 static void
5009 pack_NV12_10LE40 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5010     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5011     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5012     gint y, gint width)
5013 {
5014   gint i;
5015   gint uv = GET_UV_420 (y, flags);
5016   guint8 *restrict dy = GET_PLANE_LINE (0, y);
5017   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
5018   guint16 Y0 = 0, Y1 = 0, Y2 = 0, Y3 = 0, U0, V0 = 0, U1 = 0, V1 = 0;
5019   const guint16 *restrict s = src;
5020
5021   for (i = 0; i < width; i++) {
5022     switch (i & 3) {
5023       case 0:
5024         Y0 = s[i * 4 + 1] >> 6;
5025         GST_WRITE_UINT8 (dy, Y0 & 0xff);
5026         dy++;
5027
5028         if (IS_CHROMA_LINE_420 (y, flags)) {
5029           U0 = s[i * 4 + 2] >> 6;
5030           V0 = s[i * 4 + 3] >> 6;
5031
5032           GST_WRITE_UINT8 (duv, U0 & 0xff);
5033           duv++;
5034
5035           GST_WRITE_UINT8 (duv, (U0 >> 8) | ((V0 & 0x3f) << 2));
5036           duv++;
5037         }
5038         break;
5039       case 1:
5040         Y1 = s[i * 4 + 1] >> 6;
5041         GST_WRITE_UINT8 (dy, (Y0 >> 8) | ((Y1 & 0x3f) << 2));
5042         dy++;
5043         break;
5044       case 2:
5045         Y2 = s[i * 4 + 1] >> 6;
5046         GST_WRITE_UINT8 (dy, (Y1 >> 6) | ((Y2 & 0xf) << 4));
5047         dy++;
5048
5049         if (IS_CHROMA_LINE_420 (y, flags)) {
5050           U1 = s[i * 4 + 2] >> 6;
5051           V1 = s[i * 4 + 3] >> 6;
5052
5053           GST_WRITE_UINT8 (duv, (V0 >> 6) | ((U1 & 0xf) << 4));
5054           duv++;
5055
5056           GST_WRITE_UINT8 (duv, (U1 >> 4) | ((V1 & 0x3) << 6));
5057           duv++;
5058
5059           GST_WRITE_UINT8 (duv, V1 >> 2);
5060           duv++;
5061         }
5062         break;
5063       case 3:
5064         Y3 = s[i * 4 + 1] >> 6;
5065         GST_WRITE_UINT8 (dy, (Y2 >> 4) | ((Y3 & 0x3) << 6));
5066         dy++;
5067         GST_WRITE_UINT8 (dy, (Y3 >> 2));
5068         dy++;
5069         break;
5070     }
5071   }
5072
5073   switch (width & 3) {
5074     case 0:
5075       break;
5076     case 1:
5077       GST_WRITE_UINT8 (dy, Y0 >> 8);
5078       if (IS_CHROMA_LINE_420 (y, flags))
5079         GST_WRITE_UINT8 (duv, V0 >> 6);
5080       break;
5081     case 2:
5082       GST_WRITE_UINT8 (dy, Y1 >> 6);
5083       if (IS_CHROMA_LINE_420 (y, flags))
5084         GST_WRITE_UINT8 (duv, V0 >> 6);
5085       break;
5086     case 3:
5087       GST_WRITE_UINT8 (dy, Y2 >> 4);
5088       break;
5089   }
5090 }
5091
5092 typedef struct
5093 {
5094   guint32 fourcc;
5095   GstVideoFormatInfo info;
5096 } VideoFormat;
5097
5098 /* depths: bits, n_components, shift, depth */
5099 #define DPTH0            0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
5100 #define DPTH8            8, 1, { 0, 0, 0, 0 }, { 8, 0, 0, 0 }
5101 #define DPTH8_32         8, 2, { 0, 0, 0, 0 }, { 8, 32, 0, 0 }
5102 #define DPTH888          8, 3, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
5103 #define DPTH8888         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 8 }
5104 #define DPTH8880         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
5105 #define DPTH10           10, 1, { 0, 0, 0, 0 }, { 10, 0, 0, 0 }
5106 #define DPTH10_10_10     10, 3, { 0, 0, 0, 0 }, { 10, 10, 10, 0 }
5107 #define DPTH10_10_10_10  10, 4, { 0, 0, 0, 0 }, { 10, 10, 10, 10 }
5108 #define DPTH10_10_10_HI  16, 3, { 6, 6, 6, 0 }, { 10, 10, 10, 0 }
5109 #define DPTH12_12_12     12, 3, { 0, 0, 0, 0 }, { 12, 12, 12, 0 }
5110 #define DPTH12_12_12_12  12, 4, { 0, 0, 0, 0 }, { 12, 12, 12, 12 }
5111 #define DPTH16           16, 1, { 0, 0, 0, 0 }, { 16, 0, 0, 0 }
5112 #define DPTH16_16_16     16, 3, { 0, 0, 0, 0 }, { 16, 16, 16, 0 }
5113 #define DPTH16_16_16_16  16, 4, { 0, 0, 0, 0 }, { 16, 16, 16, 16 }
5114 #define DPTH555          16, 3, { 10, 5, 0, 0 }, { 5, 5, 5, 0 }
5115 #define DPTH565          16, 3, { 11, 5, 0, 0 }, { 5, 6, 5, 0 }
5116
5117 /* pixel strides */
5118 #define PSTR0             { 0, 0, 0, 0 }
5119 #define PSTR1             { 1, 0, 0, 0 }
5120 #define PSTR14            { 1, 4, 0, 0 }
5121 #define PSTR111           { 1, 1, 1, 0 }
5122 #define PSTR1111          { 1, 1, 1, 1 }
5123 #define PSTR122           { 1, 2, 2, 0 }
5124 #define PSTR2             { 2, 0, 0, 0 }
5125 #define PSTR222           { 2, 2, 2, 0 }
5126 #define PSTR2222          { 2, 2, 2, 2 }
5127 #define PSTR244           { 2, 4, 4, 0 }
5128 #define PSTR444           { 4, 4, 4, 0 }
5129 #define PSTR4444          { 4, 4, 4, 4 }
5130 #define PSTR333           { 3, 3, 3, 0 }
5131 #define PSTR488           { 4, 8, 8, 0 }
5132 #define PSTR8888          { 8, 8, 8, 8 }
5133
5134 /* planes, in what plane do we find component N */
5135 #define PLANE_NA          0, { 0, 0, 0, 0 }
5136 #define PLANE0            1, { 0, 0, 0, 0 }
5137 #define PLANE01           2, { 0, 1, 0, 0 }
5138 #define PLANE011          2, { 0, 1, 1, 0 }
5139 #define PLANE012          3, { 0, 1, 2, 0 }
5140 #define PLANE0123         4, { 0, 1, 2, 3 }
5141 #define PLANE021          3, { 0, 2, 1, 0 }
5142 #define PLANE201          3, { 2, 0, 1, 0 }
5143 #define PLANE2013         4, { 2, 0, 1, 3 }
5144
5145 /* offsets */
5146 #define OFFS0             { 0, 0, 0, 0 }
5147 #define OFFS013           { 0, 1, 3, 0 }
5148 #define OFFS102           { 1, 0, 2, 0 }
5149 #define OFFS1230          { 1, 2, 3, 0 }
5150 #define OFFS012           { 0, 1, 2, 0 }
5151 #define OFFS210           { 2, 1, 0, 0 }
5152 #define OFFS123           { 1, 2, 3, 0 }
5153 #define OFFS321           { 3, 2, 1, 0 }
5154 #define OFFS0123          { 0, 1, 2, 3 }
5155 #define OFFS2103          { 2, 1, 0, 3 }
5156 #define OFFS3210          { 3, 2, 1, 0 }
5157 #define OFFS031           { 0, 3, 1, 0 }
5158 #define OFFS204           { 2, 0, 4, 0 }
5159 #define OFFS001           { 0, 0, 1, 0 }
5160 #define OFFS010           { 0, 1, 0, 0 }
5161 #define OFFS104           { 1, 0, 4, 0 }
5162 #define OFFS2460          { 2, 4, 6, 0 }
5163
5164 /* subsampling, w_sub, h_sub */
5165 #define SUB410            { 0, 2, 2, 0 }, { 0, 2, 2, 0 }
5166 #define SUB411            { 0, 2, 2, 0 }, { 0, 0, 0, 0 }
5167 #define SUB420            { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
5168 #define SUB422            { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
5169 #define SUB4              { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
5170 #define SUB44             { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
5171 #define SUB444            { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
5172 #define SUB4444           { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
5173 #define SUB4204           { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
5174 #define SUB4224           { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
5175
5176 /* tile_mode, tile_width, tile_height */
5177 #define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5
5178
5179 #define MAKE_YUV_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
5180  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV, depth, pstride, plane, offs, sub, pack } }
5181 #define MAKE_YUV_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
5182  { 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 } }
5183 #define MAKE_YUVA_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
5184  { 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 } }
5185 #define MAKE_YUVA_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
5186  { 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 } }
5187 #define MAKE_YUVA_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
5188  { 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 } }
5189 #define MAKE_YUVA_LE_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
5190  { 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 } }
5191 #define MAKE_YUV_C_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
5192  { 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 } }
5193 #define MAKE_YUV_C_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
5194  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_COMPLEX | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
5195 #define MAKE_YUV_T_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack, tile) \
5196  { 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 } }
5197
5198 #define MAKE_RGB_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5199  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB, depth, pstride, plane, offs, sub, pack } }
5200 #define MAKE_RGB_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5201  { 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 } }
5202 #define MAKE_RGBA_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5203  { 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 } }
5204 #define MAKE_RGBA_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5205  { 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 } }
5206 #define MAKE_RGBAP_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5207  { 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 } }
5208 #define MAKE_RGBA_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5209  { 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 } }
5210 #define MAKE_RGBA_LE_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5211  { 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 } }
5212
5213 #define MAKE_GRAY_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5214  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY, depth, pstride, plane, offs, sub, pack } }
5215 #define MAKE_GRAY_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5216  { 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 } }
5217 #define MAKE_GRAY_C_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
5218  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY | GST_VIDEO_FORMAT_FLAG_COMPLEX | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
5219
5220 static const VideoFormat formats[] = {
5221   {0x00000000, {GST_VIDEO_FORMAT_UNKNOWN, "UNKNOWN", "unknown video", 0, DPTH0,
5222           PSTR0, PLANE_NA, OFFS0}},
5223   {0x00000000, {GST_VIDEO_FORMAT_ENCODED, "ENCODED", "encoded video",
5224           GST_VIDEO_FORMAT_FLAG_COMPLEX, DPTH0, PSTR0, PLANE_NA, OFFS0}},
5225
5226   MAKE_YUV_FORMAT (I420, "raw video", GST_MAKE_FOURCC ('I', '4', '2', '0'),
5227       DPTH888, PSTR111, PLANE012, OFFS0, SUB420, PACK_420),
5228   MAKE_YUV_FORMAT (YV12, "raw video", GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
5229       DPTH888, PSTR111, PLANE021, OFFS0, SUB420, PACK_420),
5230   MAKE_YUV_FORMAT (YUY2, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
5231       DPTH888, PSTR244, PLANE0, OFFS013, SUB422, PACK_YUY2),
5232   MAKE_YUV_FORMAT (UYVY, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
5233       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_UYVY),
5234   MAKE_YUVA_PACK_FORMAT (AYUV, "raw video", GST_MAKE_FOURCC ('A', 'Y', 'U',
5235           'V'), DPTH8888, PSTR4444, PLANE0, OFFS1230, SUB4444, PACK_AYUV),
5236   MAKE_RGB_FORMAT (RGBx, "raw video", DPTH888, PSTR444, PLANE0, OFFS012,
5237       SUB444, PACK_RGBA),
5238   MAKE_RGB_FORMAT (BGRx, "raw video", DPTH888, PSTR444, PLANE0, OFFS210,
5239       SUB444, PACK_BGRA),
5240   MAKE_RGB_FORMAT (xRGB, "raw video", DPTH888, PSTR444, PLANE0, OFFS123,
5241       SUB444, PACK_ARGB),
5242   MAKE_RGB_FORMAT (xBGR, "raw video", DPTH888, PSTR444, PLANE0, OFFS321,
5243       SUB444, PACK_ABGR),
5244   MAKE_RGBA_FORMAT (RGBA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS0123,
5245       SUB4444, PACK_RGBA),
5246   MAKE_RGBA_FORMAT (BGRA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS2103,
5247       SUB4444, PACK_BGRA),
5248   MAKE_RGBA_PACK_FORMAT (ARGB, "raw video", DPTH8888, PSTR4444, PLANE0,
5249       OFFS1230, SUB4444, PACK_ARGB),
5250   MAKE_RGBA_FORMAT (ABGR, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS3210,
5251       SUB4444, PACK_ABGR),
5252   MAKE_RGB_FORMAT (RGB, "raw video", DPTH888, PSTR333, PLANE0, OFFS012, SUB444,
5253       PACK_RGB),
5254   MAKE_RGB_FORMAT (BGR, "raw video", DPTH888, PSTR333, PLANE0, OFFS210, SUB444,
5255       PACK_BGR),
5256
5257   MAKE_YUV_FORMAT (Y41B, "raw video", GST_MAKE_FOURCC ('Y', '4', '1', 'B'),
5258       DPTH888, PSTR111, PLANE012, OFFS0, SUB411, PACK_Y41B),
5259   MAKE_YUV_FORMAT (Y42B, "raw video", GST_MAKE_FOURCC ('Y', '4', '2', 'B'),
5260       DPTH888, PSTR111, PLANE012, OFFS0, SUB422, PACK_Y42B),
5261   MAKE_YUV_FORMAT (YVYU, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'),
5262       DPTH888, PSTR244, PLANE0, OFFS031, SUB422, PACK_YVYU),
5263   MAKE_YUV_FORMAT (Y444, "raw video", GST_MAKE_FOURCC ('Y', '4', '4', '4'),
5264       DPTH888, PSTR111, PLANE012, OFFS0, SUB444, PACK_Y444),
5265   MAKE_YUV_C_FORMAT (v210, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '0'),
5266       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_v210),
5267   MAKE_YUV_FORMAT (v216, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '6'),
5268       DPTH16_16_16, PSTR488, PLANE0, OFFS204, SUB422, PACK_v216),
5269   MAKE_YUV_FORMAT (NV12, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '2'),
5270       DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12),
5271   MAKE_YUV_FORMAT (NV21, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '1'),
5272       DPTH888, PSTR122, PLANE011, OFFS010, SUB420, PACK_NV21),
5273
5274   MAKE_GRAY_FORMAT (GRAY8, "raw video", DPTH8, PSTR1, PLANE0, OFFS0, SUB4,
5275       PACK_GRAY8),
5276   MAKE_GRAY_FORMAT (GRAY16_BE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0, SUB4,
5277       PACK_GRAY16_BE),
5278   MAKE_GRAY_LE_FORMAT (GRAY16_LE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0,
5279       SUB4, PACK_GRAY16_LE),
5280
5281   MAKE_YUV_FORMAT (v308, "raw video", GST_MAKE_FOURCC ('v', '3', '0', '8'),
5282       DPTH888, PSTR333, PLANE0, OFFS012, SUB444, PACK_v308),
5283
5284 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
5285   MAKE_RGB_LE_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
5286       SUB444, PACK_RGB16),
5287   MAKE_RGB_LE_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
5288       SUB444, PACK_BGR16),
5289   MAKE_RGB_LE_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
5290       SUB444, PACK_RGB15),
5291   MAKE_RGB_LE_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
5292       SUB444, PACK_BGR15),
5293 #else
5294   MAKE_RGB_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
5295       PACK_RGB16),
5296   MAKE_RGB_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
5297       PACK_BGR16),
5298   MAKE_RGB_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
5299       PACK_RGB15),
5300   MAKE_RGB_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
5301       PACK_BGR15),
5302 #endif
5303
5304   MAKE_YUV_C_FORMAT (UYVP, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'),
5305       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_UYVP),
5306   MAKE_YUVA_FORMAT (A420, "raw video", GST_MAKE_FOURCC ('A', '4', '2', '0'),
5307       DPTH8888, PSTR1111, PLANE0123, OFFS0, SUB4204, PACK_A420),
5308   MAKE_RGBAP_FORMAT (RGB8P, "raw video", DPTH8_32, PSTR14, PLANE01,
5309       OFFS0, SUB44, PACK_RGB8P),
5310   MAKE_YUV_FORMAT (YUV9, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'V', '9'),
5311       DPTH888, PSTR111, PLANE012, OFFS0, SUB410, PACK_410),
5312   MAKE_YUV_FORMAT (YVU9, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'U', '9'),
5313       DPTH888, PSTR111, PLANE021, OFFS0, SUB410, PACK_410),
5314   MAKE_YUV_FORMAT (IYU1, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '1'),
5315       DPTH888, PSTR0, PLANE0, OFFS104, SUB411, PACK_IYU1),
5316 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
5317   MAKE_RGBA_LE_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888,
5318       PLANE0,
5319       OFFS2460, SUB444, PACK_ARGB64),
5320   MAKE_YUVA_LE_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
5321       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
5322 #else
5323   MAKE_RGBA_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
5324       OFFS2460, SUB444, PACK_ARGB64),
5325   MAKE_YUVA_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
5326       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
5327 #endif
5328   MAKE_RGB_FORMAT (r210, "raw video", DPTH10_10_10, PSTR444, PLANE0, OFFS0,
5329       SUB444, PACK_r210),
5330   MAKE_YUV_FORMAT (I420_10BE, "raw video", 0x00000000, DPTH10_10_10,
5331       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10BE),
5332   MAKE_YUV_LE_FORMAT (I420_10LE, "raw video", 0x00000000, DPTH10_10_10,
5333       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10LE),
5334   MAKE_YUV_FORMAT (I422_10BE, "raw video", 0x00000000, DPTH10_10_10,
5335       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10BE),
5336   MAKE_YUV_LE_FORMAT (I422_10LE, "raw video", 0x00000000, DPTH10_10_10,
5337       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10LE),
5338   MAKE_YUV_FORMAT (Y444_10BE, "raw video", 0x00000000, DPTH10_10_10,
5339       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10BE),
5340   MAKE_YUV_LE_FORMAT (Y444_10LE, "raw video", 0x00000000, DPTH10_10_10,
5341       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10LE),
5342   MAKE_RGB_FORMAT (GBR, "raw video", DPTH888, PSTR111, PLANE201, OFFS0, SUB444,
5343       PACK_GBR),
5344   MAKE_RGB_FORMAT (GBR_10BE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
5345       OFFS0, SUB444, PACK_GBR_10BE),
5346   MAKE_RGB_LE_FORMAT (GBR_10LE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
5347       OFFS0, SUB444, PACK_GBR_10LE),
5348   MAKE_YUV_FORMAT (NV16, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '6'),
5349       DPTH888, PSTR122, PLANE011, OFFS001, SUB422, PACK_NV16),
5350   MAKE_YUV_FORMAT (NV24, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '4'),
5351       DPTH888, PSTR122, PLANE011, OFFS001, SUB444, PACK_NV24),
5352   MAKE_YUV_T_FORMAT (NV12_64Z32, "raw video",
5353       GST_MAKE_FOURCC ('T', 'M', '1', '2'), DPTH8880, PSTR122, PLANE011,
5354       OFFS001, SUB420, PACK_NV12_64Z32, TILE_64x32 (ZFLIPZ_2X2)),
5355   MAKE_YUVA_FORMAT (A420_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
5356       PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_10BE),
5357   MAKE_YUVA_LE_FORMAT (A420_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
5358       PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_10LE),
5359   MAKE_YUVA_FORMAT (A422_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
5360       PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_10BE),
5361   MAKE_YUVA_LE_FORMAT (A422_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
5362       PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_10LE),
5363   MAKE_YUVA_FORMAT (A444_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
5364       PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_10BE),
5365   MAKE_YUVA_LE_FORMAT (A444_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
5366       PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_10LE),
5367   MAKE_YUV_FORMAT (NV61, "raw video", GST_MAKE_FOURCC ('N', 'V', '6', '1'),
5368       DPTH888, PSTR122, PLANE011, OFFS010, SUB422, PACK_NV61),
5369   MAKE_YUV_FORMAT (P010_10BE, "raw video", 0x00000000, DPTH10_10_10_HI,
5370       PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10BE),
5371   MAKE_YUV_LE_FORMAT (P010_10LE, "raw video", 0x00000000, DPTH10_10_10_HI,
5372       PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10LE),
5373   MAKE_YUV_FORMAT (IYU2, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '2'),
5374       DPTH888, PSTR333, PLANE0, OFFS102, SUB444, PACK_IYU2),
5375   MAKE_YUV_FORMAT (VYUY, "raw video", GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y'),
5376       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_VYUY),
5377   MAKE_RGBA_FORMAT (GBRA, "raw video", DPTH8888, PSTR1111, PLANE2013,
5378       OFFS0, SUB4444, PACK_GBRA),
5379   MAKE_RGBA_FORMAT (GBRA_10BE, "raw video", DPTH10_10_10_10, PSTR222, PLANE2013,
5380       OFFS0, SUB4444, PACK_GBRA_10BE),
5381   MAKE_RGBA_LE_FORMAT (GBRA_10LE, "raw video", DPTH10_10_10_10, PSTR222,
5382       PLANE2013,
5383       OFFS0, SUB4444, PACK_GBRA_10LE),
5384   MAKE_RGB_FORMAT (GBR_12BE, "raw video", DPTH12_12_12, PSTR222, PLANE201,
5385       OFFS0, SUB444, PACK_GBR_12BE),
5386   MAKE_RGB_LE_FORMAT (GBR_12LE, "raw video", DPTH12_12_12, PSTR222, PLANE201,
5387       OFFS0, SUB444, PACK_GBR_12LE),
5388   MAKE_RGBA_FORMAT (GBRA_12BE, "raw video", DPTH12_12_12_12, PSTR222, PLANE2013,
5389       OFFS0, SUB4444, PACK_GBRA_12BE),
5390   MAKE_RGBA_LE_PACK_FORMAT (GBRA_12LE, "raw video", DPTH12_12_12_12, PSTR222,
5391       PLANE2013, OFFS0, SUB4444, PACK_GBRA_12LE),
5392   MAKE_YUV_FORMAT (I420_12BE, "raw video", 0x00000000, DPTH12_12_12,
5393       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_12BE),
5394   MAKE_YUV_LE_FORMAT (I420_12LE, "raw video", 0x00000000, DPTH12_12_12,
5395       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_12LE),
5396   MAKE_YUV_FORMAT (I422_12BE, "raw video", 0x00000000, DPTH12_12_12,
5397       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_12BE),
5398   MAKE_YUV_LE_FORMAT (I422_12LE, "raw video", 0x00000000, DPTH12_12_12,
5399       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_12LE),
5400   MAKE_YUV_FORMAT (Y444_12BE, "raw video", 0x00000000, DPTH12_12_12,
5401       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_12BE),
5402   MAKE_YUV_LE_FORMAT (Y444_12LE, "raw video", 0x00000000, DPTH12_12_12,
5403       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_12LE),
5404   MAKE_GRAY_C_LE_FORMAT (GRAY10_LE32, "raw video", DPTH10, PSTR0, PLANE0, OFFS0,
5405       SUB4, PACK_GRAY10_LE32),
5406   MAKE_YUV_C_LE_FORMAT (NV12_10LE32, "raw video",
5407       GST_MAKE_FOURCC ('X', 'V', '1', '5'), DPTH10_10_10, PSTR0, PLANE011,
5408       OFFS001, SUB420, PACK_NV12_10LE32),
5409   MAKE_YUV_C_LE_FORMAT (NV16_10LE32, "raw video",
5410       GST_MAKE_FOURCC ('X', 'V', '2', '0'), DPTH10_10_10, PSTR0, PLANE011,
5411       OFFS001, SUB422, PACK_NV16_10LE32),
5412   MAKE_YUV_C_LE_FORMAT (NV12_10LE40, "raw video",
5413       GST_MAKE_FOURCC ('R', 'K', '2', '0'), DPTH10_10_10, PSTR0, PLANE011,
5414       OFFS0, SUB420, PACK_NV12_10LE40),
5415 };
5416
5417 static GstVideoFormat
5418 gst_video_format_from_rgb32_masks (int red_mask, int green_mask, int blue_mask)
5419 {
5420   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
5421       blue_mask == 0x0000ff00) {
5422     return GST_VIDEO_FORMAT_RGBx;
5423   }
5424   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
5425       blue_mask == 0xff000000) {
5426     return GST_VIDEO_FORMAT_BGRx;
5427   }
5428   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
5429       blue_mask == 0x000000ff) {
5430     return GST_VIDEO_FORMAT_xRGB;
5431   }
5432   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
5433       blue_mask == 0x00ff0000) {
5434     return GST_VIDEO_FORMAT_xBGR;
5435   }
5436
5437   return GST_VIDEO_FORMAT_UNKNOWN;
5438 }
5439
5440 static GstVideoFormat
5441 gst_video_format_from_rgba32_masks (int red_mask, int green_mask,
5442     int blue_mask, int alpha_mask)
5443 {
5444   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
5445       blue_mask == 0x0000ff00 && alpha_mask == 0x000000ff) {
5446     return GST_VIDEO_FORMAT_RGBA;
5447   }
5448   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
5449       blue_mask == 0xff000000 && alpha_mask == 0x000000ff) {
5450     return GST_VIDEO_FORMAT_BGRA;
5451   }
5452   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
5453       blue_mask == 0x000000ff && alpha_mask == 0xff000000) {
5454     return GST_VIDEO_FORMAT_ARGB;
5455   }
5456   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
5457       blue_mask == 0x00ff0000 && alpha_mask == 0xff000000) {
5458     return GST_VIDEO_FORMAT_ABGR;
5459   }
5460   return GST_VIDEO_FORMAT_UNKNOWN;
5461 }
5462
5463 static GstVideoFormat
5464 gst_video_format_from_rgb24_masks (int red_mask, int green_mask, int blue_mask)
5465 {
5466   if (red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff) {
5467     return GST_VIDEO_FORMAT_RGB;
5468   }
5469   if (red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000) {
5470     return GST_VIDEO_FORMAT_BGR;
5471   }
5472
5473   return GST_VIDEO_FORMAT_UNKNOWN;
5474 }
5475
5476 #define GST_VIDEO_COMP1_MASK_16_INT 0xf800
5477 #define GST_VIDEO_COMP2_MASK_16_INT 0x07e0
5478 #define GST_VIDEO_COMP3_MASK_16_INT 0x001f
5479
5480 #define GST_VIDEO_COMP1_MASK_15_INT 0x7c00
5481 #define GST_VIDEO_COMP2_MASK_15_INT 0x03e0
5482 #define GST_VIDEO_COMP3_MASK_15_INT 0x001f
5483
5484 static GstVideoFormat
5485 gst_video_format_from_rgb16_masks (int red_mask, int green_mask, int blue_mask)
5486 {
5487   if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
5488       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
5489       && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
5490     return GST_VIDEO_FORMAT_RGB16;
5491   }
5492   if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
5493       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
5494       && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
5495     return GST_VIDEO_FORMAT_BGR16;
5496   }
5497   if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
5498       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
5499       && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
5500     return GST_VIDEO_FORMAT_RGB15;
5501   }
5502   if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
5503       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
5504       && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
5505     return GST_VIDEO_FORMAT_BGR15;
5506   }
5507   return GST_VIDEO_FORMAT_UNKNOWN;
5508 }
5509
5510 /**
5511  * gst_video_format_from_masks:
5512  * @depth: the amount of bits used for a pixel
5513  * @bpp: the amount of bits used to store a pixel. This value is bigger than
5514  *   @depth
5515  * @endianness: the endianness of the masks, #G_LITTLE_ENDIAN or #G_BIG_ENDIAN
5516  * @red_mask: the red mask
5517  * @green_mask: the green mask
5518  * @blue_mask: the blue mask
5519  * @alpha_mask: the alpha mask, or 0 if no alpha mask
5520  *
5521  * Find the #GstVideoFormat for the given parameters.
5522  *
5523  * Returns: a #GstVideoFormat or GST_VIDEO_FORMAT_UNKNOWN when the parameters to
5524  * not specify a known format.
5525  */
5526 GstVideoFormat
5527 gst_video_format_from_masks (gint depth, gint bpp, gint endianness,
5528     guint red_mask, guint green_mask, guint blue_mask, guint alpha_mask)
5529 {
5530   GstVideoFormat format;
5531
5532   /* our caps system handles 24/32bpp RGB as big-endian. */
5533   if ((bpp == 24 || bpp == 32) && endianness == G_LITTLE_ENDIAN) {
5534     red_mask = GUINT32_TO_BE (red_mask);
5535     green_mask = GUINT32_TO_BE (green_mask);
5536     blue_mask = GUINT32_TO_BE (blue_mask);
5537     alpha_mask = GUINT32_TO_BE (alpha_mask);
5538     endianness = G_BIG_ENDIAN;
5539     if (bpp == 24) {
5540       red_mask >>= 8;
5541       green_mask >>= 8;
5542       blue_mask >>= 8;
5543     }
5544   }
5545
5546   if (depth == 30 && bpp == 32) {
5547     format = GST_VIDEO_FORMAT_r210;
5548   } else if (depth == 24 && bpp == 32) {
5549     format = gst_video_format_from_rgb32_masks (red_mask, green_mask,
5550         blue_mask);
5551   } else if (depth == 32 && bpp == 32 && alpha_mask) {
5552     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
5553         blue_mask, alpha_mask);
5554   } else if (depth == 24 && bpp == 24) {
5555     format = gst_video_format_from_rgb24_masks (red_mask, green_mask,
5556         blue_mask);
5557   } else if ((depth == 15 || depth == 16) && bpp == 16 &&
5558       endianness == G_BYTE_ORDER) {
5559     format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
5560         blue_mask);
5561   } else if (depth == 8 && bpp == 8) {
5562     format = GST_VIDEO_FORMAT_RGB8P;
5563   } else if (depth == 64 && bpp == 64) {
5564     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
5565         blue_mask, alpha_mask);
5566     if (format == GST_VIDEO_FORMAT_ARGB) {
5567       format = GST_VIDEO_FORMAT_ARGB64;
5568     } else {
5569       format = GST_VIDEO_FORMAT_UNKNOWN;
5570     }
5571   } else {
5572     format = GST_VIDEO_FORMAT_UNKNOWN;
5573   }
5574   return format;
5575 }
5576
5577 /**
5578  * gst_video_format_from_fourcc:
5579  * @fourcc: a FOURCC value representing raw YUV video
5580  *
5581  * Converts a FOURCC value into the corresponding #GstVideoFormat.
5582  * If the FOURCC cannot be represented by #GstVideoFormat,
5583  * #GST_VIDEO_FORMAT_UNKNOWN is returned.
5584  *
5585  * Returns: the #GstVideoFormat describing the FOURCC value
5586  */
5587 GstVideoFormat
5588 gst_video_format_from_fourcc (guint32 fourcc)
5589 {
5590   switch (fourcc) {
5591     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5592       return GST_VIDEO_FORMAT_I420;
5593     case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5594       return GST_VIDEO_FORMAT_YV12;
5595     case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5596       return GST_VIDEO_FORMAT_YUY2;
5597     case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
5598       return GST_VIDEO_FORMAT_YVYU;
5599     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5600       return GST_VIDEO_FORMAT_UYVY;
5601     case GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y'):
5602       return GST_VIDEO_FORMAT_VYUY;
5603     case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5604       return GST_VIDEO_FORMAT_AYUV;
5605     case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
5606       return GST_VIDEO_FORMAT_Y41B;
5607     case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
5608       return GST_VIDEO_FORMAT_Y42B;
5609     case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
5610       return GST_VIDEO_FORMAT_Y444;
5611     case GST_MAKE_FOURCC ('v', '2', '1', '0'):
5612       return GST_VIDEO_FORMAT_v210;
5613     case GST_MAKE_FOURCC ('v', '2', '1', '6'):
5614       return GST_VIDEO_FORMAT_v216;
5615     case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
5616       return GST_VIDEO_FORMAT_NV12;
5617     case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
5618       return GST_VIDEO_FORMAT_NV21;
5619     case GST_MAKE_FOURCC ('N', 'V', '1', '6'):
5620       return GST_VIDEO_FORMAT_NV16;
5621     case GST_MAKE_FOURCC ('N', 'V', '6', '1'):
5622       return GST_VIDEO_FORMAT_NV61;
5623     case GST_MAKE_FOURCC ('N', 'V', '2', '4'):
5624       return GST_VIDEO_FORMAT_NV24;
5625     case GST_MAKE_FOURCC ('v', '3', '0', '8'):
5626       return GST_VIDEO_FORMAT_v308;
5627     case GST_MAKE_FOURCC ('I', 'Y', 'U', '2'):
5628       return GST_VIDEO_FORMAT_IYU2;
5629     case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5630     case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5631     case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
5632       return GST_VIDEO_FORMAT_GRAY8;
5633     case GST_MAKE_FOURCC ('Y', '1', '6', ' '):
5634       return GST_VIDEO_FORMAT_GRAY16_LE;
5635     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'):
5636       return GST_VIDEO_FORMAT_UYVP;
5637     case GST_MAKE_FOURCC ('A', '4', '2', '0'):
5638       return GST_VIDEO_FORMAT_A420;
5639     case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
5640       return GST_VIDEO_FORMAT_YUV9;
5641     case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
5642       return GST_VIDEO_FORMAT_YVU9;
5643     case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
5644       return GST_VIDEO_FORMAT_IYU1;
5645     case GST_MAKE_FOURCC ('A', 'Y', '6', '4'):
5646       return GST_VIDEO_FORMAT_AYUV64;
5647     case GST_MAKE_FOURCC ('X', 'V', '1', '0'):
5648       return GST_VIDEO_FORMAT_GRAY10_LE32;
5649     case GST_MAKE_FOURCC ('X', 'V', '1', '5'):
5650       return GST_VIDEO_FORMAT_NV12_10LE32;
5651     case GST_MAKE_FOURCC ('X', 'V', '2', '0'):
5652       return GST_VIDEO_FORMAT_NV16_10LE32;
5653     case GST_MAKE_FOURCC ('R', 'K', '2', '0'):
5654       return GST_VIDEO_FORMAT_NV12_10LE40;
5655     default:
5656       return GST_VIDEO_FORMAT_UNKNOWN;
5657   }
5658 }
5659
5660 /**
5661  * gst_video_format_from_string:
5662  * @format: a format string
5663  *
5664  * Convert the @format string to its #GstVideoFormat.
5665  *
5666  * Returns: the #GstVideoFormat for @format or GST_VIDEO_FORMAT_UNKNOWN when the
5667  * string is not a known format.
5668  */
5669 GstVideoFormat
5670 gst_video_format_from_string (const gchar * format)
5671 {
5672   guint i;
5673
5674   g_return_val_if_fail (format != NULL, GST_VIDEO_FORMAT_UNKNOWN);
5675
5676   for (i = 0; i < G_N_ELEMENTS (formats); i++) {
5677     if (strcmp (GST_VIDEO_FORMAT_INFO_NAME (&formats[i].info), format) == 0)
5678       return GST_VIDEO_FORMAT_INFO_FORMAT (&formats[i].info);
5679   }
5680   return GST_VIDEO_FORMAT_UNKNOWN;
5681 }
5682
5683
5684 /**
5685  * gst_video_format_to_fourcc:
5686  * @format: a #GstVideoFormat video format
5687  *
5688  * Converts a #GstVideoFormat value into the corresponding FOURCC.  Only
5689  * a few YUV formats have corresponding FOURCC values.  If @format has
5690  * no corresponding FOURCC value, 0 is returned.
5691  *
5692  * Returns: the FOURCC corresponding to @format
5693  */
5694 guint32
5695 gst_video_format_to_fourcc (GstVideoFormat format)
5696 {
5697   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
5698
5699   if ((gint) format >= G_N_ELEMENTS (formats))
5700     return 0;
5701
5702   return formats[format].fourcc;
5703 }
5704
5705 /**
5706  * gst_video_format_to_string:
5707  * @format: a #GstVideoFormat video format
5708  *
5709  * Returns a string containing a descriptive name for
5710  * the #GstVideoFormat if there is one, or NULL otherwise.
5711  *
5712  * Returns: the name corresponding to @format
5713  */
5714 const gchar *
5715 gst_video_format_to_string (GstVideoFormat format)
5716 {
5717   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
5718
5719   if ((gint) format >= G_N_ELEMENTS (formats))
5720     return NULL;
5721
5722   return GST_VIDEO_FORMAT_INFO_NAME (&formats[format].info);
5723 }
5724
5725 /**
5726  * gst_video_format_get_info:
5727  * @format: a #GstVideoFormat
5728  *
5729  * Get the #GstVideoFormatInfo for @format
5730  *
5731  * Returns: The #GstVideoFormatInfo for @format.
5732  */
5733 const GstVideoFormatInfo *
5734 gst_video_format_get_info (GstVideoFormat format)
5735 {
5736   g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
5737
5738   return &formats[format].info;
5739 }
5740
5741 /**
5742  * gst_video_format_get_palette:
5743  * @format: a #GstVideoFormat
5744  * @size: (out): size of the palette in bytes
5745  *
5746  * Get the default palette of @format. This the palette used in the pack
5747  * function for paletted formats.
5748  *
5749  * Returns: (transfer none): the default palette of @format or %NULL when
5750  * @format does not have a palette.
5751  *
5752  * Since: 1.2
5753  */
5754 gconstpointer
5755 gst_video_format_get_palette (GstVideoFormat format, gsize * size)
5756 {
5757   g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
5758   g_return_val_if_fail (size != NULL, NULL);
5759
5760   switch (format) {
5761     case GST_VIDEO_FORMAT_RGB8P:
5762       *size = sizeof (std_palette_RGB8P);
5763       return std_palette_RGB8P;
5764     default:
5765       return NULL;
5766   }
5767 }