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