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