• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
unpack_planar_420(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_planar_420(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_YUY2(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_YUY2(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_UYVY(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_UYVY(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_VYUY(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_VYUY(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_YVYU(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_YVYU(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_v308(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_v308(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_IYU2(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_IYU2(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_copy4(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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
pack_copy4(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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
unpack_v210(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)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   if (x != 0)
572     GST_FIXME ("Horizontal offsets are not supported for v210");
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
pack_v210(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)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; i += 6) {
665     y1 = y2 = y3 = y4 = y5 = 0;
666     u1 = u2 = v1 = v2 = 0;
667 
668     y0 = s[4 * (i + 0) + 1] >> 6;
669     u0 = s[4 * (i + 0) + 2] >> 6;
670     v0 = s[4 * (i + 0) + 3] >> 6;
671 
672     if (i < width - 1) {
673       y1 = s[4 * (i + 1) + 1] >> 6;
674     }
675     if (i < width - 2) {
676       y2 = s[4 * (i + 2) + 1] >> 6;
677       u1 = s[4 * (i + 2) + 2] >> 6;
678       v1 = s[4 * (i + 2) + 3] >> 6;
679     }
680     if (i < width - 3) {
681       y3 = s[4 * (i + 3) + 1] >> 6;
682     }
683     if (i < width - 4) {
684       y4 = s[4 * (i + 4) + 1] >> 6;
685       u2 = s[4 * (i + 4) + 2] >> 6;
686       v2 = s[4 * (i + 4) + 3] >> 6;
687     }
688     if (i < width - 5) {
689       y5 = s[4 * (i + 5) + 1] >> 6;
690     }
691 
692     a0 = u0 | (y0 << 10) | (v0 << 20);
693     a1 = y1 | (u1 << 10) | (y2 << 20);
694     a2 = v1 | (y3 << 10) | (u2 << 20);
695     a3 = y4 | (v2 << 10) | (y5 << 20);
696 
697     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 0, a0);
698     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 4, a1);
699     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 8, a2);
700     GST_WRITE_UINT32_LE (d + (i / 6) * 16 + 12, a3);
701   }
702 }
703 
704 #define PACK_v216 GST_VIDEO_FORMAT_AYUV64, unpack_v216, 1, pack_v216
705 static void
unpack_v216(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)706 unpack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
707     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
708     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
709 {
710   int i;
711   const guint8 *restrict s = GET_LINE (y);
712   guint16 *restrict d = dest;
713 
714   s += (x & ~1) << 2;
715   if (x & 1) {
716     d[0] = 0xffff;
717     d[1] = GST_READ_UINT16_LE (s + 6);
718     d[2] = GST_READ_UINT16_LE (s + 0);
719     d[3] = GST_READ_UINT16_LE (s + 4);
720     s += 8;
721     d += 4;
722     width--;
723   }
724 
725   for (i = 0; i < width; i++) {
726     d[i * 4 + 0] = 0xffff;
727     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i * 4 + 2);
728     d[i * 4 + 2] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 0);
729     d[i * 4 + 3] = GST_READ_UINT16_LE (s + (i >> 1) * 8 + 4);
730   }
731 }
732 
733 static void
pack_v216(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)734 pack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
735     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
736     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
737     gint y, gint width)
738 {
739   int i;
740   guint8 *restrict d = GET_LINE (y);
741   const guint16 *restrict s = src;
742 
743   for (i = 0; i < width - 1; i += 2) {
744     GST_WRITE_UINT16_LE (d + i * 4 + 0, s[(i + 0) * 4 + 2]);
745     GST_WRITE_UINT16_LE (d + i * 4 + 2, s[(i + 0) * 4 + 1]);
746     GST_WRITE_UINT16_LE (d + i * 4 + 4, s[(i + 0) * 4 + 3]);
747     GST_WRITE_UINT16_LE (d + i * 4 + 6, s[(i + 1) * 4 + 1]);
748   }
749   if (i == width - 1) {
750     GST_WRITE_UINT16_LE (d + i * 4 + 0, s[i * 4 + 2]);
751     GST_WRITE_UINT16_LE (d + i * 4 + 2, s[i * 4 + 1]);
752     GST_WRITE_UINT16_LE (d + i * 4 + 4, s[i * 4 + 3]);
753     GST_WRITE_UINT16_LE (d + i * 4 + 6, s[i * 4 + 1]);
754   }
755 }
756 
757 #define PACK_Y210 GST_VIDEO_FORMAT_AYUV64, unpack_Y210, 1, pack_Y210
758 static void
unpack_Y210(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)759 unpack_Y210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
760     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
761     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
762 {
763   int i;
764   const guint8 *restrict s = GET_LINE (y);
765   guint16 *restrict d = dest;
766   guint Y0, Y1, U, V;
767 
768   s += GST_ROUND_DOWN_2 (x) * 4;
769 
770   if (x & 1) {
771     Y1 = GST_READ_UINT16_LE (s + 4);
772     U = GST_READ_UINT16_LE (s + 2);
773     V = GST_READ_UINT16_LE (s + 6);
774 
775     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
776       Y1 |= (Y1 >> 10);
777       U |= (U >> 10);
778       V |= (V >> 10);
779     }
780 
781     d[0] = 0xffff;
782     d[1] = Y1;
783     d[2] = U;
784     d[3] = V;
785     s += 8;
786     d += 4;
787     width--;
788   }
789 
790   for (i = 0; i < width / 2; i++) {
791     Y0 = GST_READ_UINT16_LE (s + i * 8 + 0);
792     U = GST_READ_UINT16_LE (s + i * 8 + 2);
793     V = GST_READ_UINT16_LE (s + i * 8 + 6);
794     Y1 = GST_READ_UINT16_LE (s + i * 8 + 4);
795 
796     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
797       Y0 |= (Y0 >> 10);
798       U |= (U >> 10);
799       V |= (V >> 10);
800     }
801 
802     d[i * 8 + 0] = 0xffff;
803     d[i * 8 + 1] = Y0;
804     d[i * 8 + 2] = U;
805     d[i * 8 + 3] = V;
806 
807     d[i * 8 + 4] = 0xffff;
808     d[i * 8 + 5] = Y1;
809     d[i * 8 + 6] = U;
810     d[i * 8 + 7] = V;
811   }
812 
813   if (width & 1) {
814     i = width - 1;
815 
816     Y0 = GST_READ_UINT16_LE (s + i * 4 + 0);
817     U = GST_READ_UINT16_LE (s + i * 4 + 2);
818     V = GST_READ_UINT16_LE (s + i * 4 + 6);
819 
820     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
821       Y0 |= (Y0 >> 10);
822       U |= (U >> 10);
823       V |= (V >> 10);
824     }
825 
826     d[i * 4 + 0] = 0xffff;
827     d[i * 4 + 1] = Y0;
828     d[i * 4 + 2] = U;
829     d[i * 4 + 3] = V;
830   }
831 }
832 
833 static void
pack_Y210(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)834 pack_Y210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
835     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
836     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
837     gint y, gint width)
838 {
839   int i;
840   guint16 Y0, Y1, U, V;
841   guint8 *restrict d = GET_LINE (y);
842   const guint16 *restrict s = src;
843 
844   for (i = 0; i < width; i += 2) {
845     Y0 = s[i * 4 + 1] & 0xffc0;
846     U = s[i * 4 + 2] & 0xffc0;
847     V = s[i * 4 + 3] & 0xffc0;
848     if (i == width - 1)
849       Y1 = s[i * 4 + 1] & 0xffc0;
850     else
851       Y1 = s[(i + 1) * 4 + 1] & 0xffc0;
852 
853     GST_WRITE_UINT16_LE (d + i * 4 + 0, Y0);
854     GST_WRITE_UINT16_LE (d + i * 4 + 2, U);
855     GST_WRITE_UINT16_LE (d + i * 4 + 4, Y1);
856     GST_WRITE_UINT16_LE (d + i * 4 + 6, V);
857   }
858 }
859 
860 #define PACK_Y410 GST_VIDEO_FORMAT_AYUV64, unpack_Y410, 1, pack_Y410
861 static void
unpack_Y410(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)862 unpack_Y410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
863     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
864     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
865 {
866   int i;
867   const guint8 *restrict s = GET_LINE (y);
868   guint16 *restrict d = dest;
869   guint32 AVYU;
870   guint16 A, Y, U, V;
871 
872   s += x * 4;
873 
874   for (i = 0; i < width; i++) {
875     AVYU = GST_READ_UINT32_LE (s + 4 * i);
876 
877     U = ((AVYU >> 0) & 0x3ff) << 6;
878     Y = ((AVYU >> 10) & 0x3ff) << 6;
879     V = ((AVYU >> 20) & 0x3ff) << 6;
880     A = ((AVYU >> 30) & 0x03) << 14;
881 
882     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
883       U |= (U >> 10);
884       Y |= (Y >> 10);
885       V |= (V >> 10);
886       A |= (A >> 10);
887     }
888 
889     d[4 * i + 0] = A;
890     d[4 * i + 1] = Y;
891     d[4 * i + 2] = U;
892     d[4 * i + 3] = V;
893   }
894 }
895 
896 static void
pack_Y410(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)897 pack_Y410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
898     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
899     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
900     gint y, gint width)
901 {
902   int i;
903   guint32 *restrict d = GET_LINE (y);
904   const guint16 *restrict s = src;
905   guint32 AVYU;
906   guint16 A, Y, U, V;
907 
908   for (i = 0; i < width; i++) {
909     A = s[4 * i] & 0xc000;
910     Y = s[4 * i + 1] & 0xffc0;
911     U = s[4 * i + 2] & 0xffc0;
912     V = s[4 * i + 3] & 0xffc0;
913 
914     AVYU = (U >> 6) | (Y << 4) | (V << 14) | (A << 16);
915 
916     GST_WRITE_UINT32_LE (d + i, AVYU);
917   }
918 }
919 
920 #define PACK_Y41B GST_VIDEO_FORMAT_AYUV, unpack_Y41B, 1, pack_Y41B
921 static void
unpack_Y41B(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)922 unpack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
923     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
924     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
925 {
926   const guint8 *restrict sy = GET_Y_LINE (y);
927   const guint8 *restrict su = GET_U_LINE (y);
928   const guint8 *restrict sv = GET_V_LINE (y);
929   guint8 *restrict d = dest;
930 
931   sy += x;
932   su += x >> 2;
933   sv += x >> 2;
934 
935   if (x & 3) {
936     for (; x & 3; x++) {
937       d[0] = 0xff;
938       d[1] = *sy++;
939       d[2] = *su;
940       d[3] = *sv;
941       width--;
942       d += 4;
943     }
944     su++;
945     sy++;
946   }
947 
948   if (IS_ALIGNED (d, 8))
949     video_orc_unpack_YUV9 (d, sy, su, sv, width / 2);
950   else {
951     gint i;
952     for (i = 0; i < width / 2; i++) {
953       d[i * 8 + 0] = 0xff;
954       d[i * 8 + 1] = sy[i * 2 + 0];
955       d[i * 8 + 2] = su[i >> 1];
956       d[i * 8 + 3] = sv[i >> 1];
957       d[i * 8 + 4] = 0xff;
958       d[i * 8 + 5] = sy[i * 2 + 1];
959       d[i * 8 + 6] = su[i >> 1];
960       d[i * 8 + 7] = sv[i >> 1];
961     }
962   }
963 
964   if (width & 1) {
965     gint i = width - 1;
966 
967     d[i * 4 + 0] = 0xff;
968     d[i * 4 + 1] = sy[i];
969     d[i * 4 + 2] = su[i >> 2];
970     d[i * 4 + 3] = sv[i >> 2];
971   }
972 }
973 
974 static void
pack_Y41B(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)975 pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
976     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
977     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
978     gint y, gint width)
979 {
980   int i;
981   guint8 *restrict dy = GET_Y_LINE (y);
982   guint8 *restrict du = GET_U_LINE (y);
983   guint8 *restrict dv = GET_V_LINE (y);
984   const guint8 *restrict s = src;
985 
986   for (i = 0; i < width - 3; i += 4) {
987     dy[i] = s[i * 4 + 1];
988     dy[i + 1] = s[i * 4 + 5];
989     dy[i + 2] = s[i * 4 + 9];
990     dy[i + 3] = s[i * 4 + 13];
991 
992     du[i >> 2] = s[i * 4 + 2];
993     dv[i >> 2] = s[i * 4 + 3];
994   }
995   if (i < width) {
996     dy[i] = s[i * 4 + 1];
997     du[i >> 2] = s[i * 4 + 2];
998     dv[i >> 2] = s[i * 4 + 3];
999     if (i < width - 1)
1000       dy[i + 1] = s[i * 4 + 5];
1001     if (i < width - 2)
1002       dy[i + 2] = s[i * 4 + 9];
1003   }
1004 }
1005 
1006 #define PACK_Y42B GST_VIDEO_FORMAT_AYUV, unpack_Y42B, 1, pack_Y42B
1007 static void
unpack_Y42B(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1008 unpack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1009     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1010     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1011 {
1012   const guint8 *restrict sy = GET_Y_LINE (y);
1013   const guint8 *restrict su = GET_U_LINE (y);
1014   const guint8 *restrict sv = GET_V_LINE (y);
1015   guint8 *restrict d = dest;
1016 
1017   sy += x;
1018   su += x >> 1;
1019   sv += x >> 1;
1020 
1021   if (x & 1) {
1022     d[0] = 0xff;
1023     d[1] = *sy++;
1024     d[2] = *su++;
1025     d[3] = *sv++;
1026     width--;
1027     d += 4;
1028   }
1029 
1030   if (IS_ALIGNED (d, 8))
1031     video_orc_unpack_Y42B (d, sy, su, sv, width / 2);
1032   else {
1033     gint i;
1034     for (i = 0; i < width / 2; i++) {
1035       d[i * 8 + 0] = 0xff;
1036       d[i * 8 + 1] = sy[i * 2 + 0];
1037       d[i * 8 + 2] = su[i];
1038       d[i * 8 + 3] = sv[i];
1039       d[i * 8 + 4] = 0xff;
1040       d[i * 8 + 5] = sy[i * 2 + 1];
1041       d[i * 8 + 6] = su[i];
1042       d[i * 8 + 7] = sv[i];
1043     }
1044   }
1045 
1046   if (width & 1) {
1047     gint i = width - 1;
1048 
1049     d[i * 4 + 0] = 0xff;
1050     d[i * 4 + 1] = sy[i];
1051     d[i * 4 + 2] = su[i >> 1];
1052     d[i * 4 + 3] = sv[i >> 1];
1053   }
1054 }
1055 
1056 static void
pack_Y42B(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1057 pack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1058     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1059     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1060     gint y, gint width)
1061 {
1062   guint8 *restrict dy = GET_Y_LINE (y);
1063   guint8 *restrict du = GET_U_LINE (y);
1064   guint8 *restrict dv = GET_V_LINE (y);
1065   const guint8 *restrict s = src;
1066 
1067   if (IS_ALIGNED (s, 8))
1068     video_orc_pack_Y42B (dy, du, dv, s, width / 2);
1069   else {
1070     gint i;
1071     for (i = 0; i < width / 2; i++) {
1072       dy[i * 2 + 0] = s[i * 8 + 1];
1073       dy[i * 2 + 1] = s[i * 8 + 5];
1074       du[i] = s[i * 8 + 2];
1075       dv[i] = s[i * 8 + 3];
1076     }
1077   }
1078 
1079   if (width & 1) {
1080     gint i = width - 1;
1081 
1082     dy[i] = s[i * 4 + 1];
1083     du[i >> 1] = s[i * 4 + 2];
1084     dv[i >> 1] = s[i * 4 + 3];
1085   }
1086 }
1087 
1088 #define PACK_Y444 GST_VIDEO_FORMAT_AYUV, unpack_Y444, 1, pack_Y444
1089 static void
unpack_Y444(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1090 unpack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1091     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1092     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1093 {
1094   const guint8 *restrict sy = GET_Y_LINE (y);
1095   const guint8 *restrict su = GET_U_LINE (y);
1096   const guint8 *restrict sv = GET_V_LINE (y);
1097 
1098   sy += x;
1099   su += x;
1100   sv += x;
1101 
1102   video_orc_unpack_Y444 (dest, sy, su, sv, width);
1103 }
1104 
1105 static void
pack_Y444(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1106 pack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1107     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1108     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1109     gint y, gint width)
1110 {
1111   guint8 *restrict dy = GET_Y_LINE (y);
1112   guint8 *restrict du = GET_U_LINE (y);
1113   guint8 *restrict dv = GET_V_LINE (y);
1114 
1115   video_orc_pack_Y444 (dy, du, dv, src, width);
1116 }
1117 
1118 #define PACK_GBR GST_VIDEO_FORMAT_ARGB, unpack_GBR, 1, pack_GBR
1119 static void
unpack_GBR(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1120 unpack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1121     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1122     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1123 {
1124   const guint8 *restrict sr = GET_R_LINE (y);
1125   const guint8 *restrict sg = GET_G_LINE (y);
1126   const guint8 *restrict sb = GET_B_LINE (y);
1127 
1128   sr += x;
1129   sg += x;
1130   sb += x;
1131 
1132   video_orc_unpack_Y444 (dest, sr, sg, sb, width);
1133 }
1134 
1135 static void
pack_GBR(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1136 pack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1137     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1138     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1139     gint y, gint width)
1140 {
1141   guint8 *restrict dr = GET_R_LINE (y);
1142   guint8 *restrict dg = GET_G_LINE (y);
1143   guint8 *restrict db = GET_B_LINE (y);
1144 
1145   video_orc_pack_Y444 (dr, dg, db, src, width);
1146 }
1147 
1148 #define PACK_GBRA GST_VIDEO_FORMAT_ARGB, unpack_GBRA, 1, pack_GBRA
1149 static void
unpack_GBRA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1150 unpack_GBRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1151     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1152     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1153 {
1154   int i;
1155   const guint8 *sg = GET_G_LINE (y);
1156   const guint8 *sb = GET_B_LINE (y);
1157   const guint8 *sr = GET_R_LINE (y);
1158   const guint8 *sa = GET_A_LINE (y);
1159   guint8 *d = dest, G, B, R, A;
1160 
1161   sg += x;
1162   sb += x;
1163   sr += x;
1164   sa += x;
1165 
1166   for (i = 0; i < width; i++) {
1167     G = GST_READ_UINT8 (sg + i);
1168     B = GST_READ_UINT8 (sb + i);
1169     R = GST_READ_UINT8 (sr + i);
1170     A = GST_READ_UINT8 (sa + i);
1171 
1172     d[i * 4 + 0] = A;
1173     d[i * 4 + 1] = R;
1174     d[i * 4 + 2] = G;
1175     d[i * 4 + 3] = B;
1176   }
1177 }
1178 
1179 static void
pack_GBRA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1180 pack_GBRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1181     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1182     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1183     gint y, gint width)
1184 {
1185   int i;
1186   guint8 *restrict dg = GET_G_LINE (y);
1187   guint8 *restrict db = GET_B_LINE (y);
1188   guint8 *restrict dr = GET_R_LINE (y);
1189   guint8 *restrict da = GET_A_LINE (y);
1190   guint8 G, B, R, A;
1191   const guint8 *restrict s = src;
1192 
1193   for (i = 0; i < width; i++) {
1194     G = (s[i * 4 + 2]);
1195     B = (s[i * 4 + 3]);
1196     R = (s[i * 4 + 1]);
1197     A = (s[i * 4 + 0]);
1198 
1199     GST_WRITE_UINT8 (dg + i, G);
1200     GST_WRITE_UINT8 (db + i, B);
1201     GST_WRITE_UINT8 (dr + i, R);
1202     GST_WRITE_UINT8 (da + i, A);
1203   }
1204 }
1205 
1206 #define PACK_GRAY8 GST_VIDEO_FORMAT_AYUV, unpack_GRAY8, 1, pack_GRAY8
1207 static void
unpack_GRAY8(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1208 unpack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1209     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1210     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1211 {
1212   const guint8 *restrict s = GET_LINE (y);
1213 
1214   s += x;
1215 
1216   video_orc_unpack_GRAY8 (dest, s, width);
1217 }
1218 
1219 static void
pack_GRAY8(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1220 pack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1221     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1222     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1223     gint y, gint width)
1224 {
1225   guint8 *restrict d = GET_LINE (y);
1226 
1227   video_orc_pack_GRAY8 (d, src, width);
1228 }
1229 
1230 #define PACK_GRAY16_BE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_BE, 1, pack_GRAY16_BE
1231 static void
unpack_GRAY16_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1232 unpack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1233     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1234     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1235 {
1236   int i;
1237   const guint16 *restrict s = GET_LINE (y);
1238   guint16 *restrict d = dest;
1239 
1240   s += x;
1241 
1242   for (i = 0; i < width; i++) {
1243     d[i * 4 + 0] = 0xffff;
1244     d[i * 4 + 1] = GST_READ_UINT16_BE (s + i);
1245     d[i * 4 + 2] = 0x8000;
1246     d[i * 4 + 3] = 0x8000;
1247   }
1248 }
1249 
1250 static void
pack_GRAY16_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1251 pack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1252     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1253     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1254     gint y, gint width)
1255 {
1256   int i;
1257   guint16 *restrict d = GET_LINE (y);
1258   const guint16 *restrict s = src;
1259 
1260   for (i = 0; i < width; i++) {
1261     GST_WRITE_UINT16_BE (d + i, s[i * 4 + 1]);
1262   }
1263 }
1264 
1265 #define PACK_GRAY16_LE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_LE, 1, pack_GRAY16_LE
1266 static void
unpack_GRAY16_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1267 unpack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1268     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1269     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1270 {
1271   int i;
1272   const guint16 *restrict s = GET_LINE (y);
1273   guint16 *restrict d = dest;
1274 
1275   s += x;
1276 
1277   for (i = 0; i < width; i++) {
1278     d[i * 4 + 0] = 0xffff;
1279     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i);
1280     d[i * 4 + 2] = 0x8000;
1281     d[i * 4 + 3] = 0x8000;
1282   }
1283 }
1284 
1285 static void
pack_GRAY16_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1286 pack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1287     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1288     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1289     gint y, gint width)
1290 {
1291   int i;
1292   guint16 *restrict d = GET_LINE (y);
1293   const guint16 *restrict s = src;
1294 
1295   for (i = 0; i < width; i++) {
1296     GST_WRITE_UINT16_LE (d + i, s[i * 4 + 1]);
1297   }
1298 }
1299 
1300 #define PACK_RGB16 GST_VIDEO_FORMAT_ARGB, unpack_RGB16, 1, pack_RGB16
1301 static void
unpack_RGB16(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1302 unpack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1303     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1304     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1305 {
1306   const guint16 *restrict s = GET_LINE (y);
1307 
1308   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1309     video_orc_unpack_RGB16_trunc (dest, s + x, width);
1310   else
1311     video_orc_unpack_RGB16 (dest, s + x, width);
1312 }
1313 
1314 static void
pack_RGB16(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1315 pack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1316     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1317     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1318     gint y, gint width)
1319 {
1320   guint16 *restrict d = GET_LINE (y);
1321 
1322 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1323   video_orc_pack_RGB16_le (d, src, width);
1324 #else
1325   video_orc_pack_RGB16_be (d, src, width);
1326 #endif
1327 }
1328 
1329 #define PACK_BGR16 GST_VIDEO_FORMAT_ARGB, unpack_BGR16, 1, pack_BGR16
1330 static void
unpack_BGR16(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1331 unpack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1332     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1333     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1334 {
1335   const guint16 *restrict s = GET_LINE (y);
1336 
1337   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1338     video_orc_unpack_BGR16_trunc (dest, s + x, width);
1339   else
1340     video_orc_unpack_BGR16 (dest, s + x, width);
1341 }
1342 
1343 static void
pack_BGR16(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1344 pack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1345     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1346     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1347     gint y, gint width)
1348 {
1349   guint16 *restrict d = GET_LINE (y);
1350 
1351 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1352   video_orc_pack_BGR16_le (d, src, width);
1353 #else
1354   video_orc_pack_BGR16_be (d, src, width);
1355 #endif
1356 }
1357 
1358 #define PACK_RGB15 GST_VIDEO_FORMAT_ARGB, unpack_RGB15, 1, pack_RGB15
1359 static void
unpack_RGB15(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1360 unpack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1361     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1362     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1363 {
1364   const guint16 *restrict s = GET_LINE (y);
1365 
1366 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1367   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1368     video_orc_unpack_RGB15_le_trunc (dest, s + x, width);
1369   else
1370     video_orc_unpack_RGB15_le (dest, s + x, width);
1371 #else
1372   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1373     video_orc_unpack_RGB15_be_trunc (dest, s + x, width);
1374   else
1375     video_orc_unpack_RGB15_be (dest, s + x, width);
1376 #endif
1377 }
1378 
1379 static void
pack_RGB15(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1380 pack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1381     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1382     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1383     gint y, gint width)
1384 {
1385   guint16 *restrict d = GET_LINE (y);
1386 
1387 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1388   video_orc_pack_RGB15_le (d, src, width);
1389 #else
1390   video_orc_pack_RGB15_be (d, src, width);
1391 #endif
1392 }
1393 
1394 #define PACK_BGR15 GST_VIDEO_FORMAT_ARGB, unpack_BGR15, 1, pack_BGR15
1395 static void
unpack_BGR15(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1396 unpack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1397     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1398     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1399 {
1400   const guint16 *restrict s = GET_LINE (y);
1401 
1402 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1403   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1404     video_orc_unpack_BGR15_le_trunc (dest, s + x, width);
1405   else
1406     video_orc_unpack_BGR15_le (dest, s + x, width);
1407 #else
1408   if (flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)
1409     video_orc_unpack_BGR15_be_trunc (dest, s + x, width);
1410   else
1411     video_orc_unpack_BGR15_be (dest, s + x, width);
1412 #endif
1413 }
1414 
1415 static void
pack_BGR15(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1416 pack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1417     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1418     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1419     gint y, gint width)
1420 {
1421   guint16 *restrict d = GET_LINE (y);
1422 
1423 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1424   video_orc_pack_BGR15_le (d, src, width);
1425 #else
1426   video_orc_pack_BGR15_be (d, src, width);
1427 #endif
1428 }
1429 
1430 #define PACK_BGRA GST_VIDEO_FORMAT_ARGB, unpack_BGRA, 1, pack_BGRA
1431 static void
unpack_BGRA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1432 unpack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1433     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1434     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1435 {
1436   const guint8 *restrict s = GET_LINE (y);
1437 
1438   s += x * 4;
1439 
1440   video_orc_unpack_BGRA (dest, s, width);
1441 }
1442 
1443 static void
pack_BGRA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1444 pack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1445     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1446     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1447     gint y, gint width)
1448 {
1449   guint8 *restrict d = GET_LINE (y);
1450 
1451   video_orc_pack_BGRA (d, src, width);
1452 }
1453 
1454 #define PACK_ABGR GST_VIDEO_FORMAT_ARGB, unpack_ABGR, 1, pack_ABGR
1455 static void
unpack_ABGR(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1456 unpack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1457     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1458     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1459 {
1460   const guint8 *restrict s = GET_LINE (y);
1461 
1462   s += x * 4;
1463 
1464 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1465   video_orc_unpack_ABGR_le (dest, s, width);
1466 #else
1467   video_orc_unpack_ABGR_be (dest, s, width);
1468 #endif
1469 }
1470 
1471 static void
pack_ABGR(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1472 pack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1473     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1474     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1475     gint y, gint width)
1476 {
1477   guint8 *restrict d = GET_LINE (y);
1478 
1479 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1480   video_orc_pack_ABGR_le (d, src, width);
1481 #else
1482   video_orc_pack_ABGR_be (d, src, width);
1483 #endif
1484 }
1485 
1486 #define PACK_RGBA GST_VIDEO_FORMAT_ARGB, unpack_RGBA, 1, pack_RGBA
1487 static void
unpack_RGBA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1488 unpack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1489     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1490     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1491 {
1492   const guint8 *restrict s = GET_LINE (y);
1493 
1494   s += x * 4;
1495 
1496 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1497   video_orc_unpack_RGBA_le (dest, s, width);
1498 #else
1499   video_orc_unpack_RGBA_be (dest, s, width);
1500 #endif
1501 }
1502 
1503 static void
pack_RGBA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1504 pack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1505     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1506     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1507     gint y, gint width)
1508 {
1509   guint8 *restrict d = GET_LINE (y);
1510 
1511 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1512   video_orc_pack_RGBA_le (d, src, width);
1513 #else
1514   video_orc_pack_RGBA_be (d, src, width);
1515 #endif
1516 }
1517 
1518 #define PACK_RGB GST_VIDEO_FORMAT_ARGB, unpack_RGB, 1, pack_RGB
1519 static void
unpack_RGB(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1520 unpack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1521     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1522     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1523 {
1524   int i;
1525   const guint8 *restrict s = GET_LINE (y);
1526   guint8 *restrict d = dest;
1527 
1528   s += x * 3;
1529 
1530   for (i = 0; i < width; i++) {
1531     d[i * 4 + 0] = 0xff;
1532     d[i * 4 + 1] = s[i * 3 + 0];
1533     d[i * 4 + 2] = s[i * 3 + 1];
1534     d[i * 4 + 3] = s[i * 3 + 2];
1535   }
1536 }
1537 
1538 static void
pack_RGB(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1539 pack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1540     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1541     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1542     gint y, gint width)
1543 {
1544   int i;
1545   guint8 *restrict d = GET_LINE (y);
1546   const guint8 *restrict s = src;
1547 
1548   for (i = 0; i < width; i++) {
1549     d[i * 3 + 0] = s[i * 4 + 1];
1550     d[i * 3 + 1] = s[i * 4 + 2];
1551     d[i * 3 + 2] = s[i * 4 + 3];
1552   }
1553 }
1554 
1555 #define PACK_BGR GST_VIDEO_FORMAT_ARGB, unpack_BGR, 1, pack_BGR
1556 static void
unpack_BGR(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1557 unpack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1558     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1559     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1560 {
1561   int i;
1562   const guint8 *restrict s = GET_LINE (y);
1563   guint8 *restrict d = dest;
1564 
1565   s += x * 3;
1566 
1567   for (i = 0; i < width; i++) {
1568     d[i * 4 + 0] = 0xff;
1569     d[i * 4 + 1] = s[i * 3 + 2];
1570     d[i * 4 + 2] = s[i * 3 + 1];
1571     d[i * 4 + 3] = s[i * 3 + 0];
1572   }
1573 }
1574 
1575 static void
pack_BGR(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1576 pack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1577     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1578     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1579     gint y, gint width)
1580 {
1581   int i;
1582   guint8 *restrict d = GET_LINE (y);
1583   const guint8 *restrict s = src;
1584 
1585   for (i = 0; i < width; i++) {
1586     d[i * 3 + 0] = s[i * 4 + 3];
1587     d[i * 3 + 1] = s[i * 4 + 2];
1588     d[i * 3 + 2] = s[i * 4 + 1];
1589   }
1590 }
1591 
1592 #define PACK_NV12 GST_VIDEO_FORMAT_AYUV, unpack_NV12, 1, pack_NV12
1593 static void
unpack_NV12(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1594 unpack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1595     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1596     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1597 {
1598   gint uv = GET_UV_420 (y, flags);
1599   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1600   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
1601   guint8 *restrict d = dest;
1602 
1603   sy += x;
1604   suv += (x & ~1);
1605 
1606   if (x & 1) {
1607     d[0] = 0xff;
1608     d[1] = *sy++;
1609     d[2] = suv[0];
1610     d[3] = suv[1];
1611     width--;
1612     d += 4;
1613     suv += 2;
1614   }
1615 
1616   if (IS_ALIGNED (d, 8))
1617     video_orc_unpack_NV12 (d, sy, suv, width / 2);
1618   else {
1619     gint i;
1620     for (i = 0; i < width / 2; i++) {
1621       d[i * 8 + 0] = 0xff;
1622       d[i * 8 + 1] = sy[i * 2 + 0];
1623       d[i * 8 + 2] = suv[i * 2 + 0];
1624       d[i * 8 + 3] = suv[i * 2 + 1];
1625       d[i * 8 + 4] = 0xff;
1626       d[i * 8 + 5] = sy[i * 2 + 1];
1627       d[i * 8 + 6] = suv[i * 2 + 0];
1628       d[i * 8 + 7] = suv[i * 2 + 1];
1629     }
1630   }
1631 
1632   if (width & 1) {
1633     gint i = width - 1;
1634 
1635     d[i * 4 + 0] = 0xff;
1636     d[i * 4 + 1] = sy[i];
1637     d[i * 4 + 2] = suv[i + 0];
1638     d[i * 4 + 3] = suv[i + 1];
1639   }
1640 }
1641 
1642 static void
pack_NV12(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1643 pack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1644     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1645     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1646     gint y, gint width)
1647 {
1648   gint uv = GET_UV_420 (y, flags);
1649   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1650   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
1651   const guint8 *restrict s = src;
1652 
1653   if (IS_CHROMA_LINE_420 (y, flags)) {
1654     if (IS_ALIGNED (s, 8))
1655       video_orc_pack_NV12 (dy, duv, s, width / 2);
1656     else {
1657       gint i;
1658       for (i = 0; i < width / 2; i++) {
1659         dy[i * 2 + 0] = s[i * 8 + 1];
1660         dy[i * 2 + 1] = s[i * 8 + 5];
1661         duv[i * 2 + 0] = s[i * 8 + 2];
1662         duv[i * 2 + 1] = s[i * 8 + 3];
1663       }
1664     }
1665     if (width & 1) {
1666       gint i = width - 1;
1667 
1668       dy[i] = s[i * 4 + 1];
1669       duv[i + 0] = s[i * 4 + 2];
1670       duv[i + 1] = s[i * 4 + 3];
1671     }
1672   } else
1673     video_orc_pack_Y (dy, s, width);
1674 }
1675 
1676 #define PACK_NV21 GST_VIDEO_FORMAT_AYUV, unpack_NV21, 1, pack_NV21
1677 static void
unpack_NV21(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1678 unpack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1679     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1680     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1681 {
1682   gint uv = GET_UV_420 (y, flags);
1683   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1684   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
1685   guint8 *restrict d = dest;
1686 
1687   sy += x;
1688   suv += (x & ~1);
1689 
1690   if (x & 1) {
1691     d[0] = 0xff;
1692     d[1] = *sy++;
1693     d[2] = suv[1];
1694     d[3] = suv[0];
1695     width--;
1696     d += 4;
1697     suv += 2;
1698   }
1699 
1700   if (IS_ALIGNED (d, 8))
1701     video_orc_unpack_NV21 (d, sy, suv, width / 2);
1702   else {
1703     gint i;
1704     for (i = 0; i < width / 2; i++) {
1705       d[i * 8 + 0] = 0xff;
1706       d[i * 8 + 1] = sy[i * 2 + 0];
1707       d[i * 8 + 2] = suv[i * 2 + 1];
1708       d[i * 8 + 3] = suv[i * 2 + 0];
1709       d[i * 8 + 4] = 0xff;
1710       d[i * 8 + 5] = sy[i * 2 + 1];
1711       d[i * 8 + 6] = suv[i * 2 + 1];
1712       d[i * 8 + 7] = suv[i * 2 + 0];
1713     }
1714   }
1715 
1716   if (width & 1) {
1717     gint i = width - 1;
1718 
1719     d[i * 4 + 0] = 0xff;
1720     d[i * 4 + 1] = sy[i];
1721     d[i * 4 + 2] = suv[i + 1];
1722     d[i * 4 + 3] = suv[i + 0];
1723   }
1724 }
1725 
1726 #define PACK_AV12 GST_VIDEO_FORMAT_AYUV, unpack_AV12, 1, pack_AV12
1727 static void
unpack_AV12(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1728 unpack_AV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1729     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1730     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1731 {
1732   gint uv = GET_UV_420 (y, flags);
1733   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1734   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
1735   const guint8 *restrict sa = GET_PLANE_LINE (2, y);    /* a is for 'alpha' */
1736   guint8 *restrict d = dest;
1737 
1738   sy += x;
1739   sa += x;
1740   suv += (x & ~1);
1741 
1742   if (x & 1) {
1743     d[0] = *sa++;
1744     d[1] = *sy++;
1745     d[2] = suv[0];
1746     d[3] = suv[1];
1747     width--;
1748     d += 4;
1749     suv += 2;
1750   }
1751 
1752   if (IS_ALIGNED (d, 8)) {
1753     video_orc_unpack_AV12 (d, sy, suv, sa, width / 2);
1754   } else {
1755     gint i;
1756     for (i = 0; i < width / 2; i++) {
1757       d[i * 8 + 0] = sa[i * 2 + 0];
1758       d[i * 8 + 1] = sy[i * 2 + 0];
1759       d[i * 8 + 2] = suv[i * 2 + 0];
1760       d[i * 8 + 3] = suv[i * 2 + 1];
1761       d[i * 8 + 4] = sa[i * 2 + 1];
1762       d[i * 8 + 5] = sy[i * 2 + 1];
1763       d[i * 8 + 6] = suv[i * 2 + 0];
1764       d[i * 8 + 7] = suv[i * 2 + 1];
1765     }
1766   }
1767 
1768   if (width & 1) {
1769     gint i = width - 1;
1770 
1771     d[i * 4 + 0] = sa[i];
1772     d[i * 4 + 1] = sy[i];
1773     d[i * 4 + 2] = suv[i + 0];
1774     d[i * 4 + 3] = suv[i + 1];
1775   }
1776 }
1777 
1778 static void
pack_AV12(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1779 pack_AV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1780     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1781     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1782     gint y, gint width)
1783 {
1784   gint uv = GET_UV_420 (y, flags);
1785   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1786   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
1787   guint8 *restrict da = GET_PLANE_LINE (2, y);  /* a is for 'alpha' */
1788   const guint8 *restrict s = src;
1789 
1790   if (IS_CHROMA_LINE_420 (y, flags)) {
1791     if (IS_ALIGNED (s, 8)) {
1792       video_orc_pack_AV12 (dy, duv, da, s, width / 2);
1793     } else {
1794       gint i;
1795       for (i = 0; i < width / 2; i++) {
1796         /* AYUV_AYUV: alpha is on bytes 0 and 4 */
1797         da[i * 2 + 0] = s[i * 8 + 0];
1798         da[i * 2 + 1] = s[i * 8 + 4];
1799         dy[i * 2 + 0] = s[i * 8 + 1];
1800         dy[i * 2 + 1] = s[i * 8 + 5];
1801         duv[i * 2 + 0] = s[i * 8 + 2];
1802         duv[i * 2 + 1] = s[i * 8 + 3];
1803       }
1804     }
1805     if (width & 1) {
1806       gint i = width - 1;
1807 
1808       da[i] = s[i * 4 + 0];     /* AYUV: alpha is byte 0 */
1809       dy[i] = s[i * 4 + 1];
1810       duv[i + 0] = s[i * 4 + 2];
1811       duv[i + 1] = s[i * 4 + 3];
1812     }
1813   } else {
1814     video_orc_pack_YA (dy, da, s, width);
1815   }
1816 }
1817 
1818 static void
pack_NV21(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1819 pack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1820     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1821     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1822     gint y, gint width)
1823 {
1824   gint uv = GET_UV_420 (y, flags);
1825   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1826   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
1827   const guint8 *restrict s = src;
1828 
1829   if (IS_CHROMA_LINE_420 (y, flags)) {
1830     if (IS_ALIGNED (s, 8))
1831       video_orc_pack_NV21 (dy, duv, s, width / 2);
1832     else {
1833       gint i;
1834       for (i = 0; i < width / 2; i++) {
1835         dy[i * 2 + 0] = s[i * 8 + 1];
1836         dy[i * 2 + 1] = s[i * 8 + 5];
1837         duv[i * 2 + 0] = s[i * 8 + 3];
1838         duv[i * 2 + 1] = s[i * 8 + 2];
1839       }
1840     }
1841     if (width & 1) {
1842       gint i = width - 1;
1843 
1844       dy[i] = s[i * 4 + 1];
1845       duv[i + 0] = s[i * 4 + 3];
1846       duv[i + 1] = s[i * 4 + 2];
1847     }
1848   } else
1849     video_orc_pack_Y (dy, s, width);
1850 }
1851 
1852 #define PACK_NV16 GST_VIDEO_FORMAT_AYUV, unpack_NV16, 1, pack_NV16
1853 static void
unpack_NV16(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1854 unpack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1855     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1856     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1857 {
1858   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1859   const guint8 *restrict suv = GET_PLANE_LINE (1, y);
1860   guint8 *restrict d = dest;
1861 
1862   sy += x;
1863   suv += (x & ~1);
1864 
1865   if (x & 1) {
1866     d[0] = 0xff;
1867     d[1] = *sy++;
1868     d[2] = suv[0];
1869     d[3] = suv[1];
1870     width--;
1871     d += 4;
1872     suv += 2;
1873   }
1874 
1875   if (IS_ALIGNED (d, 8))
1876     video_orc_unpack_NV12 (d, sy, suv, width / 2);
1877   else {
1878     gint i;
1879     for (i = 0; i < width / 2; i++) {
1880       d[i * 8 + 0] = 0xff;
1881       d[i * 8 + 1] = sy[i * 2 + 0];
1882       d[i * 8 + 2] = suv[i * 2 + 0];
1883       d[i * 8 + 3] = suv[i * 2 + 1];
1884       d[i * 8 + 4] = 0xff;
1885       d[i * 8 + 5] = sy[i * 2 + 1];
1886       d[i * 8 + 6] = suv[i * 2 + 0];
1887       d[i * 8 + 7] = suv[i * 2 + 1];
1888     }
1889   }
1890 
1891   if (width & 1) {
1892     gint i = width - 1;
1893 
1894     d[i * 4 + 0] = 0xff;
1895     d[i * 4 + 1] = sy[i];
1896     d[i * 4 + 2] = suv[i + 0];
1897     d[i * 4 + 3] = suv[i + 1];
1898   }
1899 }
1900 
1901 static void
pack_NV16(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1902 pack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1903     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1904     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1905     gint y, gint width)
1906 {
1907   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1908   guint8 *restrict duv = GET_PLANE_LINE (1, y);
1909   const guint8 *restrict s = src;
1910 
1911   if (IS_ALIGNED (s, 8))
1912     video_orc_pack_NV12 (dy, duv, s, width / 2);
1913   else {
1914     gint i;
1915     for (i = 0; i < width / 2; i++) {
1916       dy[i * 2 + 0] = s[i * 8 + 1];
1917       dy[i * 2 + 1] = s[i * 8 + 5];
1918       duv[i * 2 + 0] = s[i * 8 + 2];
1919       duv[i * 2 + 1] = s[i * 8 + 3];
1920     }
1921   }
1922 
1923   if (width & 1) {
1924     gint i = width - 1;
1925 
1926     dy[i] = s[i * 4 + 1];
1927     duv[i + 0] = s[i * 4 + 2];
1928     duv[i + 1] = s[i * 4 + 3];
1929   }
1930 }
1931 
1932 #define PACK_NV61 GST_VIDEO_FORMAT_AYUV, unpack_NV61, 1, pack_NV61
1933 static void
unpack_NV61(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)1934 unpack_NV61 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1935     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
1936     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
1937 {
1938   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
1939   const guint8 *restrict svu = GET_PLANE_LINE (1, y);
1940   guint8 *restrict d = dest;
1941 
1942   sy += x;
1943   svu += (x & ~1);
1944 
1945   if (x & 1) {
1946     d[0] = 0xff;
1947     d[1] = *sy++;
1948     d[2] = svu[1];
1949     d[3] = svu[0];
1950     width--;
1951     d += 4;
1952     svu += 2;
1953   }
1954 
1955   if (IS_ALIGNED (d, 8)) {
1956     video_orc_unpack_NV21 (d, sy, svu, width / 2);
1957   } else {
1958     gint i;
1959 
1960     for (i = 0; i < width / 2; i++) {
1961       d[i * 8 + 0] = 0xff;
1962       d[i * 8 + 1] = sy[i * 2 + 0];
1963       d[i * 8 + 2] = svu[i * 2 + 1];
1964       d[i * 8 + 3] = svu[i * 2 + 0];
1965       d[i * 8 + 4] = 0xff;
1966       d[i * 8 + 5] = sy[i * 2 + 1];
1967       d[i * 8 + 6] = svu[i * 2 + 1];
1968       d[i * 8 + 7] = svu[i * 2 + 0];
1969     }
1970   }
1971 
1972   if (width & 1) {
1973     gint i = width - 1;
1974 
1975     d[i * 4 + 0] = 0xff;
1976     d[i * 4 + 1] = sy[i];
1977     d[i * 4 + 2] = svu[i + 1];
1978     d[i * 4 + 3] = svu[i + 0];
1979   }
1980 }
1981 
1982 static void
pack_NV61(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)1983 pack_NV61 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
1984     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
1985     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
1986     gint y, gint width)
1987 {
1988   const guint8 *restrict s = src;
1989   guint8 *restrict dy = GET_PLANE_LINE (0, y);
1990   guint8 *restrict dvu = GET_PLANE_LINE (1, y);
1991 
1992   if (IS_ALIGNED (s, 8)) {
1993     video_orc_pack_NV21 (dy, dvu, s, width / 2);
1994   } else {
1995     gint i;
1996 
1997     for (i = 0; i < width / 2; i++) {
1998       dy[i * 2 + 0] = s[i * 8 + 1];
1999       dy[i * 2 + 1] = s[i * 8 + 5];
2000       dvu[i * 2 + 0] = s[i * 8 + 3];
2001       dvu[i * 2 + 1] = s[i * 8 + 2];
2002     }
2003   }
2004 
2005   if (width & 1) {
2006     gint i = width - 1;
2007 
2008     dy[i] = s[i * 4 + 1];
2009     dvu[i + 0] = s[i * 4 + 2];
2010     dvu[i + 1] = s[i * 4 + 3];
2011   }
2012 }
2013 
2014 #define PACK_NV24 GST_VIDEO_FORMAT_AYUV, unpack_NV24, 1, pack_NV24
2015 static void
unpack_NV24(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2016 unpack_NV24 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2017     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2018     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2019 {
2020   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
2021   const guint8 *restrict suv = GET_PLANE_LINE (1, y);
2022 
2023   sy += x;
2024   suv += x << 1;
2025 
2026   video_orc_unpack_NV24 (dest, sy, suv, width);
2027 }
2028 
2029 static void
pack_NV24(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2030 pack_NV24 (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   guint8 *restrict dy = GET_PLANE_LINE (0, y);
2036   guint8 *restrict duv = GET_PLANE_LINE (1, y);
2037 
2038   video_orc_pack_NV24 (dy, duv, src, width);
2039 }
2040 
2041 #define PACK_UYVP GST_VIDEO_FORMAT_AYUV64, unpack_UYVP, 1, pack_UYVP
2042 static void
unpack_UYVP(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2043 unpack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2044     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2045     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2046 {
2047   int i;
2048   const guint8 *restrict s = GET_LINE (y);
2049   guint16 *restrict d = dest;
2050 
2051   /* FIXME */
2052   s += x << 1;
2053 
2054   for (i = 0; i < width; i += 2) {
2055     guint16 y0, y1;
2056     guint16 u0;
2057     guint16 v0;
2058 
2059     u0 = ((s[(i / 2) * 5 + 0] << 2) | (s[(i / 2) * 5 + 1] >> 6)) << 6;
2060     y0 = (((s[(i / 2) * 5 + 1] & 0x3f) << 4) | (s[(i / 2) * 5 + 2] >> 4)) << 6;
2061     v0 = (((s[(i / 2) * 5 + 2] & 0x0f) << 6) | (s[(i / 2) * 5 + 3] >> 2)) << 6;
2062     y1 = (((s[(i / 2) * 5 + 3] & 0x03) << 8) | s[(i / 2) * 5 + 4]) << 6;
2063 
2064     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2065       y0 |= (y0 >> 10);
2066       y1 |= (y1 >> 10);
2067       u0 |= (u0 >> 10);
2068       v0 |= (v0 >> 10);
2069     }
2070 
2071     d[i * 4 + 0] = 0xffff;
2072     d[i * 4 + 1] = y0;
2073     d[i * 4 + 2] = u0;
2074     d[i * 4 + 3] = v0;
2075 
2076     if (i < width - 1) {
2077       d[i * 4 + 4] = 0xffff;
2078       d[i * 4 + 5] = y1;
2079       d[i * 4 + 6] = u0;
2080       d[i * 4 + 7] = v0;
2081     }
2082   }
2083 }
2084 
2085 static void
pack_UYVP(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2086 pack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2087     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2088     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2089     gint y, gint width)
2090 {
2091   int i;
2092   guint8 *restrict d = GET_LINE (y);
2093   const guint16 *restrict s = src;
2094 
2095   for (i = 0; i < width; i += 2) {
2096     guint16 y0, y1;
2097     guint16 u0;
2098     guint16 v0;
2099 
2100     y0 = s[4 * (i + 0) + 1];
2101     if (i < width - 1)
2102       y1 = s[4 * (i + 1) + 1];
2103     else
2104       y1 = y0;
2105 
2106     u0 = s[4 * (i + 0) + 2];
2107     v0 = s[4 * (i + 0) + 3];
2108 
2109     d[(i / 2) * 5 + 0] = u0 >> 8;
2110     d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10;
2111     d[(i / 2) * 5 + 2] = ((y0 & 0x3c0) >> 2) | (v0 >> 12);
2112     d[(i / 2) * 5 + 3] = ((v0 & 0xfc0) >> 4) | (y1 >> 14);
2113     d[(i / 2) * 5 + 4] = (y1 >> 6);
2114   }
2115 }
2116 
2117 #define PACK_A420 GST_VIDEO_FORMAT_AYUV, unpack_A420, 1, pack_A420
2118 static void
unpack_A420(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2119 unpack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2120     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2121     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2122 {
2123   gint uv = GET_UV_420 (y, flags);
2124   const guint8 *restrict sy = GET_Y_LINE (y);
2125   const guint8 *restrict su = GET_U_LINE (uv);
2126   const guint8 *restrict sv = GET_V_LINE (uv);
2127   const guint8 *restrict sa = GET_A_LINE (y);
2128   guint8 *restrict d = dest;
2129 
2130   sy += x;
2131   su += x >> 1;
2132   sv += x >> 1;
2133   sa += x;
2134 
2135   if (x & 1) {
2136     d[0] = *sa++;
2137     d[1] = *sy++;
2138     d[2] = *su++;
2139     d[3] = *sv++;
2140     width--;
2141     d += 4;
2142   }
2143   video_orc_unpack_A420 (d, sy, su, sv, sa, width);
2144 }
2145 
2146 static void
pack_A420(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2147 pack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2148     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2149     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2150     gint y, gint width)
2151 {
2152   gint uv = GET_UV_420 (y, flags);
2153   guint8 *restrict dy = GET_Y_LINE (y);
2154   guint8 *restrict du = GET_U_LINE (uv);
2155   guint8 *restrict dv = GET_V_LINE (uv);
2156   guint8 *restrict da = GET_A_LINE (y);
2157   const guint8 *restrict s = src;
2158 
2159   if (IS_CHROMA_LINE_420 (y, flags)) {
2160     if (IS_ALIGNED (s, 8))
2161       video_orc_pack_A420 (dy, du, dv, da, s, width / 2);
2162     else {
2163       gint i;
2164       for (i = 0; i < width / 2; i++) {
2165         da[i * 2 + 0] = s[i * 8 + 0];
2166         dy[i * 2 + 0] = s[i * 8 + 1];
2167         da[i * 2 + 1] = s[i * 8 + 4];
2168         dy[i * 2 + 1] = s[i * 8 + 5];
2169         du[i] = s[i * 8 + 2];
2170         dv[i] = s[i * 8 + 3];
2171       }
2172     }
2173 
2174     if (width & 1) {
2175       gint i = width - 1;
2176 
2177       da[i] = s[i * 4 + 0];
2178       dy[i] = s[i * 4 + 1];
2179       du[i >> 1] = s[i * 4 + 2];
2180       dv[i >> 1] = s[i * 4 + 3];
2181     }
2182   } else
2183     video_orc_pack_AY (dy, da, s, width);
2184 }
2185 
2186 #define PACK_RGB8P GST_VIDEO_FORMAT_ARGB, unpack_RGB8P, 1, pack_RGB8P
2187 static void
unpack_RGB8P(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2188 unpack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2189     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2190     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2191 {
2192   int i;
2193   const guint8 *restrict s = GET_LINE (y);
2194   const guint32 *restrict p = data[1];
2195   guint8 *restrict d = dest;
2196 
2197   s += x;
2198 
2199   for (i = 0; i < width; i++) {
2200     guint32 v = p[s[i]];
2201     d[i * 4 + 0] = (v >> 24) & 0xff;
2202     d[i * 4 + 1] = (v >> 16) & 0xff;
2203     d[i * 4 + 2] = (v >> 8) & 0xff;
2204     d[i * 4 + 3] = (v) & 0xff;
2205   }
2206 }
2207 
2208 static const guint32 std_palette_RGB8P[] = {
2209   0xff000000, 0xff000033, 0xff000066, 0xff000099, 0xff0000cc, 0xff0000ff,
2210   0xff003300, 0xff003333, 0xff003366, 0xff003399, 0xff0033cc, 0xff0033ff,
2211   0xff006600, 0xff006633, 0xff006666, 0xff006699, 0xff0066cc, 0xff0066ff,
2212   0xff009900, 0xff009933, 0xff009966, 0xff009999, 0xff0099cc, 0xff0099ff,
2213   0xff00cc00, 0xff00cc33, 0xff00cc66, 0xff00cc99, 0xff00cccc, 0xff00ccff,
2214   0xff00ff00, 0xff00ff33, 0xff00ff66, 0xff00ff99, 0xff00ffcc, 0xff00ffff,
2215   0xff330000, 0xff330033, 0xff330066, 0xff330099, 0xff3300cc, 0xff3300ff,
2216   0xff333300, 0xff333333, 0xff333366, 0xff333399, 0xff3333cc, 0xff3333ff,
2217   0xff336600, 0xff336633, 0xff336666, 0xff336699, 0xff3366cc, 0xff3366ff,
2218   0xff339900, 0xff339933, 0xff339966, 0xff339999, 0xff3399cc, 0xff3399ff,
2219   0xff33cc00, 0xff33cc33, 0xff33cc66, 0xff33cc99, 0xff33cccc, 0xff33ccff,
2220   0xff33ff00, 0xff33ff33, 0xff33ff66, 0xff33ff99, 0xff33ffcc, 0xff33ffff,
2221   0xff660000, 0xff660033, 0xff660066, 0xff660099, 0xff6600cc, 0xff6600ff,
2222   0xff663300, 0xff663333, 0xff663366, 0xff663399, 0xff6633cc, 0xff6633ff,
2223   0xff666600, 0xff666633, 0xff666666, 0xff666699, 0xff6666cc, 0xff6666ff,
2224   0xff669900, 0xff669933, 0xff669966, 0xff669999, 0xff6699cc, 0xff6699ff,
2225   0xff66cc00, 0xff66cc33, 0xff66cc66, 0xff66cc99, 0xff66cccc, 0xff66ccff,
2226   0xff66ff00, 0xff66ff33, 0xff66ff66, 0xff66ff99, 0xff66ffcc, 0xff66ffff,
2227   0xff990000, 0xff990033, 0xff990066, 0xff990099, 0xff9900cc, 0xff9900ff,
2228   0xff993300, 0xff993333, 0xff993366, 0xff993399, 0xff9933cc, 0xff9933ff,
2229   0xff996600, 0xff996633, 0xff996666, 0xff996699, 0xff9966cc, 0xff9966ff,
2230   0xff999900, 0xff999933, 0xff999966, 0xff999999, 0xff9999cc, 0xff9999ff,
2231   0xff99cc00, 0xff99cc33, 0xff99cc66, 0xff99cc99, 0xff99cccc, 0xff99ccff,
2232   0xff99ff00, 0xff99ff33, 0xff99ff66, 0xff99ff99, 0xff99ffcc, 0xff99ffff,
2233   0xffcc0000, 0xffcc0033, 0xffcc0066, 0xffcc0099, 0xffcc00cc, 0xffcc00ff,
2234   0xffcc3300, 0xffcc3333, 0xffcc3366, 0xffcc3399, 0xffcc33cc, 0xffcc33ff,
2235   0xffcc6600, 0xffcc6633, 0xffcc6666, 0xffcc6699, 0xffcc66cc, 0xffcc66ff,
2236   0xffcc9900, 0xffcc9933, 0xffcc9966, 0xffcc9999, 0xffcc99cc, 0xffcc99ff,
2237   0xffcccc00, 0xffcccc33, 0xffcccc66, 0xffcccc99, 0xffcccccc, 0xffccccff,
2238   0xffccff00, 0xffccff33, 0xffccff66, 0xffccff99, 0xffccffcc, 0xffccffff,
2239   0xffff0000, 0xffff0033, 0xffff0066, 0xffff0099, 0xffff00cc, 0xffff00ff,
2240   0xffff3300, 0xffff3333, 0xffff3366, 0xffff3399, 0xffff33cc, 0xffff33ff,
2241   0xffff6600, 0xffff6633, 0xffff6666, 0xffff6699, 0xffff66cc, 0xffff66ff,
2242   0xffff9900, 0xffff9933, 0xffff9966, 0xffff9999, 0xffff99cc, 0xffff99ff,
2243   0xffffcc00, 0xffffcc33, 0xffffcc66, 0xffffcc99, 0xffffcccc, 0xffffccff,
2244   0xffffff00, 0xffffff33, 0xffffff66, 0xffffff99, 0xffffffcc, 0xffffffff,
2245   0x00000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2246   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2247   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2248   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2249   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2250   0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
2251   0xff000000, 0xff000000, 0xff000000, 0xff000000
2252 };
2253 
2254 static void
pack_RGB8P(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2255 pack_RGB8P (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   int i;
2261   guint8 *restrict d = GET_LINE (y);
2262   const guint8 *restrict s = src;
2263 
2264   /* Use our poor man's palette, taken from ffmpegcolorspace too */
2265   for (i = 0; i < width; i++) {
2266     /* crude approximation for alpha ! */
2267     if (s[i * 4 + 0] < 0x80)
2268       d[i] = 6 * 6 * 6;
2269     else
2270       d[i] =
2271           ((((s[i * 4 + 1]) / 47) % 6) * 6 * 6 + (((s[i * 4 +
2272                           2]) / 47) % 6) * 6 + (((s[i * 4 + 3]) / 47) % 6));
2273   }
2274 }
2275 
2276 #define PACK_410 GST_VIDEO_FORMAT_AYUV, unpack_410, 1, pack_410
2277 static void
unpack_410(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2278 unpack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2279     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2280     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2281 {
2282   gint uv = GET_UV_410 (y, flags);
2283   const guint8 *restrict sy = GET_Y_LINE (y);
2284   const guint8 *restrict su = GET_U_LINE (uv);
2285   const guint8 *restrict sv = GET_V_LINE (uv);
2286   guint8 *restrict d = dest;
2287 
2288   sy += x;
2289   su += x >> 2;
2290   sv += x >> 2;
2291 
2292   if (x & 3) {
2293     for (; x & 3; x++) {
2294       d[0] = 0xff;
2295       d[1] = *sy++;
2296       d[2] = *su;
2297       d[3] = *sv;
2298       width--;
2299       d += 4;
2300     }
2301     su++;
2302     sy++;
2303   }
2304 
2305   if (IS_ALIGNED (d, 8))
2306     video_orc_unpack_YUV9 (d, sy, su, sv, width / 2);
2307   else {
2308     gint i;
2309     for (i = 0; i < width / 2; i++) {
2310       d[i * 8 + 0] = 0xff;
2311       d[i * 8 + 1] = sy[i * 2 + 0];
2312       d[i * 8 + 2] = su[i >> 1];
2313       d[i * 8 + 3] = sv[i >> 1];
2314       d[i * 8 + 4] = 0xff;
2315       d[i * 8 + 5] = sy[i * 2 + 1];
2316       d[i * 8 + 6] = su[i >> 1];
2317       d[i * 8 + 7] = sv[i >> 1];
2318     }
2319   }
2320 
2321   if (width & 1) {
2322     gint i = width - 1;
2323 
2324     d[i * 4 + 0] = 0xff;
2325     d[i * 4 + 1] = sy[i];
2326     d[i * 4 + 2] = su[i >> 2];
2327     d[i * 4 + 3] = sv[i >> 2];
2328   }
2329 }
2330 
2331 static void
pack_410(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2332 pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2333     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2334     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2335     gint y, gint width)
2336 {
2337   int i;
2338   gint uv = GET_UV_410 (y, flags);
2339   guint8 *restrict dy = GET_Y_LINE (y);
2340   guint8 *restrict du = GET_U_LINE (uv);
2341   guint8 *restrict dv = GET_V_LINE (uv);
2342   const guint8 *restrict s = src;
2343 
2344   for (i = 0; i < width - 3; i += 4) {
2345     dy[i] = s[i * 4 + 1];
2346     dy[i + 1] = s[i * 4 + 5];
2347     dy[i + 2] = s[i * 4 + 9];
2348     dy[i + 3] = s[i * 4 + 13];
2349     if (IS_CHROMA_LINE_410 (y, flags)) {
2350       du[i >> 2] = s[i * 4 + 2];
2351       dv[i >> 2] = s[i * 4 + 3];
2352     }
2353   }
2354   if (i < width) {
2355     dy[i] = s[i * 4 + 1];
2356     if (IS_CHROMA_LINE_410 (y, flags)) {
2357       du[i >> 2] = s[i * 4 + 2];
2358       dv[i >> 2] = s[i * 4 + 3];
2359     }
2360     if (i < width - 1)
2361       dy[i + 1] = s[i * 4 + 5];
2362     if (i < width - 2)
2363       dy[i + 2] = s[i * 4 + 9];
2364   }
2365 }
2366 
2367 #define PACK_IYU1 GST_VIDEO_FORMAT_AYUV, unpack_IYU1, 1, pack_IYU1
2368 static void
unpack_IYU1(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2369 unpack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2370     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2371     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2372 {
2373   int i;
2374   const guint8 *restrict s = GET_LINE (y);
2375   guint8 *restrict d = dest;
2376   guint8 y0, y1, y2, y3;
2377   guint8 u0;
2378   guint8 v0;
2379 
2380   /* FIXME */
2381   s += x * 4;
2382 
2383   for (i = 0; i < width - 3; i += 4) {
2384     y0 = s[(i >> 2) * 6 + 1];
2385     y1 = s[(i >> 2) * 6 + 2];
2386     y2 = s[(i >> 2) * 6 + 4];
2387     y3 = s[(i >> 2) * 6 + 5];
2388 
2389     u0 = s[(i >> 2) * 6 + 0];
2390     v0 = s[(i >> 2) * 6 + 3];
2391 
2392     d[i * 4 + 0] = 0xff;
2393     d[i * 4 + 1] = y0;
2394     d[i * 4 + 2] = u0;
2395     d[i * 4 + 3] = v0;
2396 
2397     d[i * 4 + 4] = 0xff;
2398     d[i * 4 + 5] = y1;
2399     d[i * 4 + 6] = u0;
2400     d[i * 4 + 7] = v0;
2401 
2402     d[i * 4 + 8] = 0xff;
2403     d[i * 4 + 9] = y2;
2404     d[i * 4 + 10] = u0;
2405     d[i * 4 + 11] = v0;
2406 
2407     d[i * 4 + 12] = 0xff;
2408     d[i * 4 + 13] = y3;
2409     d[i * 4 + 14] = u0;
2410     d[i * 4 + 15] = v0;
2411   }
2412   if (i < width) {
2413     u0 = s[(i >> 2) * 6 + 0];
2414     v0 = s[(i >> 2) * 6 + 3];
2415 
2416     d[i * 4 + 0] = 0xff;
2417     d[i * 4 + 1] = s[(i >> 2) * 6 + 1];
2418     d[i * 4 + 2] = u0;
2419     d[i * 4 + 3] = v0;
2420 
2421     if (i < width - 1) {
2422       d[i * 4 + 4] = 0xff;
2423       d[i * 4 + 5] = s[(i >> 2) * 6 + 2];
2424       d[i * 4 + 6] = u0;
2425       d[i * 4 + 7] = v0;
2426     }
2427     if (i < width - 2) {
2428       d[i * 4 + 8] = 0xff;
2429       d[i * 4 + 9] = s[(i >> 2) * 6 + 4];
2430       d[i * 4 + 10] = u0;
2431       d[i * 4 + 11] = v0;
2432     }
2433   }
2434 }
2435 
2436 static void
pack_IYU1(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2437 pack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2438     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2439     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2440     gint y, gint width)
2441 {
2442   int i;
2443   guint8 *restrict d = GET_LINE (y);
2444   const guint8 *restrict s = src;
2445 
2446   for (i = 0; i < width - 3; i += 4) {
2447     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
2448     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
2449     d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
2450     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
2451     d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
2452     d[(i >> 2) * 6 + 5] = s[i * 4 + 13];
2453   }
2454   if (i < width) {
2455     d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
2456     d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
2457     d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
2458     if (i < width - 1)
2459       d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
2460     if (i < width - 2)
2461       d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
2462   }
2463 }
2464 
2465 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2466 #define PACK_ARGB64_LE GST_VIDEO_FORMAT_ARGB64, unpack_copy8, 1, pack_copy8
2467 #define PACK_ARGB64_BE GST_VIDEO_FORMAT_ARGB64, unpack_ARGB64_swap, 1, pack_ARGB64_swap
2468 #else
2469 #define PACK_ARGB64_LE GST_VIDEO_FORMAT_ARGB64, unpack_ARGB64_swap, 1, pack_ARGB64_swap
2470 #define PACK_ARGB64_BE GST_VIDEO_FORMAT_ARGB64, unpack_copy8, 1, pack_copy8
2471 #endif
2472 
2473 static void
unpack_ARGB64_swap(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2474 unpack_ARGB64_swap (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2475     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2476     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2477 {
2478   int i;
2479   const guint16 *restrict s = GET_LINE (y);
2480   guint16 *restrict d = dest, R, G, B, A;
2481 
2482   s += x * 8;
2483 
2484   for (i = 0; i < width; i++) {
2485     A = GUINT16_SWAP_LE_BE (s[i * 4 + 0]);
2486     R = GUINT16_SWAP_LE_BE (s[i * 4 + 1]);
2487     G = GUINT16_SWAP_LE_BE (s[i * 4 + 2]);
2488     B = GUINT16_SWAP_LE_BE (s[i * 4 + 3]);
2489 
2490     d[i * 4 + 0] = A;
2491     d[i * 4 + 1] = R;
2492     d[i * 4 + 2] = G;
2493     d[i * 4 + 3] = B;
2494   }
2495 }
2496 
2497 static void
pack_ARGB64_swap(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2498 pack_ARGB64_swap (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2499     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2500     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2501     gint y, gint width)
2502 {
2503   int i;
2504   guint16 *restrict d = GET_LINE (y);
2505   guint16 A, R, G, B;
2506   const guint16 *restrict s = src;
2507 
2508   for (i = 0; i < width; i++) {
2509     A = s[i * 4 + 0];
2510     R = s[i * 4 + 1];
2511     G = s[i * 4 + 2];
2512     B = s[i * 4 + 3];
2513 
2514     d[i * 4 + 0] = GUINT16_SWAP_LE_BE (A);
2515     d[i * 4 + 1] = GUINT16_SWAP_LE_BE (R);
2516     d[i * 4 + 2] = GUINT16_SWAP_LE_BE (G);
2517     d[i * 4 + 3] = GUINT16_SWAP_LE_BE (B);
2518   }
2519 }
2520 
2521 #define PACK_RGBA64_LE GST_VIDEO_FORMAT_ARGB64, unpack_RGBA64_LE, 1, pack_RGBA64_LE
2522 static void
unpack_RGBA64_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2523 unpack_RGBA64_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2524     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2525     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2526 {
2527   int i;
2528   const guint16 *restrict s = GET_LINE (y);
2529   guint16 *restrict d = dest, R, G, B, A;
2530 
2531   s += x * 8;
2532 
2533   for (i = 0; i < width; i++) {
2534     R = GST_READ_UINT16_LE (s + i * 4 + 0);
2535     G = GST_READ_UINT16_LE (s + i * 4 + 1);
2536     B = GST_READ_UINT16_LE (s + i * 4 + 2);
2537     A = GST_READ_UINT16_LE (s + i * 4 + 3);
2538 
2539     d[i * 4 + 0] = A;
2540     d[i * 4 + 1] = R;
2541     d[i * 4 + 2] = G;
2542     d[i * 4 + 3] = B;
2543   }
2544 }
2545 
2546 static void
pack_RGBA64_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2547 pack_RGBA64_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2548     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2549     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2550     gint y, gint width)
2551 {
2552   int i;
2553   guint16 *restrict d = GET_LINE (y);
2554   guint16 A, R, G, B;
2555   const guint16 *restrict s = src;
2556 
2557   for (i = 0; i < width; i++) {
2558     A = s[i * 4 + 0];
2559     R = s[i * 4 + 1];
2560     G = s[i * 4 + 2];
2561     B = s[i * 4 + 3];
2562 
2563     GST_WRITE_UINT16_LE (d + i * 4 + 0, R);
2564     GST_WRITE_UINT16_LE (d + i * 4 + 1, G);
2565     GST_WRITE_UINT16_LE (d + i * 4 + 2, B);
2566     GST_WRITE_UINT16_LE (d + i * 4 + 3, A);
2567   }
2568 }
2569 
2570 #define PACK_RGBA64_BE GST_VIDEO_FORMAT_ARGB64, unpack_RGBA64_BE, 1, pack_RGBA64_BE
2571 static void
unpack_RGBA64_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2572 unpack_RGBA64_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2573     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2574     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2575 {
2576   int i;
2577   const guint16 *restrict s = GET_LINE (y);
2578   guint16 *restrict d = dest, R, G, B, A;
2579 
2580   s += x * 8;
2581 
2582   for (i = 0; i < width; i++) {
2583     R = GST_READ_UINT16_BE (s + i * 4 + 0);
2584     G = GST_READ_UINT16_BE (s + i * 4 + 1);
2585     B = GST_READ_UINT16_BE (s + i * 4 + 2);
2586     A = GST_READ_UINT16_BE (s + i * 4 + 3);
2587 
2588     d[i * 4 + 0] = A;
2589     d[i * 4 + 1] = R;
2590     d[i * 4 + 2] = G;
2591     d[i * 4 + 3] = B;
2592   }
2593 }
2594 
2595 static void
pack_RGBA64_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2596 pack_RGBA64_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2597     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2598     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2599     gint y, gint width)
2600 {
2601   int i;
2602   guint16 *restrict d = GET_LINE (y);
2603   guint16 A, R, G, B;
2604   const guint16 *restrict s = src;
2605 
2606   for (i = 0; i < width; i++) {
2607     A = s[i * 4 + 0];
2608     R = s[i * 4 + 1];
2609     G = s[i * 4 + 2];
2610     B = s[i * 4 + 3];
2611 
2612     GST_WRITE_UINT16_BE (d + i * 4 + 0, R);
2613     GST_WRITE_UINT16_BE (d + i * 4 + 1, G);
2614     GST_WRITE_UINT16_BE (d + i * 4 + 2, B);
2615     GST_WRITE_UINT16_BE (d + i * 4 + 3, A);
2616   }
2617 }
2618 
2619 #define PACK_BGRA64_LE GST_VIDEO_FORMAT_ARGB64, unpack_BGRA64_LE, 1, pack_BGRA64_LE
2620 static void
unpack_BGRA64_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2621 unpack_BGRA64_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2622     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2623     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2624 {
2625   int i;
2626   const guint16 *restrict s = GET_LINE (y);
2627   guint16 *restrict d = dest, R, G, B, A;
2628 
2629   s += x * 8;
2630 
2631   for (i = 0; i < width; i++) {
2632     B = GST_READ_UINT16_LE (s + i * 4 + 0);
2633     G = GST_READ_UINT16_LE (s + i * 4 + 1);
2634     R = GST_READ_UINT16_LE (s + i * 4 + 2);
2635     A = GST_READ_UINT16_LE (s + i * 4 + 3);
2636 
2637     d[i * 4 + 0] = A;
2638     d[i * 4 + 1] = R;
2639     d[i * 4 + 2] = G;
2640     d[i * 4 + 3] = B;
2641   }
2642 }
2643 
2644 static void
pack_BGRA64_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2645 pack_BGRA64_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2646     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2647     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2648     gint y, gint width)
2649 {
2650   int i;
2651   guint16 *restrict d = GET_LINE (y);
2652   guint16 A, R, G, B;
2653   const guint16 *restrict s = src;
2654 
2655   for (i = 0; i < width; i++) {
2656     A = s[i * 4 + 0];
2657     R = s[i * 4 + 1];
2658     G = s[i * 4 + 2];
2659     B = s[i * 4 + 3];
2660 
2661     GST_WRITE_UINT16_LE (d + i * 4 + 0, B);
2662     GST_WRITE_UINT16_LE (d + i * 4 + 1, G);
2663     GST_WRITE_UINT16_LE (d + i * 4 + 2, R);
2664     GST_WRITE_UINT16_LE (d + i * 4 + 3, A);
2665   }
2666 }
2667 
2668 #define PACK_BGRA64_BE GST_VIDEO_FORMAT_ARGB64, unpack_BGRA64_BE, 1, pack_BGRA64_BE
2669 static void
unpack_BGRA64_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2670 unpack_BGRA64_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2671     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2672     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2673 {
2674   int i;
2675   const guint16 *restrict s = GET_LINE (y);
2676   guint16 *restrict d = dest, R, G, B, A;
2677 
2678   s += x * 8;
2679 
2680   for (i = 0; i < width; i++) {
2681     B = GST_READ_UINT16_BE (s + i * 4 + 0);
2682     G = GST_READ_UINT16_BE (s + i * 4 + 1);
2683     R = GST_READ_UINT16_BE (s + i * 4 + 2);
2684     A = GST_READ_UINT16_BE (s + i * 4 + 3);
2685 
2686     d[i * 4 + 0] = A;
2687     d[i * 4 + 1] = R;
2688     d[i * 4 + 2] = G;
2689     d[i * 4 + 3] = B;
2690   }
2691 }
2692 
2693 static void
pack_BGRA64_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2694 pack_BGRA64_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2695     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2696     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2697     gint y, gint width)
2698 {
2699   int i;
2700   guint16 *restrict d = GET_LINE (y);
2701   guint16 A, R, G, B;
2702   const guint16 *restrict s = src;
2703 
2704   for (i = 0; i < width; i++) {
2705     A = s[i * 4 + 0];
2706     R = s[i * 4 + 1];
2707     G = s[i * 4 + 2];
2708     B = s[i * 4 + 3];
2709 
2710     GST_WRITE_UINT16_BE (d + i * 4 + 0, B);
2711     GST_WRITE_UINT16_BE (d + i * 4 + 1, G);
2712     GST_WRITE_UINT16_BE (d + i * 4 + 2, R);
2713     GST_WRITE_UINT16_BE (d + i * 4 + 3, A);
2714   }
2715 }
2716 
2717 
2718 #define PACK_ABGR64_LE GST_VIDEO_FORMAT_ARGB64, unpack_ABGR64_LE, 1, pack_ABGR64_LE
2719 static void
unpack_ABGR64_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2720 unpack_ABGR64_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2721     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2722     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2723 {
2724   int i;
2725   const guint16 *restrict s = GET_LINE (y);
2726   guint16 *restrict d = dest, R, G, B, A;
2727 
2728   s += x * 8;
2729 
2730   for (i = 0; i < width; i++) {
2731     A = GST_READ_UINT16_LE (s + i * 4 + 0);
2732     B = GST_READ_UINT16_LE (s + i * 4 + 1);
2733     G = GST_READ_UINT16_LE (s + i * 4 + 2);
2734     R = GST_READ_UINT16_LE (s + i * 4 + 3);
2735 
2736     d[i * 4 + 0] = A;
2737     d[i * 4 + 1] = R;
2738     d[i * 4 + 2] = G;
2739     d[i * 4 + 3] = B;
2740   }
2741 }
2742 
2743 static void
pack_ABGR64_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2744 pack_ABGR64_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2745     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2746     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2747     gint y, gint width)
2748 {
2749   int i;
2750   guint16 *restrict d = GET_LINE (y);
2751   guint16 A, R, G, B;
2752   const guint16 *restrict s = src;
2753 
2754   for (i = 0; i < width; i++) {
2755     A = s[i * 4 + 0];
2756     R = s[i * 4 + 1];
2757     G = s[i * 4 + 2];
2758     B = s[i * 4 + 3];
2759 
2760     GST_WRITE_UINT16_LE (d + i * 4 + 0, A);
2761     GST_WRITE_UINT16_LE (d + i * 4 + 1, B);
2762     GST_WRITE_UINT16_LE (d + i * 4 + 2, G);
2763     GST_WRITE_UINT16_LE (d + i * 4 + 3, R);
2764   }
2765 }
2766 
2767 #define PACK_ABGR64_BE GST_VIDEO_FORMAT_ARGB64, unpack_ABGR64_BE, 1, pack_ABGR64_BE
2768 static void
unpack_ABGR64_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2769 unpack_ABGR64_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2770     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2771     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2772 {
2773   int i;
2774   const guint16 *restrict s = GET_LINE (y);
2775   guint16 *restrict d = dest, R, G, B, A;
2776 
2777   s += x * 8;
2778 
2779   for (i = 0; i < width; i++) {
2780     A = GST_READ_UINT16_BE (s + i * 4 + 0);
2781     B = GST_READ_UINT16_BE (s + i * 4 + 1);
2782     G = GST_READ_UINT16_BE (s + i * 4 + 2);
2783     R = GST_READ_UINT16_BE (s + i * 4 + 3);
2784 
2785     d[i * 4 + 0] = A;
2786     d[i * 4 + 1] = R;
2787     d[i * 4 + 2] = G;
2788     d[i * 4 + 3] = B;
2789   }
2790 }
2791 
2792 static void
pack_ABGR64_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2793 pack_ABGR64_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2794     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2795     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2796     gint y, gint width)
2797 {
2798   int i;
2799   guint16 *restrict d = GET_LINE (y);
2800   guint16 A, R, G, B;
2801   const guint16 *restrict s = src;
2802 
2803   for (i = 0; i < width; i++) {
2804     A = s[i * 4 + 0];
2805     R = s[i * 4 + 1];
2806     G = s[i * 4 + 2];
2807     B = s[i * 4 + 3];
2808 
2809     GST_WRITE_UINT16_BE (d + i * 4 + 0, A);
2810     GST_WRITE_UINT16_BE (d + i * 4 + 1, B);
2811     GST_WRITE_UINT16_BE (d + i * 4 + 2, G);
2812     GST_WRITE_UINT16_BE (d + i * 4 + 3, R);
2813   }
2814 }
2815 
2816 
2817 #define PACK_ARGB64 GST_VIDEO_FORMAT_ARGB64, unpack_copy8, 1, pack_copy8
2818 #define PACK_AYUV64 GST_VIDEO_FORMAT_AYUV64, unpack_copy8, 1, pack_copy8
2819 static void
unpack_copy8(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2820 unpack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2821     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2822     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2823 {
2824   const guint8 *s = GET_LINE (y);
2825 
2826   s += x * 8;
2827 
2828   memcpy (dest, s, width * 8);
2829 }
2830 
2831 static void
pack_copy8(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2832 pack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2833     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2834     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2835     gint y, gint width)
2836 {
2837   guint8 *restrict d = GET_LINE (y);
2838 
2839   memcpy (d, src, width * 8);
2840 }
2841 
2842 #define PACK_r210 GST_VIDEO_FORMAT_ARGB64, unpack_r210, 1, pack_r210
2843 static void
unpack_r210(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2844 unpack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2845     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2846     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2847 {
2848   int i;
2849   const guint8 *restrict s = GET_LINE (y);
2850   guint16 *restrict d = dest, R, G, B;
2851 
2852   s += x * 4;
2853 
2854   for (i = 0; i < width; i++) {
2855     guint32 x = GST_READ_UINT32_BE (s + i * 4);
2856 
2857     R = ((x >> 14) & 0xffc0);
2858     G = ((x >> 4) & 0xffc0);
2859     B = ((x << 6) & 0xffc0);
2860 
2861     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2862       R |= (R >> 10);
2863       G |= (G >> 10);
2864       B |= (B >> 10);
2865     }
2866 
2867     d[i * 4 + 0] = 0xffff;
2868     d[i * 4 + 1] = R;
2869     d[i * 4 + 2] = G;
2870     d[i * 4 + 3] = B;
2871   }
2872 }
2873 
2874 static void
pack_r210(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2875 pack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2876     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2877     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2878     gint y, gint width)
2879 {
2880   int i;
2881   guint8 *restrict d = GET_LINE (y);
2882   const guint16 *restrict s = src;
2883 
2884   for (i = 0; i < width; i++) {
2885     guint32 x = 0;
2886     x |= (s[i * 4 + 1] & 0xffc0) << 14;
2887     x |= (s[i * 4 + 2] & 0xffc0) << 4;
2888     x |= (s[i * 4 + 3] & 0xffc0) >> 6;
2889     GST_WRITE_UINT32_BE (d + i * 4, x);
2890   }
2891 }
2892 
2893 #define PACK_GBR_10LE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10LE, 1, pack_GBR_10LE
2894 static void
unpack_GBR_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2895 unpack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2896     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2897     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2898 {
2899   int i;
2900   const guint16 *sg = GET_G_LINE (y);
2901   const guint16 *sb = GET_B_LINE (y);
2902   const guint16 *sr = GET_R_LINE (y);
2903   guint16 *d = dest, G, B, R;
2904 
2905   sg += x;
2906   sb += x;
2907   sr += x;
2908 
2909   for (i = 0; i < width; i++) {
2910     G = GST_READ_UINT16_LE (sg + i) << 6;
2911     B = GST_READ_UINT16_LE (sb + i) << 6;
2912     R = GST_READ_UINT16_LE (sr + i) << 6;
2913 
2914     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2915       R |= (R >> 10);
2916       G |= (G >> 10);
2917       B |= (B >> 10);
2918     }
2919 
2920     d[i * 4 + 0] = 0xffff;
2921     d[i * 4 + 1] = R;
2922     d[i * 4 + 2] = G;
2923     d[i * 4 + 3] = B;
2924   }
2925 }
2926 
2927 static void
pack_GBR_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2928 pack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2929     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2930     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2931     gint y, gint width)
2932 {
2933   int i;
2934   guint16 *restrict dg = GET_G_LINE (y);
2935   guint16 *restrict db = GET_B_LINE (y);
2936   guint16 *restrict dr = GET_R_LINE (y);
2937   guint16 G, B, R;
2938   const guint16 *restrict s = src;
2939 
2940   for (i = 0; i < width; i++) {
2941     G = (s[i * 4 + 2]) >> 6;
2942     B = (s[i * 4 + 3]) >> 6;
2943     R = (s[i * 4 + 1]) >> 6;
2944 
2945     GST_WRITE_UINT16_LE (dg + i, G);
2946     GST_WRITE_UINT16_LE (db + i, B);
2947     GST_WRITE_UINT16_LE (dr + i, R);
2948   }
2949 }
2950 
2951 #define PACK_GBR_10BE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_10BE, 1, pack_GBR_10BE
2952 static void
unpack_GBR_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)2953 unpack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2954     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
2955     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
2956 {
2957   int i;
2958   const guint16 *restrict sg = GET_G_LINE (y);
2959   const guint16 *restrict sb = GET_B_LINE (y);
2960   const guint16 *restrict sr = GET_R_LINE (y);
2961   guint16 *restrict d = dest, G, B, R;
2962 
2963   sg += x;
2964   sb += x;
2965   sr += x;
2966 
2967   for (i = 0; i < width; i++) {
2968     G = GST_READ_UINT16_BE (sg + i) << 6;
2969     B = GST_READ_UINT16_BE (sb + i) << 6;
2970     R = GST_READ_UINT16_BE (sr + i) << 6;
2971 
2972     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
2973       R |= (R >> 10);
2974       G |= (G >> 10);
2975       B |= (B >> 10);
2976     }
2977 
2978     d[i * 4 + 0] = 0xffff;
2979     d[i * 4 + 1] = R;
2980     d[i * 4 + 2] = G;
2981     d[i * 4 + 3] = B;
2982   }
2983 }
2984 
2985 static void
pack_GBR_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)2986 pack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
2987     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
2988     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
2989     gint y, gint width)
2990 {
2991   int i;
2992   guint16 *restrict dg = GET_G_LINE (y);
2993   guint16 *restrict db = GET_B_LINE (y);
2994   guint16 *restrict dr = GET_R_LINE (y);
2995   guint16 G, B, R;
2996   const guint16 *restrict s = src;
2997 
2998   for (i = 0; i < width; i++) {
2999     G = s[i * 4 + 2] >> 6;
3000     B = s[i * 4 + 3] >> 6;
3001     R = s[i * 4 + 1] >> 6;
3002 
3003     GST_WRITE_UINT16_BE (dg + i, G);
3004     GST_WRITE_UINT16_BE (db + i, B);
3005     GST_WRITE_UINT16_BE (dr + i, R);
3006   }
3007 }
3008 
3009 #define PACK_GBRA_10LE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_10LE, 1, pack_GBRA_10LE
3010 static void
unpack_GBRA_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3011 unpack_GBRA_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3012     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3013     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3014 {
3015   int i;
3016   const guint16 *sg = GET_G_LINE (y);
3017   const guint16 *sb = GET_B_LINE (y);
3018   const guint16 *sr = GET_R_LINE (y);
3019   const guint16 *sa = GET_A_LINE (y);
3020   guint16 *d = dest, G, B, R, A;
3021 
3022   sg += x;
3023   sb += x;
3024   sr += x;
3025   sa += x;
3026 
3027   for (i = 0; i < width; i++) {
3028     G = GST_READ_UINT16_LE (sg + i) << 6;
3029     B = GST_READ_UINT16_LE (sb + i) << 6;
3030     R = GST_READ_UINT16_LE (sr + i) << 6;
3031     A = GST_READ_UINT16_LE (sa + i) << 6;
3032 
3033     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3034       R |= (R >> 10);
3035       G |= (G >> 10);
3036       B |= (B >> 10);
3037       A |= (A >> 10);
3038     }
3039 
3040     d[i * 4 + 0] = A;
3041     d[i * 4 + 1] = R;
3042     d[i * 4 + 2] = G;
3043     d[i * 4 + 3] = B;
3044   }
3045 }
3046 
3047 static void
pack_GBRA_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3048 pack_GBRA_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3049     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3050     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3051     gint y, gint width)
3052 {
3053   int i;
3054   guint16 *restrict dg = GET_G_LINE (y);
3055   guint16 *restrict db = GET_B_LINE (y);
3056   guint16 *restrict dr = GET_R_LINE (y);
3057   guint16 *restrict da = GET_A_LINE (y);
3058   guint16 G, B, R, A;
3059   const guint16 *restrict s = src;
3060 
3061   for (i = 0; i < width; i++) {
3062     G = (s[i * 4 + 2]) >> 6;
3063     B = (s[i * 4 + 3]) >> 6;
3064     R = (s[i * 4 + 1]) >> 6;
3065     A = (s[i * 4 + 0]) >> 6;
3066 
3067     GST_WRITE_UINT16_LE (dg + i, G);
3068     GST_WRITE_UINT16_LE (db + i, B);
3069     GST_WRITE_UINT16_LE (dr + i, R);
3070     GST_WRITE_UINT16_LE (da + i, A);
3071   }
3072 }
3073 
3074 #define PACK_GBRA_10BE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_10BE, 1, pack_GBRA_10BE
3075 static void
unpack_GBRA_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3076 unpack_GBRA_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3077     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3078     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3079 {
3080   int i;
3081   const guint16 *restrict sg = GET_G_LINE (y);
3082   const guint16 *restrict sb = GET_B_LINE (y);
3083   const guint16 *restrict sr = GET_R_LINE (y);
3084   const guint16 *restrict sa = GET_A_LINE (y);
3085   guint16 *restrict d = dest, G, B, R, A;
3086 
3087   sg += x;
3088   sb += x;
3089   sr += x;
3090   sa += x;
3091 
3092   for (i = 0; i < width; i++) {
3093     G = GST_READ_UINT16_BE (sg + i) << 6;
3094     B = GST_READ_UINT16_BE (sb + i) << 6;
3095     R = GST_READ_UINT16_BE (sr + i) << 6;
3096     A = GST_READ_UINT16_BE (sa + i) << 6;
3097 
3098     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3099       R |= (R >> 10);
3100       G |= (G >> 10);
3101       B |= (B >> 10);
3102       A |= (A >> 10);
3103     }
3104 
3105     d[i * 4 + 0] = A;
3106     d[i * 4 + 1] = R;
3107     d[i * 4 + 2] = G;
3108     d[i * 4 + 3] = B;
3109   }
3110 }
3111 
3112 static void
pack_GBRA_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3113 pack_GBRA_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3114     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3115     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3116     gint y, gint width)
3117 {
3118   int i;
3119   guint16 *restrict dg = GET_G_LINE (y);
3120   guint16 *restrict db = GET_B_LINE (y);
3121   guint16 *restrict dr = GET_R_LINE (y);
3122   guint16 *restrict da = GET_A_LINE (y);
3123   guint16 G, B, R, A;
3124   const guint16 *restrict s = src;
3125 
3126   for (i = 0; i < width; i++) {
3127     G = s[i * 4 + 2] >> 6;
3128     B = s[i * 4 + 3] >> 6;
3129     R = s[i * 4 + 1] >> 6;
3130     A = s[i * 4 + 0] >> 6;
3131 
3132     GST_WRITE_UINT16_BE (dg + i, G);
3133     GST_WRITE_UINT16_BE (db + i, B);
3134     GST_WRITE_UINT16_BE (dr + i, R);
3135     GST_WRITE_UINT16_BE (da + i, A);
3136   }
3137 }
3138 
3139 #define PACK_GBR_12LE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_12LE, 1, pack_GBR_12LE
3140 static void
unpack_GBR_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3141 unpack_GBR_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3142     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3143     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3144 {
3145   int i;
3146   const guint16 *sg = GET_G_LINE (y);
3147   const guint16 *sb = GET_B_LINE (y);
3148   const guint16 *sr = GET_R_LINE (y);
3149   guint16 *d = dest, G, B, R;
3150 
3151   sg += x;
3152   sb += x;
3153   sr += x;
3154 
3155   for (i = 0; i < width; i++) {
3156     G = GST_READ_UINT16_LE (sg + i) << 4;
3157     B = GST_READ_UINT16_LE (sb + i) << 4;
3158     R = GST_READ_UINT16_LE (sr + i) << 4;
3159 
3160     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3161       R |= (R >> 12);
3162       G |= (G >> 12);
3163       B |= (B >> 12);
3164     }
3165 
3166     d[i * 4 + 0] = 0xffff;
3167     d[i * 4 + 1] = R;
3168     d[i * 4 + 2] = G;
3169     d[i * 4 + 3] = B;
3170   }
3171 }
3172 
3173 static void
pack_GBR_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3174 pack_GBR_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3175     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3176     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3177     gint y, gint width)
3178 {
3179   int i;
3180   guint16 *restrict dg = GET_G_LINE (y);
3181   guint16 *restrict db = GET_B_LINE (y);
3182   guint16 *restrict dr = GET_R_LINE (y);
3183   guint16 G, B, R;
3184   const guint16 *restrict s = src;
3185 
3186   for (i = 0; i < width; i++) {
3187     G = (s[i * 4 + 2]) >> 4;
3188     B = (s[i * 4 + 3]) >> 4;
3189     R = (s[i * 4 + 1]) >> 4;
3190 
3191     GST_WRITE_UINT16_LE (dg + i, G);
3192     GST_WRITE_UINT16_LE (db + i, B);
3193     GST_WRITE_UINT16_LE (dr + i, R);
3194   }
3195 }
3196 
3197 #define PACK_GBR_12BE GST_VIDEO_FORMAT_ARGB64, unpack_GBR_12BE, 1, pack_GBR_12BE
3198 static void
unpack_GBR_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3199 unpack_GBR_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3200     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3201     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3202 {
3203   int i;
3204   const guint16 *restrict sg = GET_G_LINE (y);
3205   const guint16 *restrict sb = GET_B_LINE (y);
3206   const guint16 *restrict sr = GET_R_LINE (y);
3207   guint16 *restrict d = dest, G, B, R;
3208 
3209   sg += x;
3210   sb += x;
3211   sr += x;
3212 
3213   for (i = 0; i < width; i++) {
3214     G = GST_READ_UINT16_BE (sg + i) << 4;
3215     B = GST_READ_UINT16_BE (sb + i) << 4;
3216     R = GST_READ_UINT16_BE (sr + i) << 4;
3217 
3218     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3219       R |= (R >> 12);
3220       G |= (G >> 12);
3221       B |= (B >> 12);
3222     }
3223 
3224     d[i * 4 + 0] = 0xffff;
3225     d[i * 4 + 1] = R;
3226     d[i * 4 + 2] = G;
3227     d[i * 4 + 3] = B;
3228   }
3229 }
3230 
3231 static void
pack_GBR_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3232 pack_GBR_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3233     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3234     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3235     gint y, gint width)
3236 {
3237   int i;
3238   guint16 *restrict dg = GET_G_LINE (y);
3239   guint16 *restrict db = GET_B_LINE (y);
3240   guint16 *restrict dr = GET_R_LINE (y);
3241   guint16 G, B, R;
3242   const guint16 *restrict s = src;
3243 
3244   for (i = 0; i < width; i++) {
3245     G = s[i * 4 + 2] >> 4;
3246     B = s[i * 4 + 3] >> 4;
3247     R = s[i * 4 + 1] >> 4;
3248 
3249     GST_WRITE_UINT16_BE (dg + i, G);
3250     GST_WRITE_UINT16_BE (db + i, B);
3251     GST_WRITE_UINT16_BE (dr + i, R);
3252   }
3253 }
3254 
3255 #define PACK_GBRA_12LE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_12LE, 1, pack_GBRA_12LE
3256 static void
unpack_GBRA_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3257 unpack_GBRA_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3258     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3259     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3260 {
3261   int i;
3262   const guint16 *sg = GET_G_LINE (y);
3263   const guint16 *sb = GET_B_LINE (y);
3264   const guint16 *sr = GET_R_LINE (y);
3265   const guint16 *sa = GET_A_LINE (y);
3266   guint16 *d = dest, G, B, R, A;
3267 
3268   sg += x;
3269   sb += x;
3270   sr += x;
3271   sa += x;
3272 
3273   for (i = 0; i < width; i++) {
3274     G = GST_READ_UINT16_LE (sg + i) << 4;
3275     B = GST_READ_UINT16_LE (sb + i) << 4;
3276     R = GST_READ_UINT16_LE (sr + i) << 4;
3277     A = GST_READ_UINT16_LE (sa + i) << 4;
3278 
3279     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3280       A |= (A >> 12);
3281       R |= (R >> 12);
3282       G |= (G >> 12);
3283       B |= (B >> 12);
3284     }
3285 
3286     d[i * 4 + 0] = A;
3287     d[i * 4 + 1] = R;
3288     d[i * 4 + 2] = G;
3289     d[i * 4 + 3] = B;
3290   }
3291 }
3292 
3293 static void
pack_GBRA_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3294 pack_GBRA_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3295     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3296     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3297     gint y, gint width)
3298 {
3299   int i;
3300   guint16 *restrict dg = GET_G_LINE (y);
3301   guint16 *restrict db = GET_B_LINE (y);
3302   guint16 *restrict dr = GET_R_LINE (y);
3303   guint16 *restrict da = GET_A_LINE (y);
3304   guint16 G, B, R, A;
3305   const guint16 *restrict s = src;
3306 
3307   for (i = 0; i < width; i++) {
3308     G = (s[i * 4 + 2]) >> 4;
3309     B = (s[i * 4 + 3]) >> 4;
3310     R = (s[i * 4 + 1]) >> 4;
3311     A = (s[i * 4 + 0]) >> 4;
3312 
3313     GST_WRITE_UINT16_LE (dg + i, G);
3314     GST_WRITE_UINT16_LE (db + i, B);
3315     GST_WRITE_UINT16_LE (dr + i, R);
3316     GST_WRITE_UINT16_LE (da + i, A);
3317   }
3318 }
3319 
3320 #define PACK_GBRA_12BE GST_VIDEO_FORMAT_ARGB64, unpack_GBRA_12BE, 1, pack_GBRA_12BE
3321 static void
unpack_GBRA_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3322 unpack_GBRA_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3323     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3324     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3325 {
3326   int i;
3327   const guint16 *restrict sg = GET_G_LINE (y);
3328   const guint16 *restrict sb = GET_B_LINE (y);
3329   const guint16 *restrict sr = GET_R_LINE (y);
3330   const guint16 *restrict sa = GET_A_LINE (y);
3331   guint16 *restrict d = dest, G, B, R, A;
3332 
3333   sg += x;
3334   sb += x;
3335   sr += x;
3336   sa += x;
3337 
3338   for (i = 0; i < width; i++) {
3339     G = GST_READ_UINT16_BE (sg + i) << 4;
3340     B = GST_READ_UINT16_BE (sb + i) << 4;
3341     R = GST_READ_UINT16_BE (sr + i) << 4;
3342     A = GST_READ_UINT16_BE (sa + i) << 4;
3343 
3344     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3345       R |= (R >> 12);
3346       G |= (G >> 12);
3347       B |= (B >> 12);
3348       A |= (A >> 12);
3349     }
3350 
3351     d[i * 4 + 0] = A;
3352     d[i * 4 + 1] = R;
3353     d[i * 4 + 2] = G;
3354     d[i * 4 + 3] = B;
3355   }
3356 }
3357 
3358 static void
pack_GBRA_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3359 pack_GBRA_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3360     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3361     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3362     gint y, gint width)
3363 {
3364   int i;
3365   guint16 *restrict dg = GET_G_LINE (y);
3366   guint16 *restrict db = GET_B_LINE (y);
3367   guint16 *restrict dr = GET_R_LINE (y);
3368   guint16 *restrict da = GET_A_LINE (y);
3369   guint16 G, B, R, A;
3370   const guint16 *restrict s = src;
3371 
3372   for (i = 0; i < width; i++) {
3373     G = s[i * 4 + 2] >> 4;
3374     B = s[i * 4 + 3] >> 4;
3375     R = s[i * 4 + 1] >> 4;
3376     A = s[i * 4 + 0] >> 4;
3377 
3378     GST_WRITE_UINT16_BE (dg + i, G);
3379     GST_WRITE_UINT16_BE (db + i, B);
3380     GST_WRITE_UINT16_BE (dr + i, R);
3381     GST_WRITE_UINT16_BE (da + i, A);
3382   }
3383 }
3384 
3385 #define PACK_Y444_10LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10LE, 1, pack_Y444_10LE
3386 static void
unpack_Y444_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3387 unpack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3388     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3389     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3390 {
3391   int i;
3392   guint16 *restrict sy = GET_Y_LINE (y);
3393   guint16 *restrict su = GET_U_LINE (y);
3394   guint16 *restrict sv = GET_V_LINE (y);
3395   guint16 *restrict d = dest, Y, U, V;
3396 
3397   sy += x;
3398   su += x;
3399   sv += x;
3400 
3401   for (i = 0; i < width; i++) {
3402     Y = GST_READ_UINT16_LE (sy + i) << 6;
3403     U = GST_READ_UINT16_LE (su + i) << 6;
3404     V = GST_READ_UINT16_LE (sv + i) << 6;
3405 
3406     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3407       Y |= (Y >> 10);
3408       U |= (U >> 10);
3409       V |= (V >> 10);
3410     }
3411 
3412     d[i * 4 + 0] = 0xffff;
3413     d[i * 4 + 1] = Y;
3414     d[i * 4 + 2] = U;
3415     d[i * 4 + 3] = V;
3416   }
3417 }
3418 
3419 static void
pack_Y444_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3420 pack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3421     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3422     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3423     gint y, gint width)
3424 {
3425   int i;
3426   guint16 *restrict dy = GET_Y_LINE (y);
3427   guint16 *restrict du = GET_U_LINE (y);
3428   guint16 *restrict dv = GET_V_LINE (y);
3429   guint16 Y, U, V;
3430   const guint16 *restrict s = src;
3431 
3432   for (i = 0; i < width; i++) {
3433     Y = (s[i * 4 + 1]) >> 6;
3434     U = (s[i * 4 + 2]) >> 6;
3435     V = (s[i * 4 + 3]) >> 6;
3436 
3437     GST_WRITE_UINT16_LE (dy + i, Y);
3438     GST_WRITE_UINT16_LE (du + i, U);
3439     GST_WRITE_UINT16_LE (dv + i, V);
3440   }
3441 }
3442 
3443 #define PACK_Y444_10BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_10BE, 1, pack_Y444_10BE
3444 static void
unpack_Y444_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3445 unpack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3446     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3447     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3448 {
3449   int i;
3450   const guint16 *restrict sy = GET_Y_LINE (y);
3451   const guint16 *restrict su = GET_U_LINE (y);
3452   const guint16 *restrict sv = GET_V_LINE (y);
3453   guint16 *restrict d = dest, Y, U, V;
3454 
3455   sy += x;
3456   su += x;
3457   sv += x;
3458 
3459   for (i = 0; i < width; i++) {
3460     Y = GST_READ_UINT16_BE (sy + i) << 6;
3461     U = GST_READ_UINT16_BE (su + i) << 6;
3462     V = GST_READ_UINT16_BE (sv + i) << 6;
3463 
3464     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3465       Y |= (Y >> 10);
3466       U |= (U >> 10);
3467       V |= (V >> 10);
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 }
3476 
3477 static void
pack_Y444_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3478 pack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3479     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3480     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3481     gint y, gint width)
3482 {
3483   int i;
3484   guint16 *restrict dy = GET_Y_LINE (y);
3485   guint16 *restrict du = GET_U_LINE (y);
3486   guint16 *restrict dv = GET_V_LINE (y);
3487   guint16 Y, U, V;
3488   const guint16 *restrict s = src;
3489 
3490   for (i = 0; i < width; i++) {
3491     Y = s[i * 4 + 1] >> 6;
3492     U = s[i * 4 + 2] >> 6;
3493     V = s[i * 4 + 3] >> 6;
3494 
3495     GST_WRITE_UINT16_BE (dy + i, Y);
3496     GST_WRITE_UINT16_BE (du + i, U);
3497     GST_WRITE_UINT16_BE (dv + i, V);
3498   }
3499 }
3500 
3501 #define PACK_I420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10LE, 1, pack_I420_10LE
3502 static void
unpack_I420_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3503 unpack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3504     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3505     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3506 {
3507   int i;
3508   gint uv = GET_UV_420 (y, flags);
3509   const guint16 *restrict sy = GET_Y_LINE (y);
3510   const guint16 *restrict su = GET_U_LINE (uv);
3511   const guint16 *restrict sv = GET_V_LINE (uv);
3512   guint16 *restrict d = dest, Y, U, V;
3513 
3514   sy += x;
3515   su += x >> 1;
3516   sv += x >> 1;
3517 
3518   for (i = 0; i < width; i++) {
3519     Y = GST_READ_UINT16_LE (sy + i) << 6;
3520     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
3521     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
3522 
3523     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3524       Y |= (Y >> 10);
3525       U |= (U >> 10);
3526       V |= (V >> 10);
3527     }
3528 
3529     d[i * 4 + 0] = 0xffff;
3530     d[i * 4 + 1] = Y;
3531     d[i * 4 + 2] = U;
3532     d[i * 4 + 3] = V;
3533 
3534     if (x & 1) {
3535       x = 0;
3536       su++;
3537       sv++;
3538     }
3539   }
3540 }
3541 
3542 static void
pack_I420_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3543 pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3544     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3545     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3546     gint y, gint width)
3547 {
3548   int i;
3549   gint uv = GET_UV_420 (y, flags);
3550   guint16 *restrict dy = GET_Y_LINE (y);
3551   guint16 *restrict du = GET_U_LINE (uv);
3552   guint16 *restrict dv = GET_V_LINE (uv);
3553   guint16 Y0, Y1, U, V;
3554   const guint16 *restrict s = src;
3555 
3556   if (IS_CHROMA_LINE_420 (y, flags)) {
3557     for (i = 0; i < width - 1; i += 2) {
3558       Y0 = s[i * 4 + 1] >> 6;
3559       Y1 = s[i * 4 + 5] >> 6;
3560       U = s[i * 4 + 2] >> 6;
3561       V = s[i * 4 + 3] >> 6;
3562 
3563       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3564       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3565       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3566       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3567     }
3568     if (i == width - 1) {
3569       Y0 = s[i * 4 + 1] >> 6;
3570       U = s[i * 4 + 2] >> 6;
3571       V = s[i * 4 + 3] >> 6;
3572 
3573       GST_WRITE_UINT16_LE (dy + i, Y0);
3574       GST_WRITE_UINT16_LE (du + (i >> 1), U);
3575       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3576     }
3577   } else {
3578     for (i = 0; i < width; i++) {
3579       Y0 = s[i * 4 + 1] >> 6;
3580       GST_WRITE_UINT16_LE (dy + i, Y0);
3581     }
3582   }
3583 }
3584 
3585 #define PACK_I420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_10BE, 1, pack_I420_10BE
3586 static void
unpack_I420_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3587 unpack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3588     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3589     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3590 {
3591   int i;
3592   gint uv = GET_UV_420 (y, flags);
3593   const guint16 *restrict sy = GET_Y_LINE (y);
3594   const guint16 *restrict su = GET_U_LINE (uv);
3595   const guint16 *restrict sv = GET_V_LINE (uv);
3596   guint16 *restrict d = dest, Y, U, V;
3597 
3598   sy += x;
3599   su += x >> 1;
3600   sv += x >> 1;
3601 
3602   for (i = 0; i < width; i++) {
3603     Y = GST_READ_UINT16_BE (sy + i) << 6;
3604     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3605     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3606 
3607     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3608       Y |= (Y >> 10);
3609       U |= (U >> 10);
3610       V |= (V >> 10);
3611     }
3612 
3613     d[i * 4 + 0] = 0xffff;
3614     d[i * 4 + 1] = Y;
3615     d[i * 4 + 2] = U;
3616     d[i * 4 + 3] = V;
3617 
3618     if (x & 1) {
3619       x = 0;
3620       su++;
3621       sv++;
3622     }
3623   }
3624 }
3625 
3626 static void
pack_I420_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3627 pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3628     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3629     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3630     gint y, gint width)
3631 {
3632   int i;
3633   gint uv = GET_UV_420 (y, flags);
3634   guint16 *restrict dy = GET_Y_LINE (y);
3635   guint16 *restrict du = GET_U_LINE (uv);
3636   guint16 *restrict dv = GET_V_LINE (uv);
3637   guint16 Y0, Y1, U, V;
3638   const guint16 *restrict s = src;
3639 
3640   if (IS_CHROMA_LINE_420 (y, flags)) {
3641     for (i = 0; i < width - 1; i += 2) {
3642       Y0 = s[i * 4 + 1] >> 6;
3643       Y1 = s[i * 4 + 5] >> 6;
3644       U = s[i * 4 + 2] >> 6;
3645       V = s[i * 4 + 3] >> 6;
3646 
3647       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3648       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3649       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3650       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3651     }
3652     if (i == width - 1) {
3653       Y0 = s[i * 4 + 1] >> 6;
3654       U = s[i * 4 + 2] >> 6;
3655       V = s[i * 4 + 3] >> 6;
3656 
3657       GST_WRITE_UINT16_BE (dy + i, Y0);
3658       GST_WRITE_UINT16_BE (du + (i >> 1), U);
3659       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3660     }
3661   } else {
3662     for (i = 0; i < width; i++) {
3663       Y0 = s[i * 4 + 1] >> 6;
3664       GST_WRITE_UINT16_BE (dy + i, Y0);
3665     }
3666   }
3667 }
3668 
3669 #define PACK_I422_10LE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10LE, 1, pack_I422_10LE
3670 static void
unpack_I422_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3671 unpack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3672     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3673     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3674 {
3675   int i;
3676   const guint16 *restrict sy = GET_Y_LINE (y);
3677   const guint16 *restrict su = GET_U_LINE (y);
3678   const guint16 *restrict sv = GET_V_LINE (y);
3679   guint16 *restrict d = dest, Y, U, V;
3680 
3681   sy += x;
3682   su += x >> 1;
3683   sv += x >> 1;
3684 
3685   for (i = 0; i < width; i++) {
3686     Y = GST_READ_UINT16_LE (sy + i) << 6;
3687     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
3688     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
3689 
3690     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3691       Y |= (Y >> 10);
3692       U |= (U >> 10);
3693       V |= (V >> 10);
3694     }
3695 
3696     d[i * 4 + 0] = 0xffff;
3697     d[i * 4 + 1] = Y;
3698     d[i * 4 + 2] = U;
3699     d[i * 4 + 3] = V;
3700 
3701     if (x & 1) {
3702       x = 0;
3703       su++;
3704       sv++;
3705     }
3706   }
3707 }
3708 
3709 static void
pack_I422_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3710 pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3711     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3712     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3713     gint y, gint width)
3714 {
3715   int i;
3716   guint16 *restrict dy = GET_Y_LINE (y);
3717   guint16 *restrict du = GET_U_LINE (y);
3718   guint16 *restrict dv = GET_V_LINE (y);
3719   guint16 Y0, Y1, U, V;
3720   const guint16 *restrict s = src;
3721 
3722   for (i = 0; i < width - 1; i += 2) {
3723     Y0 = s[i * 4 + 1] >> 6;
3724     Y1 = s[i * 4 + 5] >> 6;
3725     U = s[i * 4 + 2] >> 6;
3726     V = s[i * 4 + 3] >> 6;
3727 
3728     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3729     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3730     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3731     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3732   }
3733   if (i == width - 1) {
3734     Y0 = s[i * 4 + 1] >> 6;
3735     U = s[i * 4 + 2] >> 6;
3736     V = s[i * 4 + 3] >> 6;
3737 
3738     GST_WRITE_UINT16_LE (dy + i, Y0);
3739     GST_WRITE_UINT16_LE (du + (i >> 1), U);
3740     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
3741   }
3742 }
3743 
3744 #define PACK_I422_10BE GST_VIDEO_FORMAT_AYUV64, unpack_I422_10BE, 1, pack_I422_10BE
3745 static void
unpack_I422_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3746 unpack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3747     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3748     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3749 {
3750   int i;
3751   const guint16 *restrict sy = GET_Y_LINE (y);
3752   const guint16 *restrict su = GET_U_LINE (y);
3753   const guint16 *restrict sv = GET_V_LINE (y);
3754   guint16 *restrict d = dest, Y, U, V;
3755 
3756   sy += x;
3757   su += x >> 1;
3758   sv += x >> 1;
3759 
3760   for (i = 0; i < width; i++) {
3761     Y = GST_READ_UINT16_BE (sy + i) << 6;
3762     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
3763     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
3764 
3765     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3766       Y |= (Y >> 10);
3767       U |= (U >> 10);
3768       V |= (V >> 10);
3769     }
3770 
3771     d[i * 4 + 0] = 0xffff;
3772     d[i * 4 + 1] = Y;
3773     d[i * 4 + 2] = U;
3774     d[i * 4 + 3] = V;
3775 
3776     if (x & 1) {
3777       x = 0;
3778       su++;
3779       sv++;
3780     }
3781   }
3782 }
3783 
3784 static void
pack_I422_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3785 pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3786     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3787     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3788     gint y, gint width)
3789 {
3790   int i;
3791   guint16 *restrict dy = GET_Y_LINE (y);
3792   guint16 *restrict du = GET_U_LINE (y);
3793   guint16 *restrict dv = GET_V_LINE (y);
3794   guint16 Y0, Y1, U, V;
3795   const guint16 *restrict s = src;
3796 
3797   for (i = 0; i < width - 1; i += 2) {
3798     Y0 = s[i * 4 + 1] >> 6;
3799     Y1 = s[i * 4 + 5] >> 6;
3800     U = s[i * 4 + 2] >> 6;
3801     V = s[i * 4 + 3] >> 6;
3802 
3803     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
3804     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
3805     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3806     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3807   }
3808   if (i == width - 1) {
3809     Y0 = s[i * 4 + 1] >> 6;
3810     U = s[i * 4 + 2] >> 6;
3811     V = s[i * 4 + 3] >> 6;
3812 
3813     GST_WRITE_UINT16_BE (dy + i, Y0);
3814     GST_WRITE_UINT16_BE (du + (i >> 1), U);
3815     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
3816   }
3817 }
3818 
3819 #define PACK_Y444_12LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_12LE, 1, pack_Y444_12LE
3820 static void
unpack_Y444_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3821 unpack_Y444_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3822     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3823     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3824 {
3825   int i;
3826   guint16 *restrict sy = GET_Y_LINE (y);
3827   guint16 *restrict su = GET_U_LINE (y);
3828   guint16 *restrict sv = GET_V_LINE (y);
3829   guint16 *restrict d = dest, Y, U, V;
3830 
3831   sy += x;
3832   su += x;
3833   sv += x;
3834 
3835   for (i = 0; i < width; i++) {
3836     Y = GST_READ_UINT16_LE (sy + i) << 4;
3837     U = GST_READ_UINT16_LE (su + i) << 4;
3838     V = GST_READ_UINT16_LE (sv + i) << 4;
3839 
3840     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3841       Y |= (Y >> 12);
3842       U |= (U >> 12);
3843       V |= (V >> 12);
3844     }
3845 
3846     d[i * 4 + 0] = 0xffff;
3847     d[i * 4 + 1] = Y;
3848     d[i * 4 + 2] = U;
3849     d[i * 4 + 3] = V;
3850   }
3851 }
3852 
3853 static void
pack_Y444_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3854 pack_Y444_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3855     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3856     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3857     gint y, gint width)
3858 {
3859   int i;
3860   guint16 *restrict dy = GET_Y_LINE (y);
3861   guint16 *restrict du = GET_U_LINE (y);
3862   guint16 *restrict dv = GET_V_LINE (y);
3863   guint16 Y, U, V;
3864   const guint16 *restrict s = src;
3865 
3866   for (i = 0; i < width; i++) {
3867     Y = (s[i * 4 + 1]) >> 4;
3868     U = (s[i * 4 + 2]) >> 4;
3869     V = (s[i * 4 + 3]) >> 4;
3870 
3871     GST_WRITE_UINT16_LE (dy + i, Y);
3872     GST_WRITE_UINT16_LE (du + i, U);
3873     GST_WRITE_UINT16_LE (dv + i, V);
3874   }
3875 }
3876 
3877 #define PACK_Y444_12BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_12BE, 1, pack_Y444_12BE
3878 static void
unpack_Y444_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3879 unpack_Y444_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3880     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3881     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3882 {
3883   int i;
3884   const guint16 *restrict sy = GET_Y_LINE (y);
3885   const guint16 *restrict su = GET_U_LINE (y);
3886   const guint16 *restrict sv = GET_V_LINE (y);
3887   guint16 *restrict d = dest, Y, U, V;
3888 
3889   sy += x;
3890   su += x;
3891   sv += x;
3892 
3893   for (i = 0; i < width; i++) {
3894     Y = GST_READ_UINT16_BE (sy + i) << 4;
3895     U = GST_READ_UINT16_BE (su + i) << 4;
3896     V = GST_READ_UINT16_BE (sv + i) << 4;
3897 
3898     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3899       Y |= (Y >> 12);
3900       U |= (U >> 12);
3901       V |= (V >> 12);
3902     }
3903 
3904     d[i * 4 + 0] = 0xffff;
3905     d[i * 4 + 1] = Y;
3906     d[i * 4 + 2] = U;
3907     d[i * 4 + 3] = V;
3908   }
3909 }
3910 
3911 static void
pack_Y444_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3912 pack_Y444_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3913     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3914     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3915     gint y, gint width)
3916 {
3917   int i;
3918   guint16 *restrict dy = GET_Y_LINE (y);
3919   guint16 *restrict du = GET_U_LINE (y);
3920   guint16 *restrict dv = GET_V_LINE (y);
3921   guint16 Y, U, V;
3922   const guint16 *restrict s = src;
3923 
3924   for (i = 0; i < width; i++) {
3925     Y = s[i * 4 + 1] >> 4;
3926     U = s[i * 4 + 2] >> 4;
3927     V = s[i * 4 + 3] >> 4;
3928 
3929     GST_WRITE_UINT16_BE (dy + i, Y);
3930     GST_WRITE_UINT16_BE (du + i, U);
3931     GST_WRITE_UINT16_BE (dv + i, V);
3932   }
3933 }
3934 
3935 #define PACK_I420_12LE GST_VIDEO_FORMAT_AYUV64, unpack_I420_12LE, 1, pack_I420_12LE
3936 static void
unpack_I420_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)3937 unpack_I420_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3938     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
3939     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
3940 {
3941   int i;
3942   gint uv = GET_UV_420 (y, flags);
3943   const guint16 *restrict sy = GET_Y_LINE (y);
3944   const guint16 *restrict su = GET_U_LINE (uv);
3945   const guint16 *restrict sv = GET_V_LINE (uv);
3946   guint16 *restrict d = dest, Y, U, V;
3947 
3948   sy += x;
3949   su += x >> 1;
3950   sv += x >> 1;
3951 
3952   for (i = 0; i < width; i++) {
3953     Y = GST_READ_UINT16_LE (sy + i) << 4;
3954     U = GST_READ_UINT16_LE (su + (i >> 1)) << 4;
3955     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 4;
3956 
3957     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
3958       Y |= (Y >> 12);
3959       U |= (U >> 12);
3960       V |= (V >> 12);
3961     }
3962 
3963     d[i * 4 + 0] = 0xffff;
3964     d[i * 4 + 1] = Y;
3965     d[i * 4 + 2] = U;
3966     d[i * 4 + 3] = V;
3967 
3968     if (x & 1) {
3969       x = 0;
3970       su++;
3971       sv++;
3972     }
3973   }
3974 }
3975 
3976 static void
pack_I420_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)3977 pack_I420_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
3978     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
3979     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
3980     gint y, gint width)
3981 {
3982   int i;
3983   gint uv = GET_UV_420 (y, flags);
3984   guint16 *restrict dy = GET_Y_LINE (y);
3985   guint16 *restrict du = GET_U_LINE (uv);
3986   guint16 *restrict dv = GET_V_LINE (uv);
3987   guint16 Y0, Y1, U, V;
3988   const guint16 *restrict s = src;
3989 
3990   if (IS_CHROMA_LINE_420 (y, flags)) {
3991     for (i = 0; i < width - 1; i += 2) {
3992       Y0 = s[i * 4 + 1] >> 4;
3993       Y1 = s[i * 4 + 5] >> 4;
3994       U = s[i * 4 + 2] >> 4;
3995       V = s[i * 4 + 3] >> 4;
3996 
3997       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
3998       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
3999       GST_WRITE_UINT16_LE (du + (i >> 1), U);
4000       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4001     }
4002     if (i == width - 1) {
4003       Y0 = s[i * 4 + 1] >> 4;
4004       U = s[i * 4 + 2] >> 4;
4005       V = s[i * 4 + 3] >> 4;
4006 
4007       GST_WRITE_UINT16_LE (dy + i, Y0);
4008       GST_WRITE_UINT16_LE (du + (i >> 1), U);
4009       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4010     }
4011   } else {
4012     for (i = 0; i < width; i++) {
4013       Y0 = s[i * 4 + 1] >> 4;
4014       GST_WRITE_UINT16_LE (dy + i, Y0);
4015     }
4016   }
4017 }
4018 
4019 #define PACK_I420_12BE GST_VIDEO_FORMAT_AYUV64, unpack_I420_12BE, 1, pack_I420_12BE
4020 static void
unpack_I420_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4021 unpack_I420_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4022     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4023     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4024 {
4025   int i;
4026   gint uv = GET_UV_420 (y, flags);
4027   const guint16 *restrict sy = GET_Y_LINE (y);
4028   const guint16 *restrict su = GET_U_LINE (uv);
4029   const guint16 *restrict sv = GET_V_LINE (uv);
4030   guint16 *restrict d = dest, Y, U, V;
4031 
4032   sy += x;
4033   su += x >> 1;
4034   sv += x >> 1;
4035 
4036   for (i = 0; i < width; i++) {
4037     Y = GST_READ_UINT16_BE (sy + i) << 4;
4038     U = GST_READ_UINT16_BE (su + (i >> 1)) << 4;
4039     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 4;
4040 
4041     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4042       Y |= (Y >> 12);
4043       U |= (U >> 12);
4044       V |= (V >> 12);
4045     }
4046 
4047     d[i * 4 + 0] = 0xffff;
4048     d[i * 4 + 1] = Y;
4049     d[i * 4 + 2] = U;
4050     d[i * 4 + 3] = V;
4051 
4052     if (x & 1) {
4053       x = 0;
4054       su++;
4055       sv++;
4056     }
4057   }
4058 }
4059 
4060 static void
pack_I420_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4061 pack_I420_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4062     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4063     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4064     gint y, gint width)
4065 {
4066   int i;
4067   gint uv = GET_UV_420 (y, flags);
4068   guint16 *restrict dy = GET_Y_LINE (y);
4069   guint16 *restrict du = GET_U_LINE (uv);
4070   guint16 *restrict dv = GET_V_LINE (uv);
4071   guint16 Y0, Y1, U, V;
4072   const guint16 *restrict s = src;
4073 
4074   if (IS_CHROMA_LINE_420 (y, flags)) {
4075     for (i = 0; i < width - 1; i += 2) {
4076       Y0 = s[i * 4 + 1] >> 4;
4077       Y1 = s[i * 4 + 5] >> 4;
4078       U = s[i * 4 + 2] >> 4;
4079       V = s[i * 4 + 3] >> 4;
4080 
4081       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
4082       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
4083       GST_WRITE_UINT16_BE (du + (i >> 1), U);
4084       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4085     }
4086     if (i == width - 1) {
4087       Y0 = s[i * 4 + 1] >> 4;
4088       U = s[i * 4 + 2] >> 4;
4089       V = s[i * 4 + 3] >> 4;
4090 
4091       GST_WRITE_UINT16_BE (dy + i, Y0);
4092       GST_WRITE_UINT16_BE (du + (i >> 1), U);
4093       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4094     }
4095   } else {
4096     for (i = 0; i < width; i++) {
4097       Y0 = s[i * 4 + 1] >> 4;
4098       GST_WRITE_UINT16_BE (dy + i, Y0);
4099     }
4100   }
4101 }
4102 
4103 #define PACK_I422_12LE GST_VIDEO_FORMAT_AYUV64, unpack_I422_12LE, 1, pack_I422_12LE
4104 static void
unpack_I422_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4105 unpack_I422_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4106     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4107     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4108 {
4109   int i;
4110   const guint16 *restrict sy = GET_Y_LINE (y);
4111   const guint16 *restrict su = GET_U_LINE (y);
4112   const guint16 *restrict sv = GET_V_LINE (y);
4113   guint16 *restrict d = dest, Y, U, V;
4114 
4115   sy += x;
4116   su += x >> 1;
4117   sv += x >> 1;
4118 
4119   for (i = 0; i < width; i++) {
4120     Y = GST_READ_UINT16_LE (sy + i) << 4;
4121     U = GST_READ_UINT16_LE (su + (i >> 1)) << 4;
4122     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 4;
4123 
4124     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4125       Y |= (Y >> 12);
4126       U |= (U >> 12);
4127       V |= (V >> 12);
4128     }
4129 
4130     d[i * 4 + 0] = 0xffff;
4131     d[i * 4 + 1] = Y;
4132     d[i * 4 + 2] = U;
4133     d[i * 4 + 3] = V;
4134 
4135     if (x & 1) {
4136       x = 0;
4137       su++;
4138       sv++;
4139     }
4140   }
4141 }
4142 
4143 static void
pack_I422_12LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4144 pack_I422_12LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4145     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4146     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4147     gint y, gint width)
4148 {
4149   int i;
4150   guint16 *restrict dy = GET_Y_LINE (y);
4151   guint16 *restrict du = GET_U_LINE (y);
4152   guint16 *restrict dv = GET_V_LINE (y);
4153   guint16 Y0, Y1, U, V;
4154   const guint16 *restrict s = src;
4155 
4156   for (i = 0; i < width - 1; i += 2) {
4157     Y0 = s[i * 4 + 1] >> 4;
4158     Y1 = s[i * 4 + 5] >> 4;
4159     U = s[i * 4 + 2] >> 4;
4160     V = s[i * 4 + 3] >> 4;
4161 
4162     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
4163     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
4164     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4165     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4166   }
4167   if (i == width - 1) {
4168     Y0 = s[i * 4 + 1] >> 4;
4169     U = s[i * 4 + 2] >> 4;
4170     V = s[i * 4 + 3] >> 4;
4171 
4172     GST_WRITE_UINT16_LE (dy + i, Y0);
4173     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4174     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4175   }
4176 }
4177 
4178 #define PACK_I422_12BE GST_VIDEO_FORMAT_AYUV64, unpack_I422_12BE, 1, pack_I422_12BE
4179 static void
unpack_I422_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4180 unpack_I422_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4181     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4182     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4183 {
4184   int i;
4185   const guint16 *restrict sy = GET_Y_LINE (y);
4186   const guint16 *restrict su = GET_U_LINE (y);
4187   const guint16 *restrict sv = GET_V_LINE (y);
4188   guint16 *restrict d = dest, Y, U, V;
4189 
4190   sy += x;
4191   su += x >> 1;
4192   sv += x >> 1;
4193 
4194   for (i = 0; i < width; i++) {
4195     Y = GST_READ_UINT16_BE (sy + i) << 4;
4196     U = GST_READ_UINT16_BE (su + (i >> 1)) << 4;
4197     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 4;
4198 
4199     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4200       Y |= (Y >> 12);
4201       U |= (U >> 12);
4202       V |= (V >> 12);
4203     }
4204 
4205     d[i * 4 + 0] = 0xffff;
4206     d[i * 4 + 1] = Y;
4207     d[i * 4 + 2] = U;
4208     d[i * 4 + 3] = V;
4209 
4210     if (x & 1) {
4211       x = 0;
4212       su++;
4213       sv++;
4214     }
4215   }
4216 }
4217 
4218 static void
pack_I422_12BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4219 pack_I422_12BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4220     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4221     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4222     gint y, gint width)
4223 {
4224   int i;
4225   guint16 *restrict dy = GET_Y_LINE (y);
4226   guint16 *restrict du = GET_U_LINE (y);
4227   guint16 *restrict dv = GET_V_LINE (y);
4228   guint16 Y0, Y1, U, V;
4229   const guint16 *restrict s = src;
4230 
4231   for (i = 0; i < width - 1; i += 2) {
4232     Y0 = s[i * 4 + 1] >> 4;
4233     Y1 = s[i * 4 + 5] >> 4;
4234     U = s[i * 4 + 2] >> 4;
4235     V = s[i * 4 + 3] >> 4;
4236 
4237     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
4238     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
4239     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4240     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4241   }
4242   if (i == width - 1) {
4243     Y0 = s[i * 4 + 1] >> 4;
4244     U = s[i * 4 + 2] >> 4;
4245     V = s[i * 4 + 3] >> 4;
4246 
4247     GST_WRITE_UINT16_BE (dy + i, Y0);
4248     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4249     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4250   }
4251 }
4252 
4253 #define PACK_A444_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A444_10LE, 1, pack_A444_10LE
4254 static void
unpack_A444_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4255 unpack_A444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4256     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4257     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4258 {
4259   int i;
4260   guint16 *restrict sa = GET_A_LINE (y);
4261   guint16 *restrict sy = GET_Y_LINE (y);
4262   guint16 *restrict su = GET_U_LINE (y);
4263   guint16 *restrict sv = GET_V_LINE (y);
4264   guint16 *restrict d = dest, A, Y, U, V;
4265 
4266   sa += x;
4267   sy += x;
4268   su += x;
4269   sv += x;
4270 
4271   for (i = 0; i < width; i++) {
4272     A = GST_READ_UINT16_LE (sa + i) << 6;
4273     Y = GST_READ_UINT16_LE (sy + i) << 6;
4274     U = GST_READ_UINT16_LE (su + i) << 6;
4275     V = GST_READ_UINT16_LE (sv + i) << 6;
4276 
4277     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4278       A |= (A >> 10);
4279       Y |= (Y >> 10);
4280       U |= (U >> 10);
4281       V |= (V >> 10);
4282     }
4283 
4284     d[i * 4 + 0] = A;
4285     d[i * 4 + 1] = Y;
4286     d[i * 4 + 2] = U;
4287     d[i * 4 + 3] = V;
4288   }
4289 }
4290 
4291 static void
pack_A444_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4292 pack_A444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4293     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4294     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4295     gint y, gint width)
4296 {
4297   int i;
4298   guint16 *restrict da = GET_A_LINE (y);
4299   guint16 *restrict dy = GET_Y_LINE (y);
4300   guint16 *restrict du = GET_U_LINE (y);
4301   guint16 *restrict dv = GET_V_LINE (y);
4302   guint16 A, Y, U, V;
4303   const guint16 *restrict s = src;
4304 
4305   for (i = 0; i < width; i++) {
4306     A = (s[i * 4 + 0]) >> 6;
4307     Y = (s[i * 4 + 1]) >> 6;
4308     U = (s[i * 4 + 2]) >> 6;
4309     V = (s[i * 4 + 3]) >> 6;
4310 
4311     GST_WRITE_UINT16_LE (da + i, A);
4312     GST_WRITE_UINT16_LE (dy + i, Y);
4313     GST_WRITE_UINT16_LE (du + i, U);
4314     GST_WRITE_UINT16_LE (dv + i, V);
4315   }
4316 }
4317 
4318 #define PACK_A444_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A444_10BE, 1, pack_A444_10BE
4319 static void
unpack_A444_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4320 unpack_A444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4321     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4322     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4323 {
4324   int i;
4325   const guint16 *restrict sa = GET_A_LINE (y);
4326   const guint16 *restrict sy = GET_Y_LINE (y);
4327   const guint16 *restrict su = GET_U_LINE (y);
4328   const guint16 *restrict sv = GET_V_LINE (y);
4329   guint16 *restrict d = dest, A, Y, U, V;
4330 
4331   sa += x;
4332   sy += x;
4333   su += x;
4334   sv += x;
4335 
4336   for (i = 0; i < width; i++) {
4337     A = GST_READ_UINT16_BE (sa + i) << 6;
4338     Y = GST_READ_UINT16_BE (sy + i) << 6;
4339     U = GST_READ_UINT16_BE (su + i) << 6;
4340     V = GST_READ_UINT16_BE (sv + i) << 6;
4341 
4342     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4343       A |= (A >> 10);
4344       Y |= (Y >> 10);
4345       U |= (U >> 10);
4346       V |= (V >> 10);
4347     }
4348 
4349     d[i * 4 + 0] = A;
4350     d[i * 4 + 1] = Y;
4351     d[i * 4 + 2] = U;
4352     d[i * 4 + 3] = V;
4353   }
4354 }
4355 
4356 static void
pack_A444_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4357 pack_A444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4358     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4359     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4360     gint y, gint width)
4361 {
4362   int i;
4363   guint16 *restrict da = GET_A_LINE (y);
4364   guint16 *restrict dy = GET_Y_LINE (y);
4365   guint16 *restrict du = GET_U_LINE (y);
4366   guint16 *restrict dv = GET_V_LINE (y);
4367   guint16 A, Y, U, V;
4368   const guint16 *restrict s = src;
4369 
4370   for (i = 0; i < width; i++) {
4371     A = s[i * 4 + 0] >> 6;
4372     Y = s[i * 4 + 1] >> 6;
4373     U = s[i * 4 + 2] >> 6;
4374     V = s[i * 4 + 3] >> 6;
4375 
4376     GST_WRITE_UINT16_BE (da + i, A);
4377     GST_WRITE_UINT16_BE (dy + i, Y);
4378     GST_WRITE_UINT16_BE (du + i, U);
4379     GST_WRITE_UINT16_BE (dv + i, V);
4380   }
4381 }
4382 
4383 #define PACK_A420_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A420_10LE, 1, pack_A420_10LE
4384 static void
unpack_A420_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4385 unpack_A420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4386     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4387     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4388 {
4389   int i;
4390   gint uv = GET_UV_420 (y, flags);
4391   const guint16 *restrict sa = GET_A_LINE (y);
4392   const guint16 *restrict sy = GET_Y_LINE (y);
4393   const guint16 *restrict su = GET_U_LINE (uv);
4394   const guint16 *restrict sv = GET_V_LINE (uv);
4395   guint16 *restrict d = dest, A, Y, U, V;
4396 
4397   sa += x;
4398   sy += x;
4399   su += x >> 1;
4400   sv += x >> 1;
4401 
4402   for (i = 0; i < width; i++) {
4403     A = GST_READ_UINT16_LE (sa + i) << 6;
4404     Y = GST_READ_UINT16_LE (sy + i) << 6;
4405     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
4406     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
4407 
4408     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4409       A |= (A >> 10);
4410       Y |= (Y >> 10);
4411       U |= (U >> 10);
4412       V |= (V >> 10);
4413     }
4414 
4415     d[i * 4 + 0] = A;
4416     d[i * 4 + 1] = Y;
4417     d[i * 4 + 2] = U;
4418     d[i * 4 + 3] = V;
4419 
4420     if (x & 1) {
4421       x = 0;
4422       su++;
4423       sv++;
4424     }
4425   }
4426 }
4427 
4428 static void
pack_A420_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4429 pack_A420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4430     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4431     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4432     gint y, gint width)
4433 {
4434   int i;
4435   gint uv = GET_UV_420 (y, flags);
4436   guint16 *restrict da = GET_A_LINE (y);
4437   guint16 *restrict dy = GET_Y_LINE (y);
4438   guint16 *restrict du = GET_U_LINE (uv);
4439   guint16 *restrict dv = GET_V_LINE (uv);
4440   guint16 A0, Y0, A1, Y1, U, V;
4441   const guint16 *restrict s = src;
4442 
4443   if (IS_CHROMA_LINE_420 (y, flags)) {
4444     for (i = 0; i < width - 1; i += 2) {
4445       A0 = s[i * 4 + 0] >> 6;
4446       Y0 = s[i * 4 + 1] >> 6;
4447       A1 = s[i * 4 + 4] >> 6;
4448       Y1 = s[i * 4 + 5] >> 6;
4449       U = s[i * 4 + 2] >> 6;
4450       V = s[i * 4 + 3] >> 6;
4451 
4452       GST_WRITE_UINT16_LE (da + i + 0, A0);
4453       GST_WRITE_UINT16_LE (dy + i + 0, Y0);
4454       GST_WRITE_UINT16_LE (da + i + 1, A1);
4455       GST_WRITE_UINT16_LE (dy + i + 1, Y1);
4456       GST_WRITE_UINT16_LE (du + (i >> 1), U);
4457       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4458     }
4459     if (i == width - 1) {
4460       A0 = s[i * 4 + 0] >> 6;
4461       Y0 = s[i * 4 + 1] >> 6;
4462       U = s[i * 4 + 2] >> 6;
4463       V = s[i * 4 + 3] >> 6;
4464 
4465       GST_WRITE_UINT16_LE (da + i, A0);
4466       GST_WRITE_UINT16_LE (dy + i, Y0);
4467       GST_WRITE_UINT16_LE (du + (i >> 1), U);
4468       GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4469     }
4470   } else {
4471     for (i = 0; i < width; i++) {
4472       A0 = s[i * 4 + 0] >> 6;
4473       Y0 = s[i * 4 + 1] >> 6;
4474       GST_WRITE_UINT16_LE (da + i, A0);
4475       GST_WRITE_UINT16_LE (dy + i, Y0);
4476     }
4477   }
4478 }
4479 
4480 #define PACK_A420_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A420_10BE, 1, pack_A420_10BE
4481 static void
unpack_A420_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4482 unpack_A420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4483     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4484     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4485 {
4486   int i;
4487   gint uv = GET_UV_420 (y, flags);
4488   const guint16 *restrict sa = GET_A_LINE (y);
4489   const guint16 *restrict sy = GET_Y_LINE (y);
4490   const guint16 *restrict su = GET_U_LINE (uv);
4491   const guint16 *restrict sv = GET_V_LINE (uv);
4492   guint16 *restrict d = dest, A, Y, U, V;
4493 
4494   sa += x;
4495   sy += x;
4496   su += x >> 1;
4497   sv += x >> 1;
4498 
4499   for (i = 0; i < width; i++) {
4500     A = GST_READ_UINT16_BE (sa + i) << 6;
4501     Y = GST_READ_UINT16_BE (sy + i) << 6;
4502     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
4503     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
4504 
4505     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4506       A |= (A >> 10);
4507       Y |= (Y >> 10);
4508       U |= (U >> 10);
4509       V |= (V >> 10);
4510     }
4511 
4512     d[i * 4 + 0] = A;
4513     d[i * 4 + 1] = Y;
4514     d[i * 4 + 2] = U;
4515     d[i * 4 + 3] = V;
4516 
4517     if (x & 1) {
4518       x = 0;
4519       su++;
4520       sv++;
4521     }
4522   }
4523 }
4524 
4525 static void
pack_A420_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4526 pack_A420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4527     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4528     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4529     gint y, gint width)
4530 {
4531   int i;
4532   gint uv = GET_UV_420 (y, flags);
4533   guint16 *restrict da = GET_A_LINE (y);
4534   guint16 *restrict dy = GET_Y_LINE (y);
4535   guint16 *restrict du = GET_U_LINE (uv);
4536   guint16 *restrict dv = GET_V_LINE (uv);
4537   guint16 A0, Y0, A1, Y1, U, V;
4538   const guint16 *restrict s = src;
4539 
4540   if (IS_CHROMA_LINE_420 (y, flags)) {
4541     for (i = 0; i < width - 1; i += 2) {
4542       A0 = s[i * 4 + 0] >> 6;
4543       Y0 = s[i * 4 + 1] >> 6;
4544       A1 = s[i * 4 + 4] >> 6;
4545       Y1 = s[i * 4 + 5] >> 6;
4546       U = s[i * 4 + 2] >> 6;
4547       V = s[i * 4 + 3] >> 6;
4548 
4549       GST_WRITE_UINT16_BE (da + i + 0, A0);
4550       GST_WRITE_UINT16_BE (dy + i + 0, Y0);
4551       GST_WRITE_UINT16_BE (da + i + 1, A1);
4552       GST_WRITE_UINT16_BE (dy + i + 1, Y1);
4553       GST_WRITE_UINT16_BE (du + (i >> 1), U);
4554       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4555     }
4556     if (i == width - 1) {
4557       A0 = s[i * 4 + 0] >> 6;
4558       Y0 = s[i * 4 + 1] >> 6;
4559       U = s[i * 4 + 2] >> 6;
4560       V = s[i * 4 + 3] >> 6;
4561 
4562       GST_WRITE_UINT16_BE (da + i, A0);
4563       GST_WRITE_UINT16_BE (dy + i, Y0);
4564       GST_WRITE_UINT16_BE (du + (i >> 1), U);
4565       GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4566     }
4567   } else {
4568     for (i = 0; i < width; i++) {
4569       A0 = s[i * 4 + 0] >> 6;
4570       Y0 = s[i * 4 + 1] >> 6;
4571       GST_WRITE_UINT16_BE (da + i, A0);
4572       GST_WRITE_UINT16_BE (dy + i, Y0);
4573     }
4574   }
4575 }
4576 
4577 #define PACK_A422_10LE GST_VIDEO_FORMAT_AYUV64, unpack_A422_10LE, 1, pack_A422_10LE
4578 static void
unpack_A422_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4579 unpack_A422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4580     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4581     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4582 {
4583   int i;
4584   const guint16 *restrict sa = GET_A_LINE (y);
4585   const guint16 *restrict sy = GET_Y_LINE (y);
4586   const guint16 *restrict su = GET_U_LINE (y);
4587   const guint16 *restrict sv = GET_V_LINE (y);
4588   guint16 *restrict d = dest, A, Y, U, V;
4589 
4590   sa += x;
4591   sy += x;
4592   su += x >> 1;
4593   sv += x >> 1;
4594 
4595   for (i = 0; i < width; i++) {
4596     A = GST_READ_UINT16_LE (sa + i) << 6;
4597     Y = GST_READ_UINT16_LE (sy + i) << 6;
4598     U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
4599     V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
4600 
4601     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4602       A |= (A >> 10);
4603       Y |= (Y >> 10);
4604       U |= (U >> 10);
4605       V |= (V >> 10);
4606     }
4607 
4608     d[i * 4 + 0] = A;
4609     d[i * 4 + 1] = Y;
4610     d[i * 4 + 2] = U;
4611     d[i * 4 + 3] = V;
4612 
4613     if (x & 1) {
4614       x = 0;
4615       su++;
4616       sv++;
4617     }
4618   }
4619 }
4620 
4621 static void
pack_A422_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4622 pack_A422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4623     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4624     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4625     gint y, gint width)
4626 {
4627   int i;
4628   guint16 *restrict da = GET_A_LINE (y);
4629   guint16 *restrict dy = GET_Y_LINE (y);
4630   guint16 *restrict du = GET_U_LINE (y);
4631   guint16 *restrict dv = GET_V_LINE (y);
4632   guint16 A0, Y0, A1, Y1, U, V;
4633   const guint16 *restrict s = src;
4634 
4635   for (i = 0; i < width - 1; i += 2) {
4636     A0 = s[i * 4 + 0] >> 6;
4637     Y0 = s[i * 4 + 1] >> 6;
4638     A1 = s[i * 4 + 4] >> 6;
4639     Y1 = s[i * 4 + 5] >> 6;
4640     U = s[i * 4 + 2] >> 6;
4641     V = s[i * 4 + 3] >> 6;
4642 
4643     GST_WRITE_UINT16_LE (da + i + 0, A0);
4644     GST_WRITE_UINT16_LE (dy + i + 0, Y0);
4645     GST_WRITE_UINT16_LE (da + i + 1, A1);
4646     GST_WRITE_UINT16_LE (dy + i + 1, Y1);
4647     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4648     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4649   }
4650   if (i == width - 1) {
4651     A0 = s[i * 4 + 0] >> 6;
4652     Y0 = s[i * 4 + 1] >> 6;
4653     U = s[i * 4 + 2] >> 6;
4654     V = s[i * 4 + 3] >> 6;
4655 
4656     GST_WRITE_UINT16_LE (da + i, A0);
4657     GST_WRITE_UINT16_LE (dy + i, Y0);
4658     GST_WRITE_UINT16_LE (du + (i >> 1), U);
4659     GST_WRITE_UINT16_LE (dv + (i >> 1), V);
4660   }
4661 }
4662 
4663 #define PACK_A422_10BE GST_VIDEO_FORMAT_AYUV64, unpack_A422_10BE, 1, pack_A422_10BE
4664 static void
unpack_A422_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4665 unpack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4666     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4667     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4668 {
4669   int i;
4670   const guint16 *restrict sa = GET_A_LINE (y);
4671   const guint16 *restrict sy = GET_Y_LINE (y);
4672   const guint16 *restrict su = GET_U_LINE (y);
4673   const guint16 *restrict sv = GET_V_LINE (y);
4674   guint16 *restrict d = dest, A, Y, U, V;
4675 
4676   sa += x;
4677   sy += x;
4678   su += x >> 1;
4679   sv += x >> 1;
4680 
4681   for (i = 0; i < width; i++) {
4682     A = GST_READ_UINT16_BE (sa + i) << 6;
4683     Y = GST_READ_UINT16_BE (sy + i) << 6;
4684     U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
4685     V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
4686 
4687     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4688       A |= (A >> 10);
4689       Y |= (Y >> 10);
4690       U |= (U >> 10);
4691       V |= (V >> 10);
4692     }
4693 
4694     d[i * 4 + 0] = A;
4695     d[i * 4 + 1] = Y;
4696     d[i * 4 + 2] = U;
4697     d[i * 4 + 3] = V;
4698 
4699     if (x & 1) {
4700       x = 0;
4701       su++;
4702       sv++;
4703     }
4704   }
4705 }
4706 
4707 static void
pack_A422_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4708 pack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4709     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4710     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4711     gint y, gint width)
4712 {
4713   int i;
4714   guint16 *restrict da = GET_A_LINE (y);
4715   guint16 *restrict dy = GET_Y_LINE (y);
4716   guint16 *restrict du = GET_U_LINE (y);
4717   guint16 *restrict dv = GET_V_LINE (y);
4718   guint16 A0, Y0, A1, Y1, U, V;
4719   const guint16 *restrict s = src;
4720 
4721   for (i = 0; i < width - 1; i += 2) {
4722     A0 = s[i * 4 + 0] >> 6;
4723     Y0 = s[i * 4 + 1] >> 6;
4724     A1 = s[i * 4 + 4] >> 6;
4725     Y1 = s[i * 4 + 5] >> 6;
4726     U = s[i * 4 + 2] >> 6;
4727     V = s[i * 4 + 3] >> 6;
4728 
4729     GST_WRITE_UINT16_BE (da + i + 0, A0);
4730     GST_WRITE_UINT16_BE (dy + i + 0, Y0);
4731     GST_WRITE_UINT16_BE (da + i + 1, A1);
4732     GST_WRITE_UINT16_BE (dy + i + 1, Y1);
4733     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4734     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4735   }
4736   if (i == width - 1) {
4737     A0 = s[i * 4 + 0] >> 6;
4738     Y0 = s[i * 4 + 1] >> 6;
4739     U = s[i * 4 + 2] >> 6;
4740     V = s[i * 4 + 3] >> 6;
4741 
4742     GST_WRITE_UINT16_BE (da + i, A0);
4743     GST_WRITE_UINT16_BE (dy + i, Y0);
4744     GST_WRITE_UINT16_BE (du + (i >> 1), U);
4745     GST_WRITE_UINT16_BE (dv + (i >> 1), V);
4746   }
4747 }
4748 
4749 static void
get_tile_NV12(gint tile_width,gint ts,gint tx,gint ty,GstVideoTileMode mode,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gpointer tile_data[GST_VIDEO_MAX_PLANES],gint tile_stride[GST_VIDEO_MAX_PLANES])4750 get_tile_NV12 (gint tile_width, gint ts, gint tx, gint ty,
4751     GstVideoTileMode mode,
4752     const gpointer data[GST_VIDEO_MAX_PLANES],
4753     const gint stride[GST_VIDEO_MAX_PLANES],
4754     gpointer tile_data[GST_VIDEO_MAX_PLANES],
4755     gint tile_stride[GST_VIDEO_MAX_PLANES])
4756 {
4757   gsize offset;
4758 
4759   /* index of Y tile */
4760   offset = gst_video_tile_get_index (mode,
4761       tx, ty, GST_VIDEO_TILE_X_TILES (stride[0]),
4762       GST_VIDEO_TILE_Y_TILES (stride[0]));
4763   offset <<= ts;
4764   tile_data[0] = ((guint8 *) data[0]) + offset;
4765 
4766   /* index of UV tile */
4767   offset = gst_video_tile_get_index (mode,
4768       tx, ty >> 1, GST_VIDEO_TILE_X_TILES (stride[1]),
4769       GST_VIDEO_TILE_Y_TILES (stride[1]));
4770   offset <<= ts;
4771   /* On odd rows we return the second part of the UV tile */
4772   offset |= (ty & 1) << (ts - 1);
4773   tile_data[1] = ((guint8 *) data[1]) + offset;
4774 
4775   tile_stride[0] = tile_stride[1] = tile_width;
4776 }
4777 
4778 #define PACK_NV12_TILED GST_VIDEO_FORMAT_AYUV, unpack_NV12_TILED, 1, pack_NV12_TILED
4779 static void
unpack_NV12_TILED(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4780 unpack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4781     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4782     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4783 {
4784   const GstVideoFormatInfo *unpack_info, *finfo;
4785   guint8 *line = dest;
4786   gint ws, hs, ts, tile_width;
4787   gint ntx, tx, ty;
4788   gint unpack_pstride;
4789 
4790   ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
4791   hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
4792   ts = ws + hs;
4793 
4794   tile_width = 1 << ws;
4795 
4796   /* we reuse these unpack functions */
4797   finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
4798 
4799   /* get pstride of unpacked format */
4800   unpack_info = gst_video_format_get_info (info->unpack_format);
4801   unpack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (unpack_info, 0);
4802 
4803   /* first x tile to convert */
4804   tx = x >> ws;
4805   /* Last tile to convert */
4806   ntx = ((x + width - 1) >> ws) + 1;
4807   /* The row we are going to convert */
4808   ty = y >> hs;
4809 
4810   /* y position in a tile */
4811   y = y & ((1 << hs) - 1);
4812   /* x position in a tile */
4813   x = x & (tile_width - 1);
4814 
4815   for (; tx < ntx; tx++) {
4816     gpointer tdata[GST_VIDEO_MAX_PLANES];
4817     gint tstride[GST_VIDEO_MAX_PLANES];
4818     gint unpack_width;
4819 
4820     get_tile_NV12 (tile_width, ts, tx, ty, info->tile_mode,
4821         data, stride, tdata, tstride);
4822 
4823     /* the number of bytes left to unpack */
4824     unpack_width = MIN (width - x, tile_width - x);
4825 
4826     finfo->unpack_func (finfo, flags, line, tdata, tstride, x, y, unpack_width);
4827 
4828     x = 0;
4829     width -= unpack_width;
4830     line += unpack_width * unpack_pstride;
4831   }
4832 }
4833 
4834 static void
pack_NV12_TILED(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4835 pack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4836     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4837     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4838     gint y, gint width)
4839 {
4840   const GstVideoFormatInfo *pack_info, *finfo;
4841   guint8 *line = src;
4842   gint ws, hs, ts, tile_width;
4843   gint ntx, tx, ty;
4844   gint pack_pstride;
4845 
4846   ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
4847   hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
4848   ts = ws + hs;
4849 
4850   tile_width = 1 << ws;
4851 
4852   /* we reuse these pack functions */
4853   finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
4854 
4855   /* get pstride of packed format */
4856   pack_info = gst_video_format_get_info (info->unpack_format);
4857   pack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (pack_info, 0);
4858 
4859   /* Last tile to convert */
4860   ntx = ((width - 1) >> ws) + 1;
4861   /* The row we are going to convert */
4862   ty = y >> hs;
4863 
4864   /* y position in a tile */
4865   y = y & ((1 << hs) - 1);
4866 
4867   for (tx = 0; tx < ntx; tx++) {
4868     gpointer tdata[GST_VIDEO_MAX_PLANES];
4869     gint tstride[GST_VIDEO_MAX_PLANES];
4870     gint pack_width;
4871 
4872     get_tile_NV12 (tile_width, ts, tx, ty, info->tile_mode,
4873         data, stride, tdata, tstride);
4874 
4875     /* the number of bytes left to pack */
4876     pack_width = MIN (width, tile_width);
4877 
4878     finfo->pack_func (finfo, flags, line, sstride, tdata, tstride,
4879         chroma_site, y, pack_width);
4880 
4881     width -= pack_width;
4882     line += pack_width * pack_pstride;
4883   }
4884 }
4885 
4886 #define PACK_P010_10BE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10BE, 1, pack_P010_10BE
4887 static void
unpack_P010_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)4888 unpack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4889     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
4890     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
4891 {
4892   int i;
4893   gint uv = GET_UV_420 (y, flags);
4894   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
4895   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
4896   guint16 *restrict d = dest, Y0, Y1, U, V;
4897 
4898   sy += x;
4899   suv += (x & ~1);
4900 
4901   if (x & 1) {
4902     Y0 = GST_READ_UINT16_BE (sy);
4903     U = GST_READ_UINT16_BE (suv);
4904     V = GST_READ_UINT16_BE (suv + 1);
4905 
4906     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4907       Y0 |= (Y0 >> 10);
4908       U |= (U >> 10);
4909       V |= (V >> 10);
4910     }
4911 
4912     d[0] = 0xffff;
4913     d[1] = Y0;
4914     d[2] = U;
4915     d[3] = V;
4916     width--;
4917     d += 4;
4918     sy += 1;
4919     suv += 2;
4920   }
4921 
4922   for (i = 0; i < width / 2; i++) {
4923     Y0 = GST_READ_UINT16_BE (sy + 2 * i);
4924     Y1 = GST_READ_UINT16_BE (sy + 2 * i + 1);
4925     U = GST_READ_UINT16_BE (suv + 2 * i);
4926     V = GST_READ_UINT16_BE (suv + 2 * i + 1);
4927 
4928     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4929       Y0 |= (Y0 >> 10);
4930       Y1 |= (Y1 >> 10);
4931       U |= (U >> 10);
4932       V |= (V >> 10);
4933     }
4934 
4935     d[i * 8 + 0] = 0xffff;
4936     d[i * 8 + 1] = Y0;
4937     d[i * 8 + 2] = U;
4938     d[i * 8 + 3] = V;
4939     d[i * 8 + 4] = 0xffff;
4940     d[i * 8 + 5] = Y1;
4941     d[i * 8 + 6] = U;
4942     d[i * 8 + 7] = V;
4943   }
4944 
4945   if (width & 1) {
4946     gint i = width - 1;
4947 
4948     Y0 = GST_READ_UINT16_BE (sy + i);
4949     U = GST_READ_UINT16_BE (suv + i);
4950     V = GST_READ_UINT16_BE (suv + i + 1);
4951 
4952     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
4953       Y0 |= (Y0 >> 10);
4954       U |= (U >> 10);
4955       V |= (V >> 10);
4956     }
4957 
4958     d[i * 4 + 0] = 0xffff;
4959     d[i * 4 + 1] = Y0;
4960     d[i * 4 + 2] = U;
4961     d[i * 4 + 3] = V;
4962   }
4963 }
4964 
4965 static void
pack_P010_10BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)4966 pack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
4967     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
4968     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
4969     gint y, gint width)
4970 {
4971   int i;
4972   gint uv = GET_UV_420 (y, flags);
4973   guint16 *restrict dy = GET_PLANE_LINE (0, y);
4974   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
4975   guint16 Y0, Y1, U, V;
4976   const guint16 *restrict s = src;
4977 
4978   if (IS_CHROMA_LINE_420 (y, flags)) {
4979     for (i = 0; i < width / 2; i++) {
4980       Y0 = s[i * 8 + 1] & 0xffc0;
4981       Y1 = s[i * 8 + 5] & 0xffc0;
4982       U = s[i * 8 + 2] & 0xffc0;
4983       V = s[i * 8 + 3] & 0xffc0;
4984 
4985       GST_WRITE_UINT16_BE (dy + i * 2 + 0, Y0);
4986       GST_WRITE_UINT16_BE (dy + i * 2 + 1, Y1);
4987       GST_WRITE_UINT16_BE (duv + i * 2 + 0, U);
4988       GST_WRITE_UINT16_BE (duv + i * 2 + 1, V);
4989     }
4990     if (width & 1) {
4991       gint i = width - 1;
4992 
4993       Y0 = s[i * 4 + 1] & 0xffc0;
4994       U = s[i * 4 + 2] & 0xffc0;
4995       V = s[i * 4 + 3] & 0xffc0;
4996 
4997       GST_WRITE_UINT16_BE (dy + i, Y0);
4998       GST_WRITE_UINT16_BE (duv + i + 0, U);
4999       GST_WRITE_UINT16_BE (duv + i + 1, V);
5000     }
5001   } else {
5002     for (i = 0; i < width; i++) {
5003       Y0 = s[i * 4 + 1] & 0xffc0;
5004       GST_WRITE_UINT16_BE (dy + i, Y0);
5005     }
5006   }
5007 }
5008 
5009 #define PACK_P010_10LE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10LE, 1, pack_P010_10LE
5010 static void
unpack_P010_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5011 unpack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5012     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5013     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5014 {
5015   int i;
5016   gint uv = GET_UV_420 (y, flags);
5017   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
5018   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
5019   guint16 *restrict d = dest, Y0, Y1, U, V;
5020 
5021   sy += x;
5022   suv += (x & ~1);
5023 
5024   if (x & 1) {
5025     Y0 = GST_READ_UINT16_LE (sy);
5026     U = GST_READ_UINT16_LE (suv);
5027     V = GST_READ_UINT16_LE (suv + 1);
5028 
5029     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5030       Y0 |= (Y0 >> 10);
5031       U |= (U >> 10);
5032       V |= (V >> 10);
5033     }
5034 
5035     d[0] = 0xffff;
5036     d[1] = Y0;
5037     d[2] = U;
5038     d[3] = V;
5039     width--;
5040     d += 4;
5041     sy += 1;
5042     suv += 2;
5043   }
5044 
5045   for (i = 0; i < width / 2; i++) {
5046     Y0 = GST_READ_UINT16_LE (sy + 2 * i);
5047     Y1 = GST_READ_UINT16_LE (sy + 2 * i + 1);
5048     U = GST_READ_UINT16_LE (suv + 2 * i);
5049     V = GST_READ_UINT16_LE (suv + 2 * i + 1);
5050 
5051     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5052       Y0 |= (Y0 >> 10);
5053       Y1 |= (Y1 >> 10);
5054       U |= (U >> 10);
5055       V |= (V >> 10);
5056     }
5057 
5058     d[i * 8 + 0] = 0xffff;
5059     d[i * 8 + 1] = Y0;
5060     d[i * 8 + 2] = U;
5061     d[i * 8 + 3] = V;
5062     d[i * 8 + 4] = 0xffff;
5063     d[i * 8 + 5] = Y1;
5064     d[i * 8 + 6] = U;
5065     d[i * 8 + 7] = V;
5066   }
5067 
5068   if (width & 1) {
5069     gint i = width - 1;
5070 
5071     Y0 = GST_READ_UINT16_LE (sy + i);
5072     U = GST_READ_UINT16_LE (suv + i);
5073     V = GST_READ_UINT16_LE (suv + i + 1);
5074 
5075     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5076       Y0 |= (Y0 >> 10);
5077       U |= (U >> 10);
5078       V |= (V >> 10);
5079     }
5080 
5081     d[i * 4 + 0] = 0xffff;
5082     d[i * 4 + 1] = Y0;
5083     d[i * 4 + 2] = U;
5084     d[i * 4 + 3] = V;
5085   }
5086 }
5087 
5088 static void
pack_P010_10LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5089 pack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5090     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5091     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5092     gint y, gint width)
5093 {
5094   int i;
5095   gint uv = GET_UV_420 (y, flags);
5096   guint16 *restrict dy = GET_PLANE_LINE (0, y);
5097   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
5098   guint16 Y0, Y1, U, V;
5099   const guint16 *restrict s = src;
5100 
5101   if (IS_CHROMA_LINE_420 (y, flags)) {
5102     for (i = 0; i < width / 2; i++) {
5103       Y0 = s[i * 8 + 1] & 0xffc0;
5104       Y1 = s[i * 8 + 5] & 0xffc0;
5105       U = s[i * 8 + 2] & 0xffc0;
5106       V = s[i * 8 + 3] & 0xffc0;
5107 
5108       GST_WRITE_UINT16_LE (dy + i * 2 + 0, Y0);
5109       GST_WRITE_UINT16_LE (dy + i * 2 + 1, Y1);
5110       GST_WRITE_UINT16_LE (duv + i * 2 + 0, U);
5111       GST_WRITE_UINT16_LE (duv + i * 2 + 1, V);
5112     }
5113     if (width & 1) {
5114       gint i = width - 1;
5115 
5116       Y0 = s[i * 4 + 1] & 0xffc0;
5117       U = s[i * 4 + 2] & 0xffc0;
5118       V = s[i * 4 + 3] & 0xffc0;
5119 
5120       GST_WRITE_UINT16_LE (dy + i, Y0);
5121       GST_WRITE_UINT16_LE (duv + i + 0, U);
5122       GST_WRITE_UINT16_LE (duv + i + 1, V);
5123     }
5124   } else {
5125     for (i = 0; i < width; i++) {
5126       Y0 = s[i * 4 + 1] & 0xffc0;
5127       GST_WRITE_UINT16_LE (dy + i, Y0);
5128     }
5129   }
5130 }
5131 
5132 #define PACK_GRAY10_LE32 GST_VIDEO_FORMAT_AYUV64, unpack_GRAY10_LE32, 1, pack_GRAY10_LE32
5133 static void
unpack_GRAY10_LE32(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5134 unpack_GRAY10_LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5135     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5136     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5137 {
5138   gint i;
5139   const guint32 *restrict sy = GET_PLANE_LINE (0, y);
5140   guint16 *restrict d = dest;
5141   gint num_words = (width + 2) / 3;
5142 
5143   /* Y data is packed into little endian 32bit words, with the 2 MSB being
5144    * padding. There is only 1 pattern.
5145    * -> padding | Y1 | Y2 | Y3
5146    */
5147 
5148   for (i = 0; i < num_words; i++) {
5149     gint num_comps = MIN (3, width - i * 3);
5150     guint pix = i * 3;
5151     gsize doff = pix * 4;
5152     gint c;
5153     guint32 Y;
5154 
5155     Y = GST_READ_UINT32_LE (sy + i);
5156 
5157     for (c = 0; c < num_comps; c++) {
5158       guint16 Yn;
5159 
5160       /* For Y, we simply read 10 bit and shift it out */
5161       Yn = (Y & 0x03ff) << 6;
5162       Y >>= 10;
5163 
5164       if (G_UNLIKELY (pix + c < x))
5165         continue;
5166 
5167       if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE))
5168         Yn |= Yn >> 10;
5169 
5170       d[doff + 0] = 0xffff;
5171       d[doff + 1] = Yn;
5172       d[doff + 2] = 0x8000;
5173       d[doff + 3] = 0x8000;
5174 
5175       doff += 4;
5176     }
5177   }
5178 }
5179 
5180 static void
pack_GRAY10_LE32(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5181 pack_GRAY10_LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5182     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5183     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5184     gint y, gint width)
5185 {
5186   gint i;
5187   guint32 *restrict dy = GET_PLANE_LINE (0, y);
5188   const guint16 *restrict s = src;
5189   gint num_words = (width + 2) / 3;
5190 
5191   for (i = 0; i < num_words; i++) {
5192     gint num_comps = MIN (3, width - i * 3);
5193     guint pix = i * 3;
5194     gsize soff = pix * 4;
5195     gint c;
5196     guint32 Y = 0;
5197 
5198     for (c = 0; c < num_comps; c++) {
5199       Y |= s[soff + 1] >> 6 << (10 * c);
5200       soff += 4;
5201     }
5202 
5203     GST_WRITE_UINT32_LE (dy + i, Y);
5204   }
5205 }
5206 
5207 #define PACK_NV12_10LE32 GST_VIDEO_FORMAT_AYUV64, unpack_NV12_10LE32, 1, pack_NV12_10LE32
5208 static void
unpack_NV12_10LE32(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5209 unpack_NV12_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5210     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5211     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5212 {
5213   gint i;
5214   gint uv = GET_UV_420 (y, flags);
5215   const guint32 *restrict sy = GET_PLANE_LINE (0, y);
5216   const guint32 *restrict suv = GET_PLANE_LINE (1, uv);
5217   guint16 *restrict d = dest;
5218   gint num_words = (width + 2) / 3;
5219   guint32 UV = 0;
5220   guint16 Un = 0, Vn = 0;
5221 
5222   /* Y data is packed into little endian 32bit words, with the 2 MSB being
5223    * padding. There is only 1 pattern.
5224    * -> padding | Y1 | Y2 | Y3
5225    *
5226    * UV is packed the same way, though we end up with 2 patterns:
5227    * -> U | V | U | padding
5228    * -> V | U | V | padding
5229    */
5230 
5231   /* FIXME unroll the 6 states ? */
5232 
5233   for (i = 0; i < num_words; i++) {
5234     gint num_comps = MIN (3, width - i * 3);
5235     guint pix = i * 3;
5236     gsize doff = pix * 4;
5237     gint c;
5238     guint32 Y;
5239 
5240     Y = GST_READ_UINT32_LE (sy + i);
5241 
5242     for (c = 0; c < num_comps; c++) {
5243       guint16 Yn;
5244 
5245       /* For Y, we simply read 10 bit and shift it out */
5246       Yn = (Y & 0x03ff) << 6;
5247       Y >>= 10;
5248 
5249       /* Unpacking UV has been reduced to a cycle of 6 states. The following
5250        * code is a reduce version of:
5251        * 0: - Read first UV word (UVU)
5252        *      Unpack U and V
5253        * 1: - Reused U/V from 1 (sub-sampling)
5254        * 2: - Unpack remaining U value
5255        *    - Read following UV word (VUV)
5256        *    - Unpack V value
5257        * 3: - Reuse U/V from 2 (sub-sampling)
5258        * 4: - Unpack remaining U
5259        *    - Unpack remaining V
5260        * 5: - Reuse UV/V from 4 (sub-sampling)
5261        */
5262       switch ((pix + c) % 6) {
5263         case 0:
5264           UV = GST_READ_UINT32_LE (suv + i);
5265           /* fallthrough */
5266         case 4:
5267           Un = (UV & 0x03ff) << 6;
5268           UV >>= 10;
5269           Vn = (UV & 0x03ff) << 6;
5270           UV >>= 10;
5271           break;
5272         case 2:
5273           Un = (UV & 0x03ff) << 6;
5274           UV = GST_READ_UINT32_LE (suv + i + 1);
5275           Vn = (UV & 0x03ff) << 6;
5276           UV >>= 10;
5277           break;
5278         default:
5279           /* keep value */
5280           break;
5281       }
5282 
5283       if (G_UNLIKELY (pix + c < x))
5284         continue;
5285 
5286       if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5287         Yn |= Yn >> 10;
5288         Un |= Un >> 10;
5289         Vn |= Vn >> 10;
5290       }
5291 
5292       d[doff + 0] = 0xffff;
5293       d[doff + 1] = Yn;
5294       d[doff + 2] = Un;
5295       d[doff + 3] = Vn;
5296 
5297       doff += 4;
5298     }
5299   }
5300 }
5301 
5302 static void
pack_NV12_10LE32(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5303 pack_NV12_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5304     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5305     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5306     gint y, gint width)
5307 {
5308   gint i;
5309   gint uv = GET_UV_420 (y, flags);
5310   guint32 *restrict dy = GET_PLANE_LINE (0, y);
5311   guint32 *restrict duv = GET_PLANE_LINE (1, uv);
5312   const guint16 *restrict s = src;
5313   gint num_words = (width + 2) / 3;
5314   guint32 UV = 0;
5315 
5316   /* FIXME unroll the 6 states ? */
5317 
5318   for (i = 0; i < num_words; i++) {
5319     gint num_comps = MIN (3, width - i * 3);
5320     guint pix = i * 3;
5321     gsize soff = pix * 4;
5322     gint c;
5323     guint32 Y = 0;
5324 
5325     for (c = 0; c < num_comps; c++) {
5326       Y |= s[soff + 1] >> 6 << (10 * c);
5327 
5328       if (IS_CHROMA_LINE_420 (y, flags)) {
5329         switch ((pix + c) % 6) {
5330           case 0:
5331             UV = s[soff + 2] >> 6;
5332             UV |= s[soff + 3] >> 6 << 10;
5333             break;
5334           case 2:
5335             UV |= s[soff + 2] >> 6 << 20;
5336             GST_WRITE_UINT32_LE (duv + i, UV);
5337             UV = s[soff + 3] >> 6;
5338             break;
5339           case 4:
5340             UV |= s[soff + 2] >> 6 << 10;
5341             UV |= s[soff + 3] >> 6 << 20;
5342             GST_WRITE_UINT32_LE (duv + i, UV);
5343             break;
5344           default:
5345             /* keep value */
5346             break;
5347         }
5348       }
5349 
5350       soff += 4;
5351     }
5352 
5353     GST_WRITE_UINT32_LE (dy + i, Y);
5354 
5355     if (IS_CHROMA_LINE_420 (y, flags) && num_comps < 3)
5356       GST_WRITE_UINT32_LE (duv + i, UV);
5357 
5358   }
5359 }
5360 
5361 #define PACK_NV16_10LE32 GST_VIDEO_FORMAT_AYUV64, unpack_NV16_10LE32, 1, pack_NV16_10LE32
5362 static void
unpack_NV16_10LE32(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5363 unpack_NV16_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5364     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5365     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5366 {
5367   gint i;
5368   const guint32 *restrict sy = GET_PLANE_LINE (0, y);
5369   const guint32 *restrict suv = GET_PLANE_LINE (1, y);
5370   guint16 *restrict d = dest;
5371   gint num_words = (width + 2) / 3;
5372   guint32 UV = 0;
5373   guint16 Un = 0, Vn = 0;
5374 
5375   /* Y data is packed into little endian 32bit words, with the 2 MSB being
5376    * padding. There is only 1 pattern.
5377    * -> padding | Y1 | Y2 | Y3
5378    *
5379    * UV is packed the same way, though we end up with 2 patterns:
5380    * -> U | V | U | padding
5381    * -> V | U | V | padding
5382    */
5383 
5384   /* FIXME unroll the 6 states ? */
5385 
5386   for (i = 0; i < num_words; i++) {
5387     gint num_comps = MIN (3, width - i * 3);
5388     guint pix = i * 3;
5389     gsize doff = pix * 4;
5390     gint c;
5391     guint32 Y;
5392 
5393     Y = GST_READ_UINT32_LE (sy + i);
5394 
5395     for (c = 0; c < num_comps; c++) {
5396       guint16 Yn;
5397 
5398       /* For Y, we simply read 10 bit and shift it out */
5399       Yn = (Y & 0x03ff) << 6;
5400       Y >>= 10;
5401 
5402       /* Unpacking UV has been reduced to a cycle of 6 states. The following
5403        * code is a reduce version of:
5404        * 0: - Read first UV word (UVU)
5405        *      Unpack U and V
5406        * 1: - Reused U/V from 1 (sub-sampling)
5407        * 2: - Unpack remaining U value
5408        *    - Read following UV word (VUV)
5409        *    - Unpack V value
5410        * 3: - Reuse U/V from 2 (sub-sampling)
5411        * 4: - Unpack remaining U
5412        *    - Unpack remaining V
5413        * 5: - Reuse UV/V from 4 (sub-sampling)
5414        */
5415       switch ((pix + c) % 6) {
5416         case 0:
5417           UV = GST_READ_UINT32_LE (suv + i);
5418           /* fallthrough */
5419         case 4:
5420           Un = (UV & 0x03ff) << 6;
5421           UV >>= 10;
5422           Vn = (UV & 0x03ff) << 6;
5423           UV >>= 10;
5424           break;
5425         case 2:
5426           Un = (UV & 0x03ff) << 6;
5427           UV = GST_READ_UINT32_LE (suv + i + 1);
5428           Vn = (UV & 0x03ff) << 6;
5429           UV >>= 10;
5430           break;
5431         default:
5432           /* keep value */
5433           break;
5434       }
5435 
5436       if (G_UNLIKELY (pix + c < x))
5437         continue;
5438 
5439       if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5440         Yn |= Yn >> 10;
5441         Un |= Un >> 10;
5442         Vn |= Vn >> 10;
5443       }
5444 
5445       d[doff + 0] = 0xffff;
5446       d[doff + 1] = Yn;
5447       d[doff + 2] = Un;
5448       d[doff + 3] = Vn;
5449 
5450       doff += 4;
5451     }
5452   }
5453 }
5454 
5455 static void
pack_NV16_10LE32(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5456 pack_NV16_10LE32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5457     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5458     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5459     gint y, gint width)
5460 {
5461   gint i;
5462   guint32 *restrict dy = GET_PLANE_LINE (0, y);
5463   guint32 *restrict duv = GET_PLANE_LINE (1, y);
5464   const guint16 *restrict s = src;
5465   gint num_words = (width + 2) / 3;
5466   guint32 UV = 0;
5467 
5468   /* FIXME unroll the 6 states ? */
5469 
5470   for (i = 0; i < num_words; i++) {
5471     gint num_comps = MIN (3, width - i * 3);
5472     guint pix = i * 3;
5473     gsize soff = pix * 4;
5474     gint c;
5475     guint32 Y = 0;
5476 
5477     for (c = 0; c < num_comps; c++) {
5478       Y |= s[soff + 1] >> 6 << (10 * c);
5479 
5480       switch ((pix + c) % 6) {
5481         case 0:
5482           UV = s[soff + 2] >> 6;
5483           UV |= s[soff + 3] >> 6 << 10;
5484           break;
5485         case 2:
5486           UV |= s[soff + 2] >> 6 << 20;
5487           GST_WRITE_UINT32_LE (duv + i, UV);
5488           UV = s[soff + 3] >> 6;
5489           break;
5490         case 4:
5491           UV |= s[soff + 2] >> 6 << 10;
5492           UV |= s[soff + 3] >> 6 << 20;
5493           GST_WRITE_UINT32_LE (duv + i, UV);
5494           break;
5495         default:
5496           /* keep value */
5497           break;
5498       }
5499 
5500       soff += 4;
5501     }
5502 
5503     GST_WRITE_UINT32_LE (dy + i, Y);
5504 
5505     if (num_comps < 3)
5506       GST_WRITE_UINT32_LE (duv + i, UV);
5507   }
5508 }
5509 
5510 #define PACK_NV12_10LE40 GST_VIDEO_FORMAT_AYUV64, unpack_NV12_10LE40, 1, pack_NV12_10LE40
5511 static void
unpack_NV12_10LE40(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5512 unpack_NV12_10LE40 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5513     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5514     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5515 {
5516   gint i;
5517   gint uv = GET_UV_420 (y, flags);
5518   guint16 *restrict d = dest;
5519   const guint8 *restrict sy = GET_PLANE_LINE (0, y);
5520   const guint8 *restrict suv = GET_PLANE_LINE (1, uv);
5521   guint16 Y0 = 0, Y1 = 0, Yn = 0, Un = 0, Vn = 0;
5522   guint32 UV = 0;
5523 
5524   for (i = 0; i < width; i++) {
5525     gboolean update_c = FALSE;
5526 
5527     switch (i & 3) {
5528       case 0:
5529         Y0 = GST_READ_UINT16_LE (sy);
5530         Yn = Y0 & 0x3ff;
5531         sy += 2;
5532 
5533         UV = GST_READ_UINT32_LE (suv);
5534         Un = UV & 0x3ff;
5535         Vn = (UV >> 10) & 0x3ff;
5536         suv += 4;
5537 
5538         Yn <<= 6;
5539         Un <<= 6;
5540         Vn <<= 6;
5541         update_c = TRUE;
5542         break;
5543       case 1:
5544         Y1 = GST_READ_UINT16_LE (sy);
5545         Yn = (Y0 >> 10) | ((Y1 & 0xf) << 6);
5546         sy += 2;
5547 
5548         Yn <<= 6;
5549         break;
5550       case 2:
5551         Yn = (Y1 >> 4) & 0x3ff;
5552 
5553         Un = (UV >> 20) & 0x3ff;
5554         Vn = (UV >> 30);
5555         UV = GST_READ_UINT8 (suv);
5556         Vn |= (UV << 2);
5557         suv++;
5558 
5559         Yn <<= 6;
5560         Un <<= 6;
5561         Vn <<= 6;
5562         update_c = TRUE;
5563         break;
5564       case 3:
5565         Y0 = GST_READ_UINT8 (sy);
5566         Yn = (Y1 >> 14) | (Y0 << 2);
5567         sy++;
5568 
5569         Yn <<= 6;
5570         break;
5571     }
5572 
5573     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5574       Yn |= Yn >> 10;
5575       if (update_c) {
5576         Un |= Un >> 10;
5577         Vn |= Vn >> 10;
5578       }
5579     }
5580 
5581     d[i * 4 + 0] = 0xffff;
5582     d[i * 4 + 1] = Yn;
5583     d[i * 4 + 2] = Un;
5584     d[i * 4 + 3] = Vn;
5585   }
5586 }
5587 
5588 static void
pack_NV12_10LE40(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5589 pack_NV12_10LE40 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5590     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5591     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5592     gint y, gint width)
5593 {
5594   gint i;
5595   gint uv = GET_UV_420 (y, flags);
5596   guint8 *restrict dy = GET_PLANE_LINE (0, y);
5597   guint8 *restrict duv = GET_PLANE_LINE (1, uv);
5598   guint16 Y0 = 0, Y1 = 0, Y2 = 0, Y3 = 0, U0, V0 = 0, U1 = 0, V1 = 0;
5599   const guint16 *restrict s = src;
5600 
5601   for (i = 0; i < width; i++) {
5602     switch (i & 3) {
5603       case 0:
5604         Y0 = s[i * 4 + 1] >> 6;
5605         GST_WRITE_UINT8 (dy, Y0 & 0xff);
5606         dy++;
5607 
5608         if (IS_CHROMA_LINE_420 (y, flags)) {
5609           U0 = s[i * 4 + 2] >> 6;
5610           V0 = s[i * 4 + 3] >> 6;
5611 
5612           GST_WRITE_UINT8 (duv, U0 & 0xff);
5613           duv++;
5614 
5615           GST_WRITE_UINT8 (duv, (U0 >> 8) | ((V0 & 0x3f) << 2));
5616           duv++;
5617         }
5618         break;
5619       case 1:
5620         Y1 = s[i * 4 + 1] >> 6;
5621         GST_WRITE_UINT8 (dy, (Y0 >> 8) | ((Y1 & 0x3f) << 2));
5622         dy++;
5623         break;
5624       case 2:
5625         Y2 = s[i * 4 + 1] >> 6;
5626         GST_WRITE_UINT8 (dy, (Y1 >> 6) | ((Y2 & 0xf) << 4));
5627         dy++;
5628 
5629         if (IS_CHROMA_LINE_420 (y, flags)) {
5630           U1 = s[i * 4 + 2] >> 6;
5631           V1 = s[i * 4 + 3] >> 6;
5632 
5633           GST_WRITE_UINT8 (duv, (V0 >> 6) | ((U1 & 0xf) << 4));
5634           duv++;
5635 
5636           GST_WRITE_UINT8 (duv, (U1 >> 4) | ((V1 & 0x3) << 6));
5637           duv++;
5638 
5639           GST_WRITE_UINT8 (duv, V1 >> 2);
5640           duv++;
5641         }
5642         break;
5643       case 3:
5644         Y3 = s[i * 4 + 1] >> 6;
5645         GST_WRITE_UINT8 (dy, (Y2 >> 4) | ((Y3 & 0x3) << 6));
5646         dy++;
5647         GST_WRITE_UINT8 (dy, (Y3 >> 2));
5648         dy++;
5649         break;
5650     }
5651   }
5652 
5653   switch (width & 3) {
5654     case 0:
5655       break;
5656     case 1:
5657       GST_WRITE_UINT8 (dy, Y0 >> 8);
5658       if (IS_CHROMA_LINE_420 (y, flags))
5659         GST_WRITE_UINT8 (duv, V0 >> 6);
5660       break;
5661     case 2:
5662       GST_WRITE_UINT8 (dy, Y1 >> 6);
5663       if (IS_CHROMA_LINE_420 (y, flags))
5664         GST_WRITE_UINT8 (duv, V0 >> 6);
5665       break;
5666     case 3:
5667       GST_WRITE_UINT8 (dy, Y2 >> 4);
5668       break;
5669   }
5670 }
5671 
5672 #define PACK_VUYA GST_VIDEO_FORMAT_AYUV, unpack_VUYA, 1, pack_VUYA
5673 static void
unpack_VUYA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5674 unpack_VUYA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5675     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5676     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5677 {
5678   const guint8 *restrict s = GET_LINE (y);
5679   guint8 *restrict d = dest;
5680 
5681   s += x * 4;
5682 
5683   video_orc_unpack_VUYA (d, s, width);
5684 }
5685 
5686 static void
pack_VUYA(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5687 pack_VUYA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5688     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5689     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5690     gint y, gint width)
5691 {
5692   const guint8 *restrict s = src;
5693   guint8 *restrict d = GET_LINE (y);
5694 
5695   video_orc_pack_VUYA (d, s, width);
5696 }
5697 
5698 #define PACK_BGR10A2_LE GST_VIDEO_FORMAT_ARGB64, unpack_bgr10a2_le, 1, pack_bgr10a2_le
5699 static void
unpack_bgr10a2_le(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5700 unpack_bgr10a2_le (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5701     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5702     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5703 {
5704   int i;
5705   const guint8 *restrict s = GET_LINE (y);
5706   guint16 *restrict d = dest;
5707   guint32 ARGB;
5708   guint16 A, R, G, B;
5709 
5710   s += x * 4;
5711 
5712   for (i = 0; i < width; i++) {
5713     ARGB = GST_READ_UINT32_LE (s + 4 * i);
5714 
5715     B = ((ARGB >> 0) & 0x3ff) << 6;
5716     G = ((ARGB >> 10) & 0x3ff) << 6;
5717     R = ((ARGB >> 20) & 0x3ff) << 6;
5718     A = ((ARGB >> 30) & 0x03) << 14;
5719 
5720     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5721       B |= (B >> 10);
5722       G |= (G >> 10);
5723       R |= (R >> 10);
5724       A |= (A >> 10);
5725     }
5726 
5727     d[4 * i + 0] = A;
5728     d[4 * i + 1] = R;
5729     d[4 * i + 2] = G;
5730     d[4 * i + 3] = B;
5731   }
5732 }
5733 
5734 static void
pack_bgr10a2_le(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5735 pack_bgr10a2_le (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5736     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5737     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5738     gint y, gint width)
5739 {
5740   int i;
5741   guint32 *restrict d = GET_LINE (y);
5742   const guint16 *restrict s = src;
5743   guint32 ARGB;
5744   guint16 A, R, G, B;
5745 
5746   for (i = 0; i < width; i++) {
5747     A = s[4 * i] & 0xc000;
5748     R = s[4 * i + 1] & 0xffc0;
5749     G = s[4 * i + 2] & 0xffc0;
5750     B = s[4 * i + 3] & 0xffc0;
5751 
5752     ARGB = (B >> 6) | (G << 4) | (R << 14) | (A << 16);
5753 
5754     GST_WRITE_UINT32_LE (d + i, ARGB);
5755   }
5756 }
5757 
5758 #define PACK_RGB10A2_LE GST_VIDEO_FORMAT_ARGB64, unpack_rgb10a2_le, 1, pack_rgb10a2_le
5759 static void
unpack_rgb10a2_le(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5760 unpack_rgb10a2_le (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5761     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5762     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5763 {
5764   int i;
5765   const guint8 *restrict s = GET_LINE (y);
5766   guint16 *restrict d = dest;
5767   guint32 ARGB;
5768   guint16 A, R, G, B;
5769 
5770   s += x * 4;
5771 
5772   for (i = 0; i < width; i++) {
5773     ARGB = GST_READ_UINT32_LE (s + 4 * i);
5774 
5775     R = ((ARGB >> 0) & 0x3ff) << 6;
5776     G = ((ARGB >> 10) & 0x3ff) << 6;
5777     B = ((ARGB >> 20) & 0x3ff) << 6;
5778     A = ((ARGB >> 30) & 0x03) << 14;
5779 
5780     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
5781       R |= (R >> 10);
5782       G |= (G >> 10);
5783       B |= (B >> 10);
5784       A |= (A >> 10);
5785     }
5786 
5787     d[4 * i + 0] = A;
5788     d[4 * i + 1] = R;
5789     d[4 * i + 2] = G;
5790     d[4 * i + 3] = B;
5791   }
5792 }
5793 
5794 static void
pack_rgb10a2_le(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5795 pack_rgb10a2_le (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5796     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5797     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5798     gint y, gint width)
5799 {
5800   int i;
5801   guint32 *restrict d = GET_LINE (y);
5802   const guint16 *restrict s = src;
5803   guint32 ARGB;
5804   guint16 A, R, G, B;
5805 
5806   for (i = 0; i < width; i++) {
5807     A = s[4 * i] & 0xc000;
5808     R = s[4 * i + 1] & 0xffc0;
5809     G = s[4 * i + 2] & 0xffc0;
5810     B = s[4 * i + 3] & 0xffc0;
5811 
5812     ARGB = (R >> 6) | (G << 4) | (B << 14) | (A << 16);
5813 
5814     GST_WRITE_UINT32_LE (d + i, ARGB);
5815   }
5816 }
5817 
5818 #define PACK_Y444_16BE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_16BE, 1, pack_Y444_16BE
5819 static void
unpack_Y444_16BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5820 unpack_Y444_16BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5821     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5822     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5823 {
5824   int i;
5825   guint16 *restrict sy = GET_Y_LINE (y);
5826   guint16 *restrict su = GET_U_LINE (y);
5827   guint16 *restrict sv = GET_V_LINE (y);
5828   guint16 *restrict d = dest, Y, U, V;
5829 
5830   sy += x;
5831   su += x;
5832   sv += x;
5833 
5834   for (i = 0; i < width; i++) {
5835     Y = GST_READ_UINT16_BE (sy + i);
5836     U = GST_READ_UINT16_BE (su + i);
5837     V = GST_READ_UINT16_BE (sv + i);
5838 
5839     d[i * 4 + 0] = 0xffff;
5840     d[i * 4 + 1] = Y;
5841     d[i * 4 + 2] = U;
5842     d[i * 4 + 3] = V;
5843   }
5844 }
5845 
5846 static void
pack_Y444_16BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5847 pack_Y444_16BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5848     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5849     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5850     gint y, gint width)
5851 {
5852   int i;
5853   guint16 *restrict dy = GET_Y_LINE (y);
5854   guint16 *restrict du = GET_U_LINE (y);
5855   guint16 *restrict dv = GET_V_LINE (y);
5856   guint16 Y, U, V;
5857   const guint16 *restrict s = src;
5858 
5859   for (i = 0; i < width; i++) {
5860     Y = s[i * 4 + 1];
5861     U = s[i * 4 + 2];
5862     V = s[i * 4 + 3];
5863 
5864     GST_WRITE_UINT16_BE (dy + i, Y);
5865     GST_WRITE_UINT16_BE (du + i, U);
5866     GST_WRITE_UINT16_BE (dv + i, V);
5867   }
5868 }
5869 
5870 #define PACK_Y444_16LE GST_VIDEO_FORMAT_AYUV64, unpack_Y444_16LE, 1, pack_Y444_16LE
5871 static void
unpack_Y444_16LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5872 unpack_Y444_16LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5873     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5874     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5875 {
5876   int i;
5877   guint16 *restrict sy = GET_Y_LINE (y);
5878   guint16 *restrict su = GET_U_LINE (y);
5879   guint16 *restrict sv = GET_V_LINE (y);
5880   guint16 *restrict d = dest, Y, U, V;
5881 
5882   sy += x;
5883   su += x;
5884   sv += x;
5885 
5886   for (i = 0; i < width; i++) {
5887     Y = GST_READ_UINT16_LE (sy + i);
5888     U = GST_READ_UINT16_LE (su + i);
5889     V = GST_READ_UINT16_LE (sv + i);
5890 
5891     d[i * 4 + 0] = 0xffff;
5892     d[i * 4 + 1] = Y;
5893     d[i * 4 + 2] = U;
5894     d[i * 4 + 3] = V;
5895   }
5896 }
5897 
5898 static void
pack_Y444_16LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5899 pack_Y444_16LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5900     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5901     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5902     gint y, gint width)
5903 {
5904   int i;
5905   guint16 *restrict dy = GET_Y_LINE (y);
5906   guint16 *restrict du = GET_U_LINE (y);
5907   guint16 *restrict dv = GET_V_LINE (y);
5908   guint16 Y, U, V;
5909   const guint16 *restrict s = src;
5910 
5911   for (i = 0; i < width; i++) {
5912     Y = s[i * 4 + 1];
5913     U = s[i * 4 + 2];
5914     V = s[i * 4 + 3];
5915 
5916     GST_WRITE_UINT16_LE (dy + i, Y);
5917     GST_WRITE_UINT16_LE (du + i, U);
5918     GST_WRITE_UINT16_LE (dv + i, V);
5919   }
5920 }
5921 
5922 #define PACK_P016_BE GST_VIDEO_FORMAT_AYUV64, unpack_P016_BE, 1, pack_P016_BE
5923 static void
unpack_P016_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)5924 unpack_P016_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5925     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
5926     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
5927 {
5928   int i;
5929   gint uv = GET_UV_420 (y, flags);
5930   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
5931   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
5932   guint16 *restrict d = dest, Y0, Y1, U, V;
5933 
5934   sy += x;
5935   suv += (x & ~1);
5936 
5937   if (x & 1) {
5938     Y0 = GST_READ_UINT16_BE (sy);
5939     U = GST_READ_UINT16_BE (suv);
5940     V = GST_READ_UINT16_BE (suv + 1);
5941 
5942     d[0] = 0xffff;
5943     d[1] = Y0;
5944     d[2] = U;
5945     d[3] = V;
5946     width--;
5947     d += 4;
5948     sy += 1;
5949     suv += 2;
5950   }
5951 
5952   for (i = 0; i < width / 2; i++) {
5953     Y0 = GST_READ_UINT16_BE (sy + 2 * i);
5954     Y1 = GST_READ_UINT16_BE (sy + 2 * i + 1);
5955     U = GST_READ_UINT16_BE (suv + 2 * i);
5956     V = GST_READ_UINT16_BE (suv + 2 * i + 1);
5957 
5958     d[i * 8 + 0] = 0xffff;
5959     d[i * 8 + 1] = Y0;
5960     d[i * 8 + 2] = U;
5961     d[i * 8 + 3] = V;
5962     d[i * 8 + 4] = 0xffff;
5963     d[i * 8 + 5] = Y1;
5964     d[i * 8 + 6] = U;
5965     d[i * 8 + 7] = V;
5966   }
5967 
5968   if (width & 1) {
5969     gint i = width - 1;
5970 
5971     Y0 = GST_READ_UINT16_BE (sy + i);
5972     U = GST_READ_UINT16_BE (suv + i);
5973     V = GST_READ_UINT16_BE (suv + i + 1);
5974 
5975     d[i * 4 + 0] = 0xffff;
5976     d[i * 4 + 1] = Y0;
5977     d[i * 4 + 2] = U;
5978     d[i * 4 + 3] = V;
5979   }
5980 }
5981 
5982 static void
pack_P016_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)5983 pack_P016_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
5984     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
5985     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
5986     gint y, gint width)
5987 {
5988   int i;
5989   gint uv = GET_UV_420 (y, flags);
5990   guint16 *restrict dy = GET_PLANE_LINE (0, y);
5991   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
5992   guint16 Y0, Y1, U, V;
5993   const guint16 *restrict s = src;
5994 
5995   if (IS_CHROMA_LINE_420 (y, flags)) {
5996     for (i = 0; i < width / 2; i++) {
5997       Y0 = s[i * 8 + 1];
5998       Y1 = s[i * 8 + 5];
5999       U = s[i * 8 + 2];
6000       V = s[i * 8 + 3];
6001 
6002       GST_WRITE_UINT16_BE (dy + i * 2 + 0, Y0);
6003       GST_WRITE_UINT16_BE (dy + i * 2 + 1, Y1);
6004       GST_WRITE_UINT16_BE (duv + i * 2 + 0, U);
6005       GST_WRITE_UINT16_BE (duv + i * 2 + 1, V);
6006     }
6007     if (width & 1) {
6008       gint i = width - 1;
6009 
6010       Y0 = s[i * 4 + 1];
6011       U = s[i * 4 + 2];
6012       V = s[i * 4 + 3];
6013 
6014       GST_WRITE_UINT16_BE (dy + i, Y0);
6015       GST_WRITE_UINT16_BE (duv + i + 0, U);
6016       GST_WRITE_UINT16_BE (duv + i + 1, V);
6017     }
6018   } else {
6019     for (i = 0; i < width; i++) {
6020       Y0 = s[i * 4 + 1];
6021       GST_WRITE_UINT16_BE (dy + i, Y0);
6022     }
6023   }
6024 }
6025 
6026 #define PACK_P016_LE GST_VIDEO_FORMAT_AYUV64, unpack_P016_LE, 1, pack_P016_LE
6027 static void
unpack_P016_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6028 unpack_P016_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6029     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6030     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6031 {
6032   int i;
6033   gint uv = GET_UV_420 (y, flags);
6034   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
6035   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
6036   guint16 *restrict d = dest, Y0, Y1, U, V;
6037 
6038   sy += x;
6039   suv += (x & ~1);
6040 
6041   if (x & 1) {
6042     Y0 = GST_READ_UINT16_LE (sy);
6043     U = GST_READ_UINT16_LE (suv);
6044     V = GST_READ_UINT16_LE (suv + 1);
6045 
6046     d[0] = 0xffff;
6047     d[1] = Y0;
6048     d[2] = U;
6049     d[3] = V;
6050     width--;
6051     d += 4;
6052     sy += 1;
6053     suv += 2;
6054   }
6055 
6056   for (i = 0; i < width / 2; i++) {
6057     Y0 = GST_READ_UINT16_LE (sy + 2 * i);
6058     Y1 = GST_READ_UINT16_LE (sy + 2 * i + 1);
6059     U = GST_READ_UINT16_LE (suv + 2 * i);
6060     V = GST_READ_UINT16_LE (suv + 2 * i + 1);
6061 
6062     d[i * 8 + 0] = 0xffff;
6063     d[i * 8 + 1] = Y0;
6064     d[i * 8 + 2] = U;
6065     d[i * 8 + 3] = V;
6066     d[i * 8 + 4] = 0xffff;
6067     d[i * 8 + 5] = Y1;
6068     d[i * 8 + 6] = U;
6069     d[i * 8 + 7] = V;
6070   }
6071 
6072   if (width & 1) {
6073     gint i = width - 1;
6074 
6075     Y0 = GST_READ_UINT16_LE (sy + i);
6076     U = GST_READ_UINT16_LE (suv + i);
6077     V = GST_READ_UINT16_LE (suv + i + 1);
6078 
6079     d[i * 4 + 0] = 0xffff;
6080     d[i * 4 + 1] = Y0;
6081     d[i * 4 + 2] = U;
6082     d[i * 4 + 3] = V;
6083   }
6084 }
6085 
6086 static void
pack_P016_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6087 pack_P016_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6088     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6089     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6090     gint y, gint width)
6091 {
6092   int i;
6093   gint uv = GET_UV_420 (y, flags);
6094   guint16 *restrict dy = GET_PLANE_LINE (0, y);
6095   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
6096   guint16 Y0, Y1, U, V;
6097   const guint16 *restrict s = src;
6098 
6099   if (IS_CHROMA_LINE_420 (y, flags)) {
6100     for (i = 0; i < width / 2; i++) {
6101       Y0 = s[i * 8 + 1];
6102       Y1 = s[i * 8 + 5];
6103       U = s[i * 8 + 2];
6104       V = s[i * 8 + 3];
6105 
6106       GST_WRITE_UINT16_LE (dy + i * 2 + 0, Y0);
6107       GST_WRITE_UINT16_LE (dy + i * 2 + 1, Y1);
6108       GST_WRITE_UINT16_LE (duv + i * 2 + 0, U);
6109       GST_WRITE_UINT16_LE (duv + i * 2 + 1, V);
6110     }
6111     if (width & 1) {
6112       gint i = width - 1;
6113 
6114       Y0 = s[i * 4 + 1];
6115       U = s[i * 4 + 2];
6116       V = s[i * 4 + 3];
6117 
6118       GST_WRITE_UINT16_LE (dy + i, Y0);
6119       GST_WRITE_UINT16_LE (duv + i + 0, U);
6120       GST_WRITE_UINT16_LE (duv + i + 1, V);
6121     }
6122   } else {
6123     for (i = 0; i < width; i++) {
6124       Y0 = s[i * 4 + 1];
6125       GST_WRITE_UINT16_LE (dy + i, Y0);
6126     }
6127   }
6128 }
6129 
6130 #define PACK_P012_BE GST_VIDEO_FORMAT_AYUV64, unpack_P012_BE, 1, pack_P012_BE
6131 static void
unpack_P012_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6132 unpack_P012_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6133     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6134     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6135 {
6136   int i;
6137   gint uv = GET_UV_420 (y, flags);
6138   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
6139   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
6140   guint16 *restrict d = dest, Y0, Y1, U, V;
6141 
6142   sy += x;
6143   suv += (x & ~1);
6144 
6145   if (x & 1) {
6146     Y0 = GST_READ_UINT16_BE (sy);
6147     U = GST_READ_UINT16_BE (suv);
6148     V = GST_READ_UINT16_BE (suv + 1);
6149 
6150     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6151       Y0 |= (Y0 >> 12);
6152       U |= (U >> 12);
6153       V |= (V >> 12);
6154     }
6155 
6156     d[0] = 0xffff;
6157     d[1] = Y0;
6158     d[2] = U;
6159     d[3] = V;
6160     width--;
6161     d += 4;
6162     sy += 1;
6163     suv += 2;
6164   }
6165 
6166   for (i = 0; i < width / 2; i++) {
6167     Y0 = GST_READ_UINT16_BE (sy + 2 * i);
6168     Y1 = GST_READ_UINT16_BE (sy + 2 * i + 1);
6169     U = GST_READ_UINT16_BE (suv + 2 * i);
6170     V = GST_READ_UINT16_BE (suv + 2 * i + 1);
6171 
6172     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6173       Y0 |= (Y0 >> 12);
6174       Y1 |= (Y1 >> 12);
6175       U |= (U >> 12);
6176       V |= (V >> 12);
6177     }
6178 
6179     d[i * 8 + 0] = 0xffff;
6180     d[i * 8 + 1] = Y0;
6181     d[i * 8 + 2] = U;
6182     d[i * 8 + 3] = V;
6183     d[i * 8 + 4] = 0xffff;
6184     d[i * 8 + 5] = Y1;
6185     d[i * 8 + 6] = U;
6186     d[i * 8 + 7] = V;
6187   }
6188 
6189   if (width & 1) {
6190     gint i = width - 1;
6191 
6192     Y0 = GST_READ_UINT16_BE (sy + i);
6193     U = GST_READ_UINT16_BE (suv + i);
6194     V = GST_READ_UINT16_BE (suv + i + 1);
6195 
6196     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6197       Y0 |= (Y0 >> 12);
6198       U |= (U >> 12);
6199       V |= (V >> 12);
6200     }
6201 
6202     d[i * 4 + 0] = 0xffff;
6203     d[i * 4 + 1] = Y0;
6204     d[i * 4 + 2] = U;
6205     d[i * 4 + 3] = V;
6206   }
6207 }
6208 
6209 static void
pack_P012_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6210 pack_P012_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6211     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6212     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6213     gint y, gint width)
6214 {
6215   int i;
6216   gint uv = GET_UV_420 (y, flags);
6217   guint16 *restrict dy = GET_PLANE_LINE (0, y);
6218   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
6219   guint16 Y0, Y1, U, V;
6220   const guint16 *restrict s = src;
6221 
6222   if (IS_CHROMA_LINE_420 (y, flags)) {
6223     for (i = 0; i < width / 2; i++) {
6224       Y0 = s[i * 8 + 1] & 0xfff0;
6225       Y1 = s[i * 8 + 5] & 0xfff0;
6226       U = s[i * 8 + 2] & 0xfff0;
6227       V = s[i * 8 + 3] & 0xfff0;
6228 
6229       GST_WRITE_UINT16_BE (dy + i * 2 + 0, Y0);
6230       GST_WRITE_UINT16_BE (dy + i * 2 + 1, Y1);
6231       GST_WRITE_UINT16_BE (duv + i * 2 + 0, U);
6232       GST_WRITE_UINT16_BE (duv + i * 2 + 1, V);
6233     }
6234     if (width & 1) {
6235       gint i = width - 1;
6236 
6237       Y0 = s[i * 4 + 1] & 0xfff0;
6238       U = s[i * 4 + 2] & 0xfff0;
6239       V = s[i * 4 + 3] & 0xfff0;
6240 
6241       GST_WRITE_UINT16_BE (dy + i, Y0);
6242       GST_WRITE_UINT16_BE (duv + i + 0, U);
6243       GST_WRITE_UINT16_BE (duv + i + 1, V);
6244     }
6245   } else {
6246     for (i = 0; i < width; i++) {
6247       Y0 = s[i * 4 + 1] & 0xfff0;
6248       GST_WRITE_UINT16_BE (dy + i, Y0);
6249     }
6250   }
6251 }
6252 
6253 #define PACK_P012_LE GST_VIDEO_FORMAT_AYUV64, unpack_P012_LE, 1, pack_P012_LE
6254 static void
unpack_P012_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6255 unpack_P012_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6256     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6257     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6258 {
6259   int i;
6260   gint uv = GET_UV_420 (y, flags);
6261   const guint16 *restrict sy = GET_PLANE_LINE (0, y);
6262   const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
6263   guint16 *restrict d = dest, Y0, Y1, U, V;
6264 
6265   sy += x;
6266   suv += (x & ~1);
6267 
6268   if (x & 1) {
6269     Y0 = GST_READ_UINT16_LE (sy);
6270     U = GST_READ_UINT16_LE (suv);
6271     V = GST_READ_UINT16_LE (suv + 1);
6272 
6273     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6274       Y0 |= (Y0 >> 12);
6275       U |= (U >> 12);
6276       V |= (V >> 12);
6277     }
6278 
6279     d[0] = 0xffff;
6280     d[1] = Y0;
6281     d[2] = U;
6282     d[3] = V;
6283     width--;
6284     d += 4;
6285     sy += 1;
6286     suv += 2;
6287   }
6288 
6289   for (i = 0; i < width / 2; i++) {
6290     Y0 = GST_READ_UINT16_LE (sy + 2 * i);
6291     Y1 = GST_READ_UINT16_LE (sy + 2 * i + 1);
6292     U = GST_READ_UINT16_LE (suv + 2 * i);
6293     V = GST_READ_UINT16_LE (suv + 2 * i + 1);
6294 
6295     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6296       Y0 |= (Y0 >> 12);
6297       Y1 |= (Y1 >> 12);
6298       U |= (U >> 12);
6299       V |= (V >> 12);
6300     }
6301 
6302     d[i * 8 + 0] = 0xffff;
6303     d[i * 8 + 1] = Y0;
6304     d[i * 8 + 2] = U;
6305     d[i * 8 + 3] = V;
6306     d[i * 8 + 4] = 0xffff;
6307     d[i * 8 + 5] = Y1;
6308     d[i * 8 + 6] = U;
6309     d[i * 8 + 7] = V;
6310   }
6311 
6312   if (width & 1) {
6313     gint i = width - 1;
6314 
6315     Y0 = GST_READ_UINT16_LE (sy + i);
6316     U = GST_READ_UINT16_LE (suv + i);
6317     V = GST_READ_UINT16_LE (suv + i + 1);
6318 
6319     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6320       Y0 |= (Y0 >> 12);
6321       U |= (U >> 12);
6322       V |= (V >> 12);
6323     }
6324 
6325     d[i * 4 + 0] = 0xffff;
6326     d[i * 4 + 1] = Y0;
6327     d[i * 4 + 2] = U;
6328     d[i * 4 + 3] = V;
6329   }
6330 }
6331 
6332 static void
pack_P012_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6333 pack_P012_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6334     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6335     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6336     gint y, gint width)
6337 {
6338   int i;
6339   gint uv = GET_UV_420 (y, flags);
6340   guint16 *restrict dy = GET_PLANE_LINE (0, y);
6341   guint16 *restrict duv = GET_PLANE_LINE (1, uv);
6342   guint16 Y0, Y1, U, V;
6343   const guint16 *restrict s = src;
6344 
6345   if (IS_CHROMA_LINE_420 (y, flags)) {
6346     for (i = 0; i < width / 2; i++) {
6347       Y0 = s[i * 8 + 1] & 0xfff0;
6348       Y1 = s[i * 8 + 5] & 0xfff0;
6349       U = s[i * 8 + 2] & 0xfff0;
6350       V = s[i * 8 + 3] & 0xfff0;
6351 
6352       GST_WRITE_UINT16_LE (dy + i * 2 + 0, Y0);
6353       GST_WRITE_UINT16_LE (dy + i * 2 + 1, Y1);
6354       GST_WRITE_UINT16_LE (duv + i * 2 + 0, U);
6355       GST_WRITE_UINT16_LE (duv + i * 2 + 1, V);
6356     }
6357     if (width & 1) {
6358       gint i = width - 1;
6359 
6360       Y0 = s[i * 4 + 1] & 0xfff0;
6361       U = s[i * 4 + 2] & 0xfff0;
6362       V = s[i * 4 + 3] & 0xfff0;
6363 
6364       GST_WRITE_UINT16_LE (dy + i, Y0);
6365       GST_WRITE_UINT16_LE (duv + i + 0, U);
6366       GST_WRITE_UINT16_LE (duv + i + 1, V);
6367     }
6368   } else {
6369     for (i = 0; i < width; i++) {
6370       Y0 = s[i * 4 + 1] & 0xfff0;
6371       GST_WRITE_UINT16_LE (dy + i, Y0);
6372     }
6373   }
6374 }
6375 
6376 #define PACK_Y212_BE GST_VIDEO_FORMAT_AYUV64, unpack_Y212_BE, 1, pack_Y212_BE
6377 static void
unpack_Y212_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6378 unpack_Y212_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6379     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6380     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6381 {
6382   int i;
6383   const guint8 *restrict s = GET_LINE (y);
6384   guint16 *restrict d = dest;
6385   guint Y0, Y1, U, V;
6386 
6387   s += GST_ROUND_DOWN_2 (x) * 4;
6388 
6389   if (x & 1) {
6390     Y1 = GST_READ_UINT16_BE (s + 4);
6391     U = GST_READ_UINT16_BE (s + 2);
6392     V = GST_READ_UINT16_BE (s + 6);
6393 
6394     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6395       Y1 |= (Y1 >> 12);
6396       U |= (U >> 12);
6397       V |= (V >> 12);
6398     }
6399 
6400     d[0] = 0xffff;
6401     d[1] = Y1;
6402     d[2] = U;
6403     d[3] = V;
6404     s += 8;
6405     d += 4;
6406     width--;
6407   }
6408 
6409   for (i = 0; i < width / 2; i++) {
6410     Y0 = GST_READ_UINT16_BE (s + i * 8 + 0);
6411     U = GST_READ_UINT16_BE (s + i * 8 + 2);
6412     V = GST_READ_UINT16_BE (s + i * 8 + 6);
6413     Y1 = GST_READ_UINT16_BE (s + i * 8 + 4);
6414 
6415     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6416       Y0 |= (Y0 >> 12);
6417       U |= (U >> 12);
6418       V |= (V >> 12);
6419     }
6420 
6421     d[i * 8 + 0] = 0xffff;
6422     d[i * 8 + 1] = Y0;
6423     d[i * 8 + 2] = U;
6424     d[i * 8 + 3] = V;
6425 
6426     d[i * 8 + 4] = 0xffff;
6427     d[i * 8 + 5] = Y1;
6428     d[i * 8 + 6] = U;
6429     d[i * 8 + 7] = V;
6430   }
6431 
6432   if (width & 1) {
6433     i = width - 1;
6434 
6435     Y0 = GST_READ_UINT16_BE (s + i * 4 + 0);
6436     U = GST_READ_UINT16_BE (s + i * 4 + 2);
6437     V = GST_READ_UINT16_BE (s + i * 4 + 6);
6438 
6439     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6440       Y0 |= (Y0 >> 12);
6441       U |= (U >> 12);
6442       V |= (V >> 12);
6443     }
6444 
6445     d[i * 4 + 0] = 0xffff;
6446     d[i * 4 + 1] = Y0;
6447     d[i * 4 + 2] = U;
6448     d[i * 4 + 3] = V;
6449   }
6450 }
6451 
6452 static void
pack_Y212_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6453 pack_Y212_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6454     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6455     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6456     gint y, gint width)
6457 {
6458   int i;
6459   guint16 Y0, Y1, U, V;
6460   guint8 *restrict d = GET_LINE (y);
6461   const guint16 *restrict s = src;
6462 
6463   for (i = 0; i < width; i += 2) {
6464     Y0 = s[i * 4 + 1] & 0xfff0;
6465     U = s[i * 4 + 2] & 0xfff0;
6466     V = s[i * 4 + 3] & 0xfff0;
6467     if (i == width - 1)
6468       Y1 = s[i * 4 + 1] & 0xfff0;
6469     else
6470       Y1 = s[(i + 1) * 4 + 1] & 0xfff0;
6471 
6472     GST_WRITE_UINT16_BE (d + i * 4 + 0, Y0);
6473     GST_WRITE_UINT16_BE (d + i * 4 + 2, U);
6474     GST_WRITE_UINT16_BE (d + i * 4 + 4, Y1);
6475     GST_WRITE_UINT16_BE (d + i * 4 + 6, V);
6476   }
6477 }
6478 
6479 #define PACK_Y212_LE GST_VIDEO_FORMAT_AYUV64, unpack_Y212_LE, 1, pack_Y212_LE
6480 static void
unpack_Y212_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6481 unpack_Y212_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6482     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6483     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6484 {
6485   int i;
6486   const guint8 *restrict s = GET_LINE (y);
6487   guint16 *restrict d = dest;
6488   guint Y0, Y1, U, V;
6489 
6490   s += GST_ROUND_DOWN_2 (x) * 4;
6491 
6492   if (x & 1) {
6493     Y1 = GST_READ_UINT16_LE (s + 4);
6494     U = GST_READ_UINT16_LE (s + 2);
6495     V = GST_READ_UINT16_LE (s + 6);
6496 
6497     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6498       Y1 |= (Y1 >> 12);
6499       U |= (U >> 12);
6500       V |= (V >> 12);
6501     }
6502 
6503     d[0] = 0xffff;
6504     d[1] = Y1;
6505     d[2] = U;
6506     d[3] = V;
6507     s += 8;
6508     d += 4;
6509     width--;
6510   }
6511 
6512   for (i = 0; i < width / 2; i++) {
6513     Y0 = GST_READ_UINT16_LE (s + i * 8 + 0);
6514     U = GST_READ_UINT16_LE (s + i * 8 + 2);
6515     V = GST_READ_UINT16_LE (s + i * 8 + 6);
6516     Y1 = GST_READ_UINT16_LE (s + i * 8 + 4);
6517 
6518     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6519       Y0 |= (Y0 >> 12);
6520       U |= (U >> 12);
6521       V |= (V >> 12);
6522     }
6523 
6524     d[i * 8 + 0] = 0xffff;
6525     d[i * 8 + 1] = Y0;
6526     d[i * 8 + 2] = U;
6527     d[i * 8 + 3] = V;
6528 
6529     d[i * 8 + 4] = 0xffff;
6530     d[i * 8 + 5] = Y1;
6531     d[i * 8 + 6] = U;
6532     d[i * 8 + 7] = V;
6533   }
6534 
6535   if (width & 1) {
6536     i = width - 1;
6537 
6538     Y0 = GST_READ_UINT16_LE (s + i * 4 + 0);
6539     U = GST_READ_UINT16_LE (s + i * 4 + 2);
6540     V = GST_READ_UINT16_LE (s + i * 4 + 6);
6541 
6542     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6543       Y0 |= (Y0 >> 12);
6544       U |= (U >> 12);
6545       V |= (V >> 12);
6546     }
6547 
6548     d[i * 4 + 0] = 0xffff;
6549     d[i * 4 + 1] = Y0;
6550     d[i * 4 + 2] = U;
6551     d[i * 4 + 3] = V;
6552   }
6553 }
6554 
6555 static void
pack_Y212_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6556 pack_Y212_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6557     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6558     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6559     gint y, gint width)
6560 {
6561   int i;
6562   guint16 Y0, Y1, U, V;
6563   guint8 *restrict d = GET_LINE (y);
6564   const guint16 *restrict s = src;
6565 
6566   for (i = 0; i < width; i += 2) {
6567     Y0 = s[i * 4 + 1] & 0xfff0;
6568     U = s[i * 4 + 2] & 0xfff0;
6569     V = s[i * 4 + 3] & 0xfff0;
6570     if (i == width - 1)
6571       Y1 = s[i * 4 + 1] & 0xfff0;
6572     else
6573       Y1 = s[(i + 1) * 4 + 1] & 0xfff0;
6574 
6575     GST_WRITE_UINT16_LE (d + i * 4 + 0, Y0);
6576     GST_WRITE_UINT16_LE (d + i * 4 + 2, U);
6577     GST_WRITE_UINT16_LE (d + i * 4 + 4, Y1);
6578     GST_WRITE_UINT16_LE (d + i * 4 + 6, V);
6579   }
6580 }
6581 
6582 #define PACK_Y412_BE GST_VIDEO_FORMAT_AYUV64, unpack_Y412_BE, 1, pack_Y412_BE
6583 static void
unpack_Y412_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6584 unpack_Y412_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6585     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6586     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6587 {
6588   int i;
6589   const guint16 *restrict s = GET_LINE (y);
6590   guint16 *restrict d = dest;
6591   guint16 A, Y, U, V;
6592 
6593   s += x * 4;
6594 
6595   for (i = 0; i < width; i++) {
6596     U = GST_READ_UINT16_BE (s + 4 * i + 0) & 0xfff0;
6597     Y = GST_READ_UINT16_BE (s + 4 * i + 1) & 0xfff0;
6598     V = GST_READ_UINT16_BE (s + 4 * i + 2) & 0xfff0;
6599     A = GST_READ_UINT16_BE (s + 4 * i + 3) & 0xfff0;
6600 
6601     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6602       U |= (U >> 12);
6603       Y |= (Y >> 12);
6604       V |= (V >> 12);
6605       A |= (A >> 12);
6606     }
6607 
6608     d[4 * i + 0] = A;
6609     d[4 * i + 1] = Y;
6610     d[4 * i + 2] = U;
6611     d[4 * i + 3] = V;
6612   }
6613 }
6614 
6615 static void
pack_Y412_BE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6616 pack_Y412_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6617     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6618     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6619     gint y, gint width)
6620 {
6621   int i;
6622   guint16 *restrict d = GET_LINE (y);
6623   const guint16 *restrict s = src;
6624   guint16 A, Y, U, V;
6625 
6626   for (i = 0; i < width; i++) {
6627     A = s[4 * i + 0] & 0xfff0;
6628     Y = s[4 * i + 1] & 0xfff0;
6629     U = s[4 * i + 2] & 0xfff0;
6630     V = s[4 * i + 3] & 0xfff0;
6631 
6632     GST_WRITE_UINT16_BE (d + 4 * i + 0, U);
6633     GST_WRITE_UINT16_BE (d + 4 * i + 1, Y);
6634     GST_WRITE_UINT16_BE (d + 4 * i + 2, V);
6635     GST_WRITE_UINT16_BE (d + 4 * i + 3, A);
6636   }
6637 }
6638 
6639 #define PACK_Y412_LE GST_VIDEO_FORMAT_AYUV64, unpack_Y412_LE, 1, pack_Y412_LE
6640 static void
unpack_Y412_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6641 unpack_Y412_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6642     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6643     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6644 {
6645   int i;
6646   const guint16 *restrict s = GET_LINE (y);
6647   guint16 *restrict d = dest;
6648   guint16 A, Y, U, V;
6649 
6650   s += x * 4;
6651 
6652   for (i = 0; i < width; i++) {
6653     U = GST_READ_UINT16_LE (s + 4 * i + 0) & 0xfff0;
6654     Y = GST_READ_UINT16_LE (s + 4 * i + 1) & 0xfff0;
6655     V = GST_READ_UINT16_LE (s + 4 * i + 2) & 0xfff0;
6656     A = GST_READ_UINT16_LE (s + 4 * i + 3) & 0xfff0;
6657 
6658     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
6659       U |= (U >> 12);
6660       Y |= (Y >> 12);
6661       V |= (V >> 12);
6662       A |= (A >> 12);
6663     }
6664 
6665     d[4 * i + 0] = A;
6666     d[4 * i + 1] = Y;
6667     d[4 * i + 2] = U;
6668     d[4 * i + 3] = V;
6669   }
6670 }
6671 
6672 static void
pack_Y412_LE(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6673 pack_Y412_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6674     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6675     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6676     gint y, gint width)
6677 {
6678   int i;
6679   guint16 *restrict d = GET_LINE (y);
6680   const guint16 *restrict s = src;
6681   guint16 A, Y, U, V;
6682 
6683   for (i = 0; i < width; i++) {
6684     A = s[4 * i + 0] & 0xfff0;
6685     Y = s[4 * i + 1] & 0xfff0;
6686     U = s[4 * i + 2] & 0xfff0;
6687     V = s[4 * i + 3] & 0xfff0;
6688 
6689     GST_WRITE_UINT16_LE (d + 4 * i + 0, U);
6690     GST_WRITE_UINT16_LE (d + 4 * i + 1, Y);
6691     GST_WRITE_UINT16_LE (d + 4 * i + 2, V);
6692     GST_WRITE_UINT16_LE (d + 4 * i + 3, A);
6693   }
6694 }
6695 
6696 #define PACK_RGBP GST_VIDEO_FORMAT_ARGB, unpack_RGBP, 1, pack_RGBP
6697 static void
unpack_RGBP(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6698 unpack_RGBP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6699     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6700     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6701 {
6702   const guint8 *restrict sr = GET_R_LINE (y);
6703   const guint8 *restrict sg = GET_G_LINE (y);
6704   const guint8 *restrict sb = GET_B_LINE (y);
6705 
6706   sr += x;
6707   sg += x;
6708   sb += x;
6709 
6710   video_orc_unpack_Y444 (dest, sr, sg, sb, width);
6711 }
6712 
6713 static void
pack_RGBP(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6714 pack_RGBP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6715     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6716     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6717     gint y, gint width)
6718 {
6719   guint8 *restrict dr = GET_R_LINE (y);
6720   guint8 *restrict dg = GET_G_LINE (y);
6721   guint8 *restrict db = GET_B_LINE (y);
6722 
6723   video_orc_pack_Y444 (dr, dg, db, src, width);
6724 }
6725 
6726 #define PACK_BGRP GST_VIDEO_FORMAT_ARGB, unpack_BGRP, 1, pack_BGRP
6727 static void
unpack_BGRP(const GstVideoFormatInfo * info,GstVideoPackFlags flags,gpointer dest,const gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],gint x,gint y,gint width)6728 unpack_BGRP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6729     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
6730     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
6731 {
6732   const guint8 *restrict sr = GET_R_LINE (y);
6733   const guint8 *restrict sg = GET_G_LINE (y);
6734   const guint8 *restrict sb = GET_B_LINE (y);
6735 
6736   sr += x;
6737   sg += x;
6738   sb += x;
6739 
6740   video_orc_unpack_Y444 (dest, sr, sg, sb, width);
6741 }
6742 
6743 static void
pack_BGRP(const GstVideoFormatInfo * info,GstVideoPackFlags flags,const gpointer src,gint sstride,gpointer data[GST_VIDEO_MAX_PLANES],const gint stride[GST_VIDEO_MAX_PLANES],GstVideoChromaSite chroma_site,gint y,gint width)6744 pack_BGRP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
6745     const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
6746     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
6747     gint y, gint width)
6748 {
6749   guint8 *restrict dr = GET_R_LINE (y);
6750   guint8 *restrict dg = GET_G_LINE (y);
6751   guint8 *restrict db = GET_B_LINE (y);
6752 
6753   video_orc_pack_Y444 (dr, dg, db, src, width);
6754 }
6755 
6756 typedef struct
6757 {
6758   guint32 fourcc;
6759   GstVideoFormatInfo info;
6760 } VideoFormat;
6761 
6762 /* depths: bits, n_components, shift, depth */
6763 #define DPTH0            0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
6764 #define DPTH8            8, 1, { 0, 0, 0, 0 }, { 8, 0, 0, 0 }
6765 #define DPTH8_32         8, 2, { 0, 0, 0, 0 }, { 8, 32, 0, 0 }
6766 #define DPTH888          8, 3, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
6767 #define DPTH8888         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 8 }
6768 #define DPTH8880         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
6769 #define DPTH10           10, 1, { 0, 0, 0, 0 }, { 10, 0, 0, 0 }
6770 #define DPTH10_10_10     10, 3, { 0, 0, 0, 0 }, { 10, 10, 10, 0 }
6771 #define DPTH10_10_10_10  10, 4, { 0, 0, 0, 0 }, { 10, 10, 10, 10 }
6772 #define DPTH10_10_10_HI  16, 3, { 6, 6, 6, 0 }, { 10, 10, 10, 0 }
6773 #define DPTH10_10_10_2   10, 4, { 0, 0, 0, 0 }, { 10, 10, 10, 2}
6774 #define DPTH12_12_12     12, 3, { 0, 0, 0, 0 }, { 12, 12, 12, 0 }
6775 #define DPTH12_12_12_HI  16, 3, { 4, 4, 4, 0 }, { 12, 12, 12, 0 }
6776 #define DPTH12_12_12_12  12, 4, { 0, 0, 0, 0 }, { 12, 12, 12, 12 }
6777 #define DPTH12_12_12_12_HI   16, 4, { 4, 4, 4, 4 }, { 12, 12, 12, 12 }
6778 #define DPTH16           16, 1, { 0, 0, 0, 0 }, { 16, 0, 0, 0 }
6779 #define DPTH16_16_16     16, 3, { 0, 0, 0, 0 }, { 16, 16, 16, 0 }
6780 #define DPTH16_16_16_16  16, 4, { 0, 0, 0, 0 }, { 16, 16, 16, 16 }
6781 #define DPTH555          5, 3, { 10, 5, 0, 0 }, { 5, 5, 5, 0 }
6782 #define DPTH565          6, 3, { 11, 5, 0, 0 }, { 5, 6, 5, 0 }
6783 
6784 /* pixel strides */
6785 #define PSTR0             { 0, 0, 0, 0 }
6786 #define PSTR1             { 1, 0, 0, 0 }
6787 #define PSTR14            { 1, 4, 0, 0 }
6788 #define PSTR111           { 1, 1, 1, 0 }
6789 #define PSTR1111          { 1, 1, 1, 1 }
6790 #define PSTR122           { 1, 2, 2, 0 }
6791 #define PSTR1221          { 1, 2, 2, 1 }
6792 #define PSTR2             { 2, 0, 0, 0 }
6793 #define PSTR222           { 2, 2, 2, 0 }
6794 #define PSTR2222          { 2, 2, 2, 2 }
6795 #define PSTR244           { 2, 4, 4, 0 }
6796 #define PSTR444           { 4, 4, 4, 0 }
6797 #define PSTR4444          { 4, 4, 4, 4 }
6798 #define PSTR333           { 3, 3, 3, 0 }
6799 #define PSTR488           { 4, 8, 8, 0 }
6800 #define PSTR8888          { 8, 8, 8, 8 }
6801 
6802 /* planes, in what plane do we find component N */
6803 #define PLANE_NA          0, { 0, 0, 0, 0 }
6804 #define PLANE0            1, { 0, 0, 0, 0 }
6805 #define PLANE01           2, { 0, 1, 0, 0 }
6806 #define PLANE011          2, { 0, 1, 1, 0 }
6807 #define PLANE0112         3, { 0, 1, 1, 2 }
6808 #define PLANE012          3, { 0, 1, 2, 0 }
6809 #define PLANE0123         4, { 0, 1, 2, 3 }
6810 #define PLANE021          3, { 0, 2, 1, 0 }
6811 #define PLANE201          3, { 2, 0, 1, 0 }
6812 #define PLANE2013         4, { 2, 0, 1, 3 }
6813 #define PLANE210          3, { 2, 1, 0, 0 }
6814 
6815 /* offsets */
6816 #define OFFS0             { 0, 0, 0, 0 }
6817 #define OFFS013           { 0, 1, 3, 0 }
6818 #define OFFS102           { 1, 0, 2, 0 }
6819 #define OFFS1230          { 1, 2, 3, 0 }
6820 #define OFFS012           { 0, 1, 2, 0 }
6821 #define OFFS210           { 2, 1, 0, 0 }
6822 #define OFFS123           { 1, 2, 3, 0 }
6823 #define OFFS321           { 3, 2, 1, 0 }
6824 #define OFFS0123          { 0, 1, 2, 3 }
6825 #define OFFS2103          { 2, 1, 0, 3 }
6826 #define OFFS3210          { 3, 2, 1, 0 }
6827 #define OFFS031           { 0, 3, 1, 0 }
6828 #define OFFS204           { 2, 0, 4, 0 }
6829 #define OFFS001           { 0, 0, 1, 0 }
6830 #define OFFS010           { 0, 1, 0, 0 }
6831 #define OFFS104           { 1, 0, 4, 0 }
6832 #define OFFS0246          { 0, 2, 4, 6 }
6833 #define OFFS2460          { 2, 4, 6, 0 }
6834 #define OFFS4206          { 4, 2, 0, 6 }
6835 #define OFFS6420          { 6, 4, 2, 0 }
6836 
6837 /* subsampling, w_sub, h_sub */
6838 #define SUB410            { 0, 2, 2, 0 }, { 0, 2, 2, 0 }
6839 #define SUB411            { 0, 2, 2, 0 }, { 0, 0, 0, 0 }
6840 #define SUB420            { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
6841 #define SUB422            { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
6842 #define SUB4              { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
6843 #define SUB44             { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
6844 #define SUB444            { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
6845 #define SUB4444           { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
6846 #define SUB4204           { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
6847 #define SUB4224           { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
6848 
6849 /* tile_mode, tile_ws (width shift), tile_hs (height shift) */
6850 #define TILE_4x4(mode) GST_VIDEO_TILE_MODE_ ##mode, 2, 2
6851 #define TILE_32x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 5, 5
6852 #define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5
6853 
6854 #define MAKE_YUV_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
6855  { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV, depth, pstride, plane, offs, sub, pack } }
6856 #define MAKE_YUV_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
6857  { 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 } }
6858 #define MAKE_YUVA_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
6859  { 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 } }
6860 #define MAKE_YUVA_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
6861  { 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 } }
6862 #define MAKE_YUVA_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
6863  { 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 } }
6864 #define MAKE_YUVA_LE_PACK_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
6865  { 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 } }
6866 #define MAKE_YUV_C_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
6867  { 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 } }
6868 #define MAKE_YUV_C_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
6869  { 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 } }
6870 #define MAKE_YUV_T_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack, tile) \
6871  { 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 } }
6872 
6873 #define MAKE_RGB_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6874  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB, depth, pstride, plane, offs, sub, pack } }
6875 #define MAKE_RGB_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6876  { 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 } }
6877 #define MAKE_RGBA_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6878  { 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 } }
6879 #define MAKE_RGBA_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6880  { 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 } }
6881 #define MAKE_RGBAP_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6882  { 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 } }
6883 #define MAKE_RGBA_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6884  { 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 } }
6885 #define MAKE_RGBA_LE_PACK_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6886  { 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 } }
6887 
6888 #define MAKE_GRAY_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6889  { 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY, depth, pstride, plane, offs, sub, pack } }
6890 #define MAKE_GRAY_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6891  { 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 } }
6892 #define MAKE_GRAY_C_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
6893  { 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 } }
6894 
6895 static const VideoFormat formats[] = {
6896   {0x00000000, {GST_VIDEO_FORMAT_UNKNOWN, "UNKNOWN", "unknown video", 0, DPTH0,
6897           PSTR0, PLANE_NA, OFFS0}},
6898   {0x00000000, {GST_VIDEO_FORMAT_ENCODED, "ENCODED", "encoded video",
6899           GST_VIDEO_FORMAT_FLAG_COMPLEX, DPTH0, PSTR0, PLANE_NA, OFFS0}},
6900 
6901   MAKE_YUV_FORMAT (I420, "raw video", GST_MAKE_FOURCC ('I', '4', '2', '0'),
6902       DPTH888, PSTR111, PLANE012, OFFS0, SUB420, PACK_420),
6903   MAKE_YUV_FORMAT (YV12, "raw video", GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
6904       DPTH888, PSTR111, PLANE021, OFFS0, SUB420, PACK_420),
6905   MAKE_YUV_FORMAT (YUY2, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
6906       DPTH888, PSTR244, PLANE0, OFFS013, SUB422, PACK_YUY2),
6907   MAKE_YUV_FORMAT (UYVY, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
6908       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_UYVY),
6909   MAKE_YUVA_PACK_FORMAT (AYUV, "raw video", GST_MAKE_FOURCC ('A', 'Y', 'U',
6910           'V'), DPTH8888, PSTR4444, PLANE0, OFFS1230, SUB4444, PACK_AYUV),
6911   MAKE_RGB_FORMAT (RGBx, "raw video", DPTH888, PSTR444, PLANE0, OFFS012,
6912       SUB444, PACK_RGBA),
6913   MAKE_RGB_FORMAT (BGRx, "raw video", DPTH888, PSTR444, PLANE0, OFFS210,
6914       SUB444, PACK_BGRA),
6915   MAKE_RGB_FORMAT (xRGB, "raw video", DPTH888, PSTR444, PLANE0, OFFS123,
6916       SUB444, PACK_ARGB),
6917   MAKE_RGB_FORMAT (xBGR, "raw video", DPTH888, PSTR444, PLANE0, OFFS321,
6918       SUB444, PACK_ABGR),
6919   MAKE_RGBA_FORMAT (RGBA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS0123,
6920       SUB4444, PACK_RGBA),
6921   MAKE_RGBA_FORMAT (BGRA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS2103,
6922       SUB4444, PACK_BGRA),
6923   MAKE_RGBA_PACK_FORMAT (ARGB, "raw video", DPTH8888, PSTR4444, PLANE0,
6924       OFFS1230, SUB4444, PACK_ARGB),
6925   MAKE_RGBA_FORMAT (ABGR, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS3210,
6926       SUB4444, PACK_ABGR),
6927   MAKE_RGB_FORMAT (RGB, "raw video", DPTH888, PSTR333, PLANE0, OFFS012, SUB444,
6928       PACK_RGB),
6929   MAKE_RGB_FORMAT (BGR, "raw video", DPTH888, PSTR333, PLANE0, OFFS210, SUB444,
6930       PACK_BGR),
6931 
6932   MAKE_YUV_FORMAT (Y41B, "raw video", GST_MAKE_FOURCC ('Y', '4', '1', 'B'),
6933       DPTH888, PSTR111, PLANE012, OFFS0, SUB411, PACK_Y41B),
6934   MAKE_YUV_FORMAT (Y42B, "raw video", GST_MAKE_FOURCC ('Y', '4', '2', 'B'),
6935       DPTH888, PSTR111, PLANE012, OFFS0, SUB422, PACK_Y42B),
6936   MAKE_YUV_FORMAT (YVYU, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'),
6937       DPTH888, PSTR244, PLANE0, OFFS031, SUB422, PACK_YVYU),
6938   MAKE_YUV_FORMAT (Y444, "raw video", GST_MAKE_FOURCC ('Y', '4', '4', '4'),
6939       DPTH888, PSTR111, PLANE012, OFFS0, SUB444, PACK_Y444),
6940   MAKE_YUV_C_FORMAT (v210, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '0'),
6941       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_v210),
6942   MAKE_YUV_FORMAT (v216, "raw video", GST_MAKE_FOURCC ('v', '2', '1', '6'),
6943       DPTH16_16_16, PSTR488, PLANE0, OFFS204, SUB422, PACK_v216),
6944   MAKE_YUV_FORMAT (NV12, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '2'),
6945       DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12),
6946   MAKE_YUV_FORMAT (NV21, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '1'),
6947       DPTH888, PSTR122, PLANE011, OFFS010, SUB420, PACK_NV21),
6948 
6949   MAKE_GRAY_FORMAT (GRAY8, "raw video", DPTH8, PSTR1, PLANE0, OFFS0, SUB4,
6950       PACK_GRAY8),
6951   MAKE_GRAY_FORMAT (GRAY16_BE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0, SUB4,
6952       PACK_GRAY16_BE),
6953   MAKE_GRAY_LE_FORMAT (GRAY16_LE, "raw video", DPTH16, PSTR2, PLANE0, OFFS0,
6954       SUB4, PACK_GRAY16_LE),
6955 
6956   MAKE_YUV_FORMAT (v308, "raw video", GST_MAKE_FOURCC ('v', '3', '0', '8'),
6957       DPTH888, PSTR333, PLANE0, OFFS012, SUB444, PACK_v308),
6958 
6959 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
6960   MAKE_RGB_LE_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
6961       SUB444, PACK_RGB16),
6962   MAKE_RGB_LE_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0,
6963       SUB444, PACK_BGR16),
6964   MAKE_RGB_LE_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
6965       SUB444, PACK_RGB15),
6966   MAKE_RGB_LE_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0,
6967       SUB444, PACK_BGR15),
6968 #else
6969   MAKE_RGB_FORMAT (RGB16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
6970       PACK_RGB16),
6971   MAKE_RGB_FORMAT (BGR16, "raw video", DPTH565, PSTR222, PLANE0, OFFS0, SUB444,
6972       PACK_BGR16),
6973   MAKE_RGB_FORMAT (RGB15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
6974       PACK_RGB15),
6975   MAKE_RGB_FORMAT (BGR15, "raw video", DPTH555, PSTR222, PLANE0, OFFS0, SUB444,
6976       PACK_BGR15),
6977 #endif
6978 
6979   MAKE_YUV_C_FORMAT (UYVP, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'),
6980       DPTH10_10_10, PSTR0, PLANE0, OFFS0, SUB422, PACK_UYVP),
6981   MAKE_YUVA_FORMAT (A420, "raw video", GST_MAKE_FOURCC ('A', '4', '2', '0'),
6982       DPTH8888, PSTR1111, PLANE0123, OFFS0, SUB4204, PACK_A420),
6983   MAKE_RGBAP_FORMAT (RGB8P, "raw video", DPTH8_32, PSTR14, PLANE01,
6984       OFFS0, SUB44, PACK_RGB8P),
6985   MAKE_YUV_FORMAT (YUV9, "raw video", GST_MAKE_FOURCC ('Y', 'U', 'V', '9'),
6986       DPTH888, PSTR111, PLANE012, OFFS0, SUB410, PACK_410),
6987   MAKE_YUV_FORMAT (YVU9, "raw video", GST_MAKE_FOURCC ('Y', 'V', 'U', '9'),
6988       DPTH888, PSTR111, PLANE021, OFFS0, SUB410, PACK_410),
6989   MAKE_YUV_FORMAT (IYU1, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '1'),
6990       DPTH888, PSTR0, PLANE0, OFFS104, SUB411, PACK_IYU1),
6991 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
6992   MAKE_RGBA_LE_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888,
6993       PLANE0,
6994       OFFS2460, SUB444, PACK_ARGB64),
6995   MAKE_YUVA_LE_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
6996       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
6997 #else
6998   MAKE_RGBA_PACK_FORMAT (ARGB64, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
6999       OFFS2460, SUB444, PACK_ARGB64),
7000   MAKE_YUVA_PACK_FORMAT (AYUV64, "raw video", 0x00000000, DPTH16_16_16_16,
7001       PSTR8888, PLANE0, OFFS2460, SUB444, PACK_AYUV64),
7002 #endif
7003   MAKE_RGB_FORMAT (r210, "raw video", DPTH10_10_10, PSTR444, PLANE0, OFFS0,
7004       SUB444, PACK_r210),
7005   MAKE_YUV_FORMAT (I420_10BE, "raw video", 0x00000000, DPTH10_10_10,
7006       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10BE),
7007   MAKE_YUV_LE_FORMAT (I420_10LE, "raw video", 0x00000000, DPTH10_10_10,
7008       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_10LE),
7009   MAKE_YUV_FORMAT (I422_10BE, "raw video", 0x00000000, DPTH10_10_10,
7010       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10BE),
7011   MAKE_YUV_LE_FORMAT (I422_10LE, "raw video", 0x00000000, DPTH10_10_10,
7012       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_10LE),
7013   MAKE_YUV_FORMAT (Y444_10BE, "raw video", 0x00000000, DPTH10_10_10,
7014       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10BE),
7015   MAKE_YUV_LE_FORMAT (Y444_10LE, "raw video", 0x00000000, DPTH10_10_10,
7016       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_10LE),
7017   MAKE_RGB_FORMAT (GBR, "raw video", DPTH888, PSTR111, PLANE201, OFFS0, SUB444,
7018       PACK_GBR),
7019   MAKE_RGB_FORMAT (GBR_10BE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
7020       OFFS0, SUB444, PACK_GBR_10BE),
7021   MAKE_RGB_LE_FORMAT (GBR_10LE, "raw video", DPTH10_10_10, PSTR222, PLANE201,
7022       OFFS0, SUB444, PACK_GBR_10LE),
7023   MAKE_YUV_FORMAT (NV16, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '6'),
7024       DPTH888, PSTR122, PLANE011, OFFS001, SUB422, PACK_NV16),
7025   MAKE_YUV_FORMAT (NV24, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '4'),
7026       DPTH888, PSTR122, PLANE011, OFFS001, SUB444, PACK_NV24),
7027   MAKE_YUV_T_FORMAT (NV12_64Z32, "raw video",
7028       GST_MAKE_FOURCC ('T', 'M', '1', '2'), DPTH888, PSTR122, PLANE011,
7029       OFFS001, SUB420, PACK_NV12_TILED, TILE_64x32 (ZFLIPZ_2X2)),
7030   MAKE_YUVA_FORMAT (A420_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
7031       PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_10BE),
7032   MAKE_YUVA_LE_FORMAT (A420_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
7033       PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_10LE),
7034   MAKE_YUVA_FORMAT (A422_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
7035       PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_10BE),
7036   MAKE_YUVA_LE_FORMAT (A422_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
7037       PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_10LE),
7038   MAKE_YUVA_FORMAT (A444_10BE, "raw video", 0x00000000, DPTH10_10_10_10,
7039       PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_10BE),
7040   MAKE_YUVA_LE_FORMAT (A444_10LE, "raw video", 0x00000000, DPTH10_10_10_10,
7041       PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_10LE),
7042   MAKE_YUV_FORMAT (NV61, "raw video", GST_MAKE_FOURCC ('N', 'V', '6', '1'),
7043       DPTH888, PSTR122, PLANE011, OFFS010, SUB422, PACK_NV61),
7044   MAKE_YUV_FORMAT (P010_10BE, "raw video", 0x00000000, DPTH10_10_10_HI,
7045       PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10BE),
7046   MAKE_YUV_LE_FORMAT (P010_10LE, "raw video", 0x00000000, DPTH10_10_10_HI,
7047       PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10LE),
7048   MAKE_YUV_FORMAT (IYU2, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '2'),
7049       DPTH888, PSTR333, PLANE0, OFFS102, SUB444, PACK_IYU2),
7050   MAKE_YUV_FORMAT (VYUY, "raw video", GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y'),
7051       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_VYUY),
7052   MAKE_RGBA_FORMAT (GBRA, "raw video", DPTH8888, PSTR1111, PLANE2013,
7053       OFFS0, SUB4444, PACK_GBRA),
7054   MAKE_RGBA_FORMAT (GBRA_10BE, "raw video", DPTH10_10_10_10, PSTR2222,
7055       PLANE2013, OFFS0, SUB4444, PACK_GBRA_10BE),
7056   MAKE_RGBA_LE_FORMAT (GBRA_10LE, "raw video", DPTH10_10_10_10, PSTR2222,
7057       PLANE2013, OFFS0, SUB4444, PACK_GBRA_10LE),
7058   MAKE_RGB_FORMAT (GBR_12BE, "raw video", DPTH12_12_12, PSTR222, PLANE201,
7059       OFFS0, SUB444, PACK_GBR_12BE),
7060   MAKE_RGB_LE_FORMAT (GBR_12LE, "raw video", DPTH12_12_12, PSTR222, PLANE201,
7061       OFFS0, SUB444, PACK_GBR_12LE),
7062   MAKE_RGBA_FORMAT (GBRA_12BE, "raw video", DPTH12_12_12_12, PSTR2222,
7063       PLANE2013, OFFS0, SUB4444, PACK_GBRA_12BE),
7064   MAKE_RGBA_LE_PACK_FORMAT (GBRA_12LE, "raw video", DPTH12_12_12_12, PSTR2222,
7065       PLANE2013, OFFS0, SUB4444, PACK_GBRA_12LE),
7066   MAKE_YUV_FORMAT (I420_12BE, "raw video", 0x00000000, DPTH12_12_12,
7067       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_12BE),
7068   MAKE_YUV_LE_FORMAT (I420_12LE, "raw video", 0x00000000, DPTH12_12_12,
7069       PSTR222, PLANE012, OFFS0, SUB420, PACK_I420_12LE),
7070   MAKE_YUV_FORMAT (I422_12BE, "raw video", 0x00000000, DPTH12_12_12,
7071       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_12BE),
7072   MAKE_YUV_LE_FORMAT (I422_12LE, "raw video", 0x00000000, DPTH12_12_12,
7073       PSTR222, PLANE012, OFFS0, SUB422, PACK_I422_12LE),
7074   MAKE_YUV_FORMAT (Y444_12BE, "raw video", 0x00000000, DPTH12_12_12,
7075       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_12BE),
7076   MAKE_YUV_LE_FORMAT (Y444_12LE, "raw video", 0x00000000, DPTH12_12_12,
7077       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_12LE),
7078   MAKE_GRAY_C_LE_FORMAT (GRAY10_LE32, "raw video", DPTH10, PSTR0, PLANE0, OFFS0,
7079       SUB4, PACK_GRAY10_LE32),
7080   MAKE_YUV_C_LE_FORMAT (NV12_10LE32, "raw video",
7081       GST_MAKE_FOURCC ('X', 'V', '1', '5'), DPTH10_10_10, PSTR0, PLANE011,
7082       OFFS001, SUB420, PACK_NV12_10LE32),
7083   MAKE_YUV_C_LE_FORMAT (NV16_10LE32, "raw video",
7084       GST_MAKE_FOURCC ('X', 'V', '2', '0'), DPTH10_10_10, PSTR0, PLANE011,
7085       OFFS001, SUB422, PACK_NV16_10LE32),
7086   MAKE_YUV_C_LE_FORMAT (NV12_10LE40, "raw video",
7087       GST_MAKE_FOURCC ('R', 'K', '2', '0'), DPTH10_10_10, PSTR0, PLANE011,
7088       OFFS0, SUB420, PACK_NV12_10LE40),
7089   MAKE_YUV_FORMAT (Y210, "raw video", GST_MAKE_FOURCC ('Y', '2', '1', '0'),
7090       DPTH10_10_10, PSTR488, PLANE0, OFFS0, SUB422, PACK_Y210),
7091   MAKE_YUV_FORMAT (Y410, "raw video", GST_MAKE_FOURCC ('Y', '4', '1', '0'),
7092       DPTH10_10_10_2, PSTR4444, PLANE0, OFFS0, SUB4444, PACK_Y410),
7093   MAKE_YUVA_PACK_FORMAT (VUYA, "raw video", GST_MAKE_FOURCC ('V', 'U', 'Y',
7094           'A'), DPTH8888, PSTR4444, PLANE0, OFFS2103, SUB4444, PACK_VUYA),
7095   MAKE_RGBA_LE_PACK_FORMAT (BGR10A2_LE, "raw video", DPTH10_10_10_2, PSTR4444,
7096       PLANE0,
7097       OFFS0, SUB4444, PACK_BGR10A2_LE),
7098   MAKE_RGBA_LE_PACK_FORMAT (RGB10A2_LE, "raw video", DPTH10_10_10_2, PSTR4444,
7099       PLANE0, OFFS0, SUB4444, PACK_RGB10A2_LE),
7100   MAKE_YUV_FORMAT (Y444_16BE, "raw video", 0x00000000, DPTH16_16_16,
7101       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_16BE),
7102   MAKE_YUV_LE_FORMAT (Y444_16LE, "raw video", 0x00000000, DPTH16_16_16,
7103       PSTR222, PLANE012, OFFS0, SUB444, PACK_Y444_16LE),
7104   MAKE_YUV_FORMAT (P016_BE, "raw video", 0x00000000, DPTH16_16_16,
7105       PSTR244, PLANE011, OFFS001, SUB420, PACK_P016_BE),
7106   MAKE_YUV_LE_FORMAT (P016_LE, "raw video", 0x00000000, DPTH16_16_16,
7107       PSTR244, PLANE011, OFFS001, SUB420, PACK_P016_LE),
7108   MAKE_YUV_FORMAT (P012_BE, "raw video", 0x00000000, DPTH12_12_12_HI,
7109       PSTR244, PLANE011, OFFS001, SUB420, PACK_P012_BE),
7110   MAKE_YUV_LE_FORMAT (P012_LE, "raw video", 0x00000000, DPTH12_12_12_HI,
7111       PSTR244, PLANE011, OFFS001, SUB420, PACK_P012_LE),
7112   MAKE_YUV_FORMAT (Y212_BE, "raw video", 0x00000000, DPTH12_12_12_HI,
7113       PSTR488, PLANE0, OFFS0, SUB422, PACK_Y212_BE),
7114   MAKE_YUV_LE_FORMAT (Y212_LE, "raw video", 0x00000000, DPTH12_12_12_HI,
7115       PSTR488, PLANE0, OFFS0, SUB422, PACK_Y212_LE),
7116   MAKE_YUV_FORMAT (Y412_BE, "raw video", 0x00000000, DPTH12_12_12_12_HI,
7117       PSTR8888, PLANE0, OFFS0, SUB4444, PACK_Y412_BE),
7118   MAKE_YUV_LE_FORMAT (Y412_LE, "raw video", 0x00000000, DPTH12_12_12_12_HI,
7119       PSTR8888, PLANE0, OFFS0, SUB4444, PACK_Y412_LE),
7120   MAKE_YUV_T_FORMAT (NV12_4L4, "raw video",
7121       GST_MAKE_FOURCC ('V', 'T', '1', '2'), DPTH888, PSTR122, PLANE011,
7122       OFFS001, SUB420, PACK_NV12_TILED, TILE_4x4 (LINEAR)),
7123   MAKE_YUV_T_FORMAT (NV12_32L32, "raw video",
7124       GST_MAKE_FOURCC ('S', 'T', '1', '2'), DPTH888, PSTR122, PLANE011,
7125       OFFS001, SUB420, PACK_NV12_TILED, TILE_32x32 (LINEAR)),
7126   MAKE_RGB_FORMAT (RGBP, "raw video", DPTH888, PSTR111, PLANE012, OFFS0, SUB444,
7127       PACK_RGBP),
7128   MAKE_RGB_FORMAT (BGRP, "raw video", DPTH888, PSTR111, PLANE210, OFFS0, SUB444,
7129       PACK_BGRP),
7130   MAKE_YUV_FORMAT (AV12, "raw video", GST_MAKE_FOURCC ('A', 'V', '1', '2'),
7131       DPTH8888, PSTR1221, PLANE0112, OFFS001, SUB4204, PACK_AV12),
7132   MAKE_RGBA_LE_FORMAT (ARGB64_LE, "raw video", DPTH16_16_16_16, PSTR8888,
7133       PLANE0, OFFS2460, SUB4444, PACK_ARGB64_LE),
7134   MAKE_RGBA_FORMAT (ARGB64_BE, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
7135       OFFS2460, SUB4444, PACK_ARGB64_BE),
7136   MAKE_RGBA_LE_FORMAT (RGBA64_LE, "raw video", DPTH16_16_16_16, PSTR8888,
7137       PLANE0, OFFS0246, SUB4444, PACK_RGBA64_LE),
7138   MAKE_RGBA_FORMAT (RGBA64_BE, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
7139       OFFS0246, SUB4444, PACK_RGBA64_BE),
7140   MAKE_RGBA_LE_FORMAT (BGRA64_LE, "raw video", DPTH16_16_16_16, PSTR8888,
7141       PLANE0, OFFS4206, SUB4444, PACK_BGRA64_LE),
7142   MAKE_RGBA_FORMAT (BGRA64_BE, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
7143       OFFS4206, SUB4444, PACK_BGRA64_BE),
7144   MAKE_RGBA_LE_FORMAT (ABGR64_LE, "raw video", DPTH16_16_16_16, PSTR8888,
7145       PLANE0, OFFS6420, SUB444, PACK_ABGR64_LE),
7146   MAKE_RGBA_FORMAT (ABGR64_BE, "raw video", DPTH16_16_16_16, PSTR8888, PLANE0,
7147       OFFS6420, SUB4444, PACK_ABGR64_BE),
7148 };
7149 
7150 static GstVideoFormat
gst_video_format_from_rgb32_masks(int red_mask,int green_mask,int blue_mask)7151 gst_video_format_from_rgb32_masks (int red_mask, int green_mask, int blue_mask)
7152 {
7153   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
7154       blue_mask == 0x0000ff00) {
7155     return GST_VIDEO_FORMAT_RGBx;
7156   }
7157   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
7158       blue_mask == 0xff000000) {
7159     return GST_VIDEO_FORMAT_BGRx;
7160   }
7161   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
7162       blue_mask == 0x000000ff) {
7163     return GST_VIDEO_FORMAT_xRGB;
7164   }
7165   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
7166       blue_mask == 0x00ff0000) {
7167     return GST_VIDEO_FORMAT_xBGR;
7168   }
7169 
7170   return GST_VIDEO_FORMAT_UNKNOWN;
7171 }
7172 
7173 static GstVideoFormat
gst_video_format_from_rgba32_masks(int red_mask,int green_mask,int blue_mask,int alpha_mask)7174 gst_video_format_from_rgba32_masks (int red_mask, int green_mask,
7175     int blue_mask, int alpha_mask)
7176 {
7177   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
7178       blue_mask == 0x0000ff00 && alpha_mask == 0x000000ff) {
7179     return GST_VIDEO_FORMAT_RGBA;
7180   }
7181   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
7182       blue_mask == 0xff000000 && alpha_mask == 0x000000ff) {
7183     return GST_VIDEO_FORMAT_BGRA;
7184   }
7185   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
7186       blue_mask == 0x000000ff && alpha_mask == 0xff000000) {
7187     return GST_VIDEO_FORMAT_ARGB;
7188   }
7189   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
7190       blue_mask == 0x00ff0000 && alpha_mask == 0xff000000) {
7191     return GST_VIDEO_FORMAT_ABGR;
7192   }
7193   return GST_VIDEO_FORMAT_UNKNOWN;
7194 }
7195 
7196 static GstVideoFormat
gst_video_format_from_rgb24_masks(int red_mask,int green_mask,int blue_mask)7197 gst_video_format_from_rgb24_masks (int red_mask, int green_mask, int blue_mask)
7198 {
7199   if (red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff) {
7200     return GST_VIDEO_FORMAT_RGB;
7201   }
7202   if (red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000) {
7203     return GST_VIDEO_FORMAT_BGR;
7204   }
7205 
7206   return GST_VIDEO_FORMAT_UNKNOWN;
7207 }
7208 
7209 #define GST_VIDEO_COMP1_MASK_16_INT 0xf800
7210 #define GST_VIDEO_COMP2_MASK_16_INT 0x07e0
7211 #define GST_VIDEO_COMP3_MASK_16_INT 0x001f
7212 
7213 #define GST_VIDEO_COMP1_MASK_15_INT 0x7c00
7214 #define GST_VIDEO_COMP2_MASK_15_INT 0x03e0
7215 #define GST_VIDEO_COMP3_MASK_15_INT 0x001f
7216 
7217 static GstVideoFormat
gst_video_format_from_rgb16_masks(int red_mask,int green_mask,int blue_mask)7218 gst_video_format_from_rgb16_masks (int red_mask, int green_mask, int blue_mask)
7219 {
7220   if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
7221       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
7222       && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
7223     return GST_VIDEO_FORMAT_RGB16;
7224   }
7225   if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
7226       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
7227       && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
7228     return GST_VIDEO_FORMAT_BGR16;
7229   }
7230   if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
7231       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
7232       && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
7233     return GST_VIDEO_FORMAT_RGB15;
7234   }
7235   if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
7236       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
7237       && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
7238     return GST_VIDEO_FORMAT_BGR15;
7239   }
7240   return GST_VIDEO_FORMAT_UNKNOWN;
7241 }
7242 
7243 /**
7244  * gst_video_format_from_masks:
7245  * @depth: the amount of bits used for a pixel
7246  * @bpp: the amount of bits used to store a pixel. This value is bigger than
7247  *   @depth
7248  * @endianness: the endianness of the masks, #G_LITTLE_ENDIAN or #G_BIG_ENDIAN
7249  * @red_mask: the red mask
7250  * @green_mask: the green mask
7251  * @blue_mask: the blue mask
7252  * @alpha_mask: the alpha mask, or 0 if no alpha mask
7253  *
7254  * Find the #GstVideoFormat for the given parameters.
7255  *
7256  * Returns: a #GstVideoFormat or GST_VIDEO_FORMAT_UNKNOWN when the parameters to
7257  * not specify a known format.
7258  */
7259 GstVideoFormat
gst_video_format_from_masks(gint depth,gint bpp,gint endianness,guint red_mask,guint green_mask,guint blue_mask,guint alpha_mask)7260 gst_video_format_from_masks (gint depth, gint bpp, gint endianness,
7261     guint red_mask, guint green_mask, guint blue_mask, guint alpha_mask)
7262 {
7263   GstVideoFormat format;
7264 
7265   /* our caps system handles 24/32bpp RGB as big-endian. */
7266   if ((bpp == 24 || bpp == 32) && endianness == G_LITTLE_ENDIAN &&
7267       alpha_mask != 0xc0000000) {
7268     red_mask = GUINT32_TO_BE (red_mask);
7269     green_mask = GUINT32_TO_BE (green_mask);
7270     blue_mask = GUINT32_TO_BE (blue_mask);
7271     alpha_mask = GUINT32_TO_BE (alpha_mask);
7272     endianness = G_BIG_ENDIAN;
7273     if (bpp == 24) {
7274       red_mask >>= 8;
7275       green_mask >>= 8;
7276       blue_mask >>= 8;
7277     }
7278   }
7279 
7280   if (depth == 32 && bpp == 32 && alpha_mask == 0xc0000000 &&
7281       endianness == G_LITTLE_ENDIAN) {
7282     if (red_mask == 0x3ff00000)
7283       format = GST_VIDEO_FORMAT_RGB10A2_LE;
7284     else
7285       format = GST_VIDEO_FORMAT_BGR10A2_LE;
7286   } else if (depth == 30 && bpp == 32) {
7287     format = GST_VIDEO_FORMAT_r210;
7288   } else if (depth == 24 && bpp == 32) {
7289     format = gst_video_format_from_rgb32_masks (red_mask, green_mask,
7290         blue_mask);
7291   } else if (depth == 32 && bpp == 32 && alpha_mask) {
7292     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
7293         blue_mask, alpha_mask);
7294   } else if (depth == 24 && bpp == 24) {
7295     format = gst_video_format_from_rgb24_masks (red_mask, green_mask,
7296         blue_mask);
7297   } else if ((depth == 15 || depth == 16) && bpp == 16 &&
7298       endianness == G_BYTE_ORDER) {
7299     format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
7300         blue_mask);
7301   } else if (depth == 8 && bpp == 8) {
7302     format = GST_VIDEO_FORMAT_RGB8P;
7303   } else if (depth == 64 && bpp == 64) {
7304     format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
7305         blue_mask, alpha_mask);
7306     if (format == GST_VIDEO_FORMAT_ARGB) {
7307       format = GST_VIDEO_FORMAT_ARGB64;
7308     } else {
7309       format = GST_VIDEO_FORMAT_UNKNOWN;
7310     }
7311   } else {
7312     format = GST_VIDEO_FORMAT_UNKNOWN;
7313   }
7314   return format;
7315 }
7316 
7317 /**
7318  * gst_video_format_from_fourcc:
7319  * @fourcc: a FOURCC value representing raw YUV video
7320  *
7321  * Converts a FOURCC value into the corresponding #GstVideoFormat.
7322  * If the FOURCC cannot be represented by #GstVideoFormat,
7323  * #GST_VIDEO_FORMAT_UNKNOWN is returned.
7324  *
7325  * Returns: the #GstVideoFormat describing the FOURCC value
7326  */
7327 GstVideoFormat
gst_video_format_from_fourcc(guint32 fourcc)7328 gst_video_format_from_fourcc (guint32 fourcc)
7329 {
7330   switch (fourcc) {
7331     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
7332       return GST_VIDEO_FORMAT_I420;
7333     case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
7334       return GST_VIDEO_FORMAT_YV12;
7335     case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
7336       return GST_VIDEO_FORMAT_YUY2;
7337     case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
7338       return GST_VIDEO_FORMAT_YVYU;
7339     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
7340       return GST_VIDEO_FORMAT_UYVY;
7341     case GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y'):
7342       return GST_VIDEO_FORMAT_VYUY;
7343     case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
7344       return GST_VIDEO_FORMAT_AYUV;
7345     case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
7346       return GST_VIDEO_FORMAT_Y41B;
7347     case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
7348       return GST_VIDEO_FORMAT_Y42B;
7349     case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
7350       return GST_VIDEO_FORMAT_Y444;
7351     case GST_MAKE_FOURCC ('v', '2', '1', '0'):
7352       return GST_VIDEO_FORMAT_v210;
7353     case GST_MAKE_FOURCC ('v', '2', '1', '6'):
7354       return GST_VIDEO_FORMAT_v216;
7355     case GST_MAKE_FOURCC ('Y', '2', '1', '0'):
7356       return GST_VIDEO_FORMAT_Y210;
7357     case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
7358       return GST_VIDEO_FORMAT_NV12;
7359     case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
7360       return GST_VIDEO_FORMAT_NV21;
7361     case GST_MAKE_FOURCC ('N', 'V', '1', '6'):
7362       return GST_VIDEO_FORMAT_NV16;
7363     case GST_MAKE_FOURCC ('N', 'V', '6', '1'):
7364       return GST_VIDEO_FORMAT_NV61;
7365     case GST_MAKE_FOURCC ('N', 'V', '2', '4'):
7366       return GST_VIDEO_FORMAT_NV24;
7367     case GST_MAKE_FOURCC ('v', '3', '0', '8'):
7368       return GST_VIDEO_FORMAT_v308;
7369     case GST_MAKE_FOURCC ('I', 'Y', 'U', '2'):
7370       return GST_VIDEO_FORMAT_IYU2;
7371     case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
7372     case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
7373     case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
7374       return GST_VIDEO_FORMAT_GRAY8;
7375     case GST_MAKE_FOURCC ('Y', '1', '6', ' '):
7376       return GST_VIDEO_FORMAT_GRAY16_LE;
7377     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'):
7378       return GST_VIDEO_FORMAT_UYVP;
7379     case GST_MAKE_FOURCC ('A', '4', '2', '0'):
7380       return GST_VIDEO_FORMAT_A420;
7381     case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
7382       return GST_VIDEO_FORMAT_YUV9;
7383     case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
7384       return GST_VIDEO_FORMAT_YVU9;
7385     case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
7386       return GST_VIDEO_FORMAT_IYU1;
7387     case GST_MAKE_FOURCC ('A', 'Y', '6', '4'):
7388       return GST_VIDEO_FORMAT_AYUV64;
7389     case GST_MAKE_FOURCC ('X', 'V', '1', '0'):
7390       return GST_VIDEO_FORMAT_GRAY10_LE32;
7391     case GST_MAKE_FOURCC ('X', 'V', '1', '5'):
7392       return GST_VIDEO_FORMAT_NV12_10LE32;
7393     case GST_MAKE_FOURCC ('X', 'V', '2', '0'):
7394       return GST_VIDEO_FORMAT_NV16_10LE32;
7395     case GST_MAKE_FOURCC ('R', 'K', '2', '0'):
7396       return GST_VIDEO_FORMAT_NV12_10LE40;
7397     case GST_MAKE_FOURCC ('Y', '4', '1', '0'):
7398       return GST_VIDEO_FORMAT_Y410;
7399     case GST_MAKE_FOURCC ('V', 'U', 'Y', 'A'):
7400       return GST_VIDEO_FORMAT_VUYA;
7401     case GST_MAKE_FOURCC ('A', 'R', '3', '0'):
7402       return GST_VIDEO_FORMAT_BGR10A2_LE;
7403 
7404     default:
7405       return GST_VIDEO_FORMAT_UNKNOWN;
7406   }
7407 }
7408 
7409 /**
7410  * gst_video_format_from_string:
7411  * @format: a format string
7412  *
7413  * Convert the @format string to its #GstVideoFormat.
7414  *
7415  * Returns: the #GstVideoFormat for @format or GST_VIDEO_FORMAT_UNKNOWN when the
7416  * string is not a known format.
7417  */
7418 GstVideoFormat
gst_video_format_from_string(const gchar * format)7419 gst_video_format_from_string (const gchar * format)
7420 {
7421   guint i;
7422 
7423   g_return_val_if_fail (format != NULL, GST_VIDEO_FORMAT_UNKNOWN);
7424 
7425   for (i = 0; i < G_N_ELEMENTS (formats); i++) {
7426     if (strcmp (GST_VIDEO_FORMAT_INFO_NAME (&formats[i].info), format) == 0)
7427       return GST_VIDEO_FORMAT_INFO_FORMAT (&formats[i].info);
7428   }
7429   return GST_VIDEO_FORMAT_UNKNOWN;
7430 }
7431 
7432 
7433 /**
7434  * gst_video_format_to_fourcc:
7435  * @format: a #GstVideoFormat video format
7436  *
7437  * Converts a #GstVideoFormat value into the corresponding FOURCC.  Only
7438  * a few YUV formats have corresponding FOURCC values.  If @format has
7439  * no corresponding FOURCC value, 0 is returned.
7440  *
7441  * Returns: the FOURCC corresponding to @format
7442  */
7443 guint32
gst_video_format_to_fourcc(GstVideoFormat format)7444 gst_video_format_to_fourcc (GstVideoFormat format)
7445 {
7446   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
7447 
7448   if ((gint) format >= G_N_ELEMENTS (formats))
7449     return 0;
7450 
7451   return formats[format].fourcc;
7452 }
7453 
7454 /**
7455  * gst_video_format_to_string:
7456  * @format: a #GstVideoFormat video format
7457  *
7458  * Returns a string containing a descriptive name for
7459  * the #GstVideoFormat if there is one, or NULL otherwise.
7460  *
7461  * Returns: the name corresponding to @format
7462  */
7463 const gchar *
gst_video_format_to_string(GstVideoFormat format)7464 gst_video_format_to_string (GstVideoFormat format)
7465 {
7466   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
7467 
7468   if ((gint) format >= G_N_ELEMENTS (formats))
7469     return NULL;
7470 
7471   return GST_VIDEO_FORMAT_INFO_NAME (&formats[format].info);
7472 }
7473 
7474 /**
7475  * gst_video_format_get_info:
7476  * @format: a #GstVideoFormat
7477  *
7478  * Get the #GstVideoFormatInfo for @format
7479  *
7480  * Returns: The #GstVideoFormatInfo for @format.
7481  */
7482 const GstVideoFormatInfo *
gst_video_format_get_info(GstVideoFormat format)7483 gst_video_format_get_info (GstVideoFormat format)
7484 {
7485   g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
7486 
7487   return &formats[format].info;
7488 }
7489 
7490 /**
7491  * gst_video_format_get_palette:
7492  * @format: a #GstVideoFormat
7493  * @size: (out): size of the palette in bytes
7494  *
7495  * Get the default palette of @format. This the palette used in the pack
7496  * function for paletted formats.
7497  *
7498  * Returns: (transfer none): the default palette of @format or %NULL when
7499  * @format does not have a palette.
7500  *
7501  * Since: 1.2
7502  */
7503 gconstpointer
gst_video_format_get_palette(GstVideoFormat format,gsize * size)7504 gst_video_format_get_palette (GstVideoFormat format, gsize * size)
7505 {
7506   g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
7507   g_return_val_if_fail (size != NULL, NULL);
7508 
7509   switch (format) {
7510     case GST_VIDEO_FORMAT_RGB8P:
7511       *size = sizeof (std_palette_RGB8P);
7512       return std_palette_RGB8P;
7513     default:
7514       return NULL;
7515   }
7516 }
7517 
7518 /**
7519  * gst_video_format_info_component:
7520  * @info: #GstVideoFormatInfo
7521  * @plane: a plane number
7522  * @components: (out): array used to store component numbers
7523  *
7524  * Fill @components with the number of all the components packed in plane @p
7525  * for the format @info. A value of -1 in @components indicates that no more
7526  * components are packed in the plane.
7527  *
7528  * Since: 1.18
7529  */
7530 void
gst_video_format_info_component(const GstVideoFormatInfo * info,guint plane,gint components[GST_VIDEO_MAX_COMPONENTS])7531 gst_video_format_info_component (const GstVideoFormatInfo * info, guint plane,
7532     gint components[GST_VIDEO_MAX_COMPONENTS])
7533 {
7534   guint c, i = 0;
7535 
7536   /* Reverse mapping of info->plane */
7537   for (c = 0; c < GST_VIDEO_FORMAT_INFO_N_COMPONENTS (info); c++) {
7538     if (GST_VIDEO_FORMAT_INFO_PLANE (info, c) == plane) {
7539       components[i] = c;
7540       i++;
7541     }
7542   }
7543 
7544   for (c = i; c < GST_VIDEO_MAX_COMPONENTS; c++)
7545     components[c] = -1;
7546 }
7547 
7548 struct RawVideoFormats
7549 {
7550   GstVideoFormat *formats;
7551   guint n;
7552 };
7553 
7554 static gpointer
generate_raw_video_formats(gpointer data)7555 generate_raw_video_formats (gpointer data)
7556 {
7557   GValue list = G_VALUE_INIT;
7558   struct RawVideoFormats *all = g_new (struct RawVideoFormats, 1);
7559   gchar *tmp;
7560   guint i;
7561   gboolean res G_GNUC_UNUSED;
7562 
7563   g_value_init (&list, GST_TYPE_LIST);
7564   /* Workaround a bug in our parser that would lead to segfaults
7565    * when deserializing container types using static strings,
7566    * see https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/446 */
7567   tmp = g_strdup (GST_VIDEO_FORMATS_ALL);
7568   res = gst_value_deserialize (&list, tmp);
7569   g_assert (res);
7570   g_free (tmp);
7571 
7572   all->n = gst_value_list_get_size (&list);
7573   all->formats = g_new (GstVideoFormat, all->n);
7574 
7575   for (i = 0; i < all->n; i++) {
7576     const GValue *v = gst_value_list_get_value (&list, i);
7577 
7578     all->formats[i] = gst_video_format_from_string (g_value_get_string (v));
7579     g_assert (all->formats[i] != GST_VIDEO_FORMAT_UNKNOWN
7580         && all->formats[i] != GST_VIDEO_FORMAT_ENCODED);
7581   }
7582 
7583   g_value_unset (&list);
7584 
7585   return all;
7586 }
7587 
7588 /**
7589  * gst_video_formats_raw:
7590  * @len: (out): the number of elements in the returned array
7591  *
7592  * Return all the raw video formats supported by GStreamer.
7593  *
7594  * Returns: (transfer none) (array length=len): an array of #GstVideoFormat
7595  * Since: 1.18
7596  */
7597 const GstVideoFormat *
gst_video_formats_raw(guint * len)7598 gst_video_formats_raw (guint * len)
7599 {
7600   static GOnce raw_video_formats_once = G_ONCE_INIT;
7601   struct RawVideoFormats *all;
7602 
7603   g_return_val_if_fail (len, NULL);
7604 
7605   g_once (&raw_video_formats_once, generate_raw_video_formats, NULL);
7606 
7607   all = raw_video_formats_once.retval;
7608   *len = all->n;
7609   return all->formats;
7610 }
7611 
7612 /**
7613  * gst_video_make_raw_caps:
7614  * @formats: (array length=len) (nullable): an array of raw #GstVideoFormat, or %NULL
7615  * @len: the size of @formats
7616  *
7617  * Return a generic raw video caps for formats defined in @formats.
7618  * If @formats is %NULL returns a caps for all the supported raw video formats,
7619  * see gst_video_formats_raw().
7620  *
7621  * Returns: (transfer full): a video @GstCaps
7622  * Since: 1.18
7623  */
7624 GstCaps *
gst_video_make_raw_caps(const GstVideoFormat formats[],guint len)7625 gst_video_make_raw_caps (const GstVideoFormat formats[], guint len)
7626 {
7627   return gst_video_make_raw_caps_with_features (formats, len, NULL);
7628 }
7629 
7630 /**
7631  * gst_video_make_raw_caps_with_features:
7632  * @formats: (array length=len) (nullable): an array of raw #GstVideoFormat, or %NULL
7633  * @len: the size of @formats
7634  * @features: (transfer full) (allow-none): the #GstCapsFeatures to set on the caps
7635  *
7636  * Return a generic raw video caps for formats defined in @formats with features
7637  * @features.
7638  * If @formats is %NULL returns a caps for all the supported video formats,
7639  * see gst_video_formats_raw().
7640  *
7641  * Returns: (transfer full): a video @GstCaps
7642  * Since: 1.18
7643  */
7644 GstCaps *
gst_video_make_raw_caps_with_features(const GstVideoFormat formats[],guint len,GstCapsFeatures * features)7645 gst_video_make_raw_caps_with_features (const GstVideoFormat formats[],
7646     guint len, GstCapsFeatures * features)
7647 {
7648   GstStructure *s;
7649   GValue format = G_VALUE_INIT;
7650   GstCaps *caps;
7651 
7652   g_return_val_if_fail ((formats && len > 0) || (!formats && len == 0), NULL);
7653 
7654   if (!formats) {
7655     formats = gst_video_formats_raw (&len);
7656   }
7657 
7658   if (len > 1) {
7659     guint i;
7660 
7661     g_value_init (&format, GST_TYPE_LIST);
7662 
7663     for (i = 0; i < len; i++) {
7664       GValue v = G_VALUE_INIT;
7665 
7666       g_return_val_if_fail (formats[i] != GST_VIDEO_FORMAT_UNKNOWN
7667           && formats[i] != GST_VIDEO_FORMAT_ENCODED, NULL);
7668 
7669       g_value_init (&v, G_TYPE_STRING);
7670       g_value_set_static_string (&v, gst_video_format_to_string (formats[i]));
7671       gst_value_list_append_and_take_value (&format, &v);
7672     }
7673   } else {
7674     g_value_init (&format, G_TYPE_STRING);
7675 
7676     g_value_set_static_string (&format,
7677         gst_video_format_to_string (formats[0]));
7678   }
7679 
7680   s = gst_structure_new ("video/x-raw",
7681       "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
7682       "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
7683       "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
7684 
7685   gst_structure_take_value (s, "format", &format);
7686 
7687   caps = gst_caps_new_full (s, NULL);
7688 
7689   if (features)
7690     gst_caps_set_features (caps, 0, features);
7691 
7692   return caps;
7693 }
7694