UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
video_codec.c
Go to the documentation of this file.
1
16/* Copyright (c) 2005-2023 CESNET z.s.p.o.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, is permitted provided that the following conditions
20 * are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 *
29 * 3. All advertising materials mentioning features or use of this software
30 * must display the following acknowledgement:
31 *
32 * This product includes software developed by CESNET z.s.p.o.
33 *
34 * 4. Neither the name of the CESNET nor the names of its contributors may be
35 * used to endorse or promote products derived from this software without
36 * specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
39 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
40 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
41 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
42 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
43 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
45 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 *
51 */
52
53#define __STDC_WANT_LIB_EXT1__ 1
54
55#ifdef HAVE_CONFIG_H
56#include "config.h"
57#endif // HAVE_CONFIG_H
58#include "config_unix.h"
59#include "config_win32.h"
60
61#include <assert.h>
62#include <stdint.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66
67#include "color.h"
68#include "compat/qsort_s.h"
69#include "debug.h"
70#include "host.h"
71#include "hwaccel_vdpau.h"
72#include "hwaccel_drm.h"
73#include "utils/macros.h" // to_fourcc, OPTIMEZED_FOR
74#include "video_codec.h"
75
76#ifdef __SSSE3__
77#include "tmmintrin.h"
78#endif
79
80char pixfmt_conv_pref[] = "dsc";
81
82#ifdef WORDS_BIGENDIAN
83#define BYTE_SWAP(x) (3 - x)
84#else
85#define BYTE_SWAP(x) x
86#endif
87
88#ifdef __SSE2__
89static void vc_deinterlace_aligned(unsigned char *src, long src_linesize, int lines);
90static void vc_deinterlace_unaligned(unsigned char *src, long src_linesize, int lines);
91#endif
92
100 const char *name;
101 const char *name_long;
102 uint32_t fcc;
107 unsigned rgb:1;
108 unsigned opaque:1;
109 unsigned interframe:1;
110 unsigned const_size:1;
112 const char *file_extension;
113};
114
115#ifdef HWACC_VDPAU
116#define HW_VDPAU_FRAME_SZ sizeof(hw_vdpau_frame)
117#else
118#define HW_VDPAU_FRAME_SZ 0
119#endif
120
121static const struct codec_info_t codec_info[] = {
122 [VIDEO_CODEC_NONE] = {"(none)", "Undefined Codec",
123 0, 0, 0.0, 0, 0, FALSE, FALSE, FALSE, FALSE, 0, NULL},
124 [RGBA] = {"RGBA", "Red Green Blue Alpha 32bit",
125 to_fourcc('R','G','B','A'), 4, 1, 1, 8, TRUE, FALSE, FALSE, FALSE, 4444, "rgba"},
126 [UYVY] = {"UYVY", "YUV 4:2:2",
127 to_fourcc('U','Y','V','Y'), 4, 2, 2, 8, FALSE, FALSE, FALSE, FALSE, 4220, "yuv"},
128 [YUYV] = {"YUYV", "YUV 4:2:2",
129 to_fourcc('Y','U','Y','V'), 4, 2, 2, 8, FALSE, FALSE, FALSE, FALSE, 4220, "yuv"},
130 [R10k] = {"R10k", "10-bit RGB 4:4:4", // called 'R10b' in BMD SDK
131 to_fourcc('R','1','0','k'), 4, 1, 64, 10, TRUE, FALSE, FALSE, FALSE, 4440, "r10k"},
132 [R12L] = {"R12L", "12-bit packed RGB 4:4:4 little-endian", // SMPTE 268M DPX v1, Annex C, Method C4
133 to_fourcc('R','1','2','l'), 36, 8, 8, 12, TRUE, FALSE, FALSE, FALSE, 4440, "r12l"},
134 [v210] = {"v210", "10-bit YUV 4:2:2",
135 to_fourcc('v','2','1','0'), 16, 6, 48, 10, FALSE, FALSE, FALSE, FALSE, 4220, "v210"},
136 [DVS10] = {"DVS10", "Centaurus 10bit YUV 4:2:2",
137 to_fourcc('D','S','1','0'), 16, 6, 48, 10, FALSE, FALSE, FALSE, FALSE, 4220, "dvs10"},
138 [DXT1] = {"DXT1", "S3 Compressed Texture DXT1",
139 to_fourcc('D','X','T','1'), 1, 2, 0, 2, TRUE, TRUE, FALSE, FALSE, 0, "dxt1"},
140 [DXT1_YUV] = {"DXT1_YUV", "S3 Compressed Texture DXT1 YUV",
141 to_fourcc('D','X','T','Y'), 1, 2, 0, 2, FALSE, TRUE, FALSE, FALSE, 0, "dxt1y"}, /* packet YCbCr inside DXT1 channels */
142 [DXT5] = {"DXT5", "S3 Compressed Texture DXT5 YCoCg",
143 to_fourcc('D','X','T','5'), 1, 1, 0, 4, FALSE, TRUE, FALSE, FALSE, 0, "yog"},/* DXT5 YCoCg */
144 [RGB] = {"RGB", "Red Green Blue 24bit",
145 to_fourcc('R','G','B','2'), 3, 1, 1, 8, TRUE, FALSE, FALSE, FALSE, 4440, "rgb"},
146 [JPEG] = {"JPEG", "JPEG",
147 to_fourcc('J','P','E','G'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "jpg"},
148 [RAW] = {"raw", "Raw SDI video",
149 to_fourcc('r','a','w','s'), 1, 1, 0, 0, FALSE, TRUE, FALSE, FALSE, 0, "raw"}, /* raw SDI */
150 [H264] = {"H.264", "H.264/AVC",
151 to_fourcc('A','V','C','1'), 1, 1, 0, 8, FALSE, TRUE, TRUE, FALSE, 0, "h264"},
152 [H265] = {"H.265", "H.265/HEVC",
153 to_fourcc('H','E','V','C'), 1, 1, 0, 8, FALSE, TRUE, TRUE, FALSE, 0, "h265"},
154 [MJPG] = {"MJPEG", "MJPEG",
155 to_fourcc('M','J','P','G'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "jpg"},
156 [VP8] = {"VP8", "Google VP8",
157 to_fourcc('V','P','8','0'), 1, 1, 0, 8, FALSE, TRUE, TRUE, FALSE, 0, "vp8"},
158 [VP9] = {"VP9", "Google VP9",
159 to_fourcc('V','P','9','0'), 1, 1, 0, 8, FALSE, TRUE, TRUE, FALSE, 0, "vp9"},
160 [BGR] = {"BGR", "Blue Green Red 24bit",
161 to_fourcc('B','G','R','2'), 3, 1, 1, 8, TRUE, FALSE, FALSE, FALSE, 4440, "bgr"},
162 [J2K] = {"J2K", "JPEG 2000",
163 to_fourcc('M','J','2','C'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "j2k"},
164 [J2KR] = {"J2KR", "JPEG 2000 RGB",
165 to_fourcc('M','J','2','R'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "j2k"},
166 [HW_VDPAU] = {"HW_VDPAU", "VDPAU hardware surface",
167 to_fourcc('V', 'D', 'P', 'S'), HW_VDPAU_FRAME_SZ, 1, 0, 8, FALSE, TRUE, FALSE, TRUE, 4440, "vdpau"},
168 [HFYU] = {"HFYU", "HuffYUV",
169 to_fourcc('H','F','Y','U'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "hfyu"},
170 [FFV1] = {"FFV1", "FFV1",
171 to_fourcc('F','F','V','1'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "ffv1"},
172 [CFHD] = {"CFHD", "Cineform",
173 to_fourcc('C','F','H','D'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "cfhd"},
174 [RG48] = {"RG48", "16-bit RGB little-endian",
175 to_fourcc('R','G','4','8'), 6, 1, 1, 16, TRUE, FALSE, FALSE, FALSE, 4440, "rg48"},
176 [AV1] = {"AV1", "AOMedia Video 1",
177 to_fourcc('a','v','0','1'), 1, 1, 0, 8, FALSE, TRUE, TRUE, FALSE, 0, "av1"},
178 [I420] = {"I420", "planar YUV 4:2:0",
179 to_fourcc('I','4','2','0'), 3, 2, 2, 8, FALSE, FALSE, FALSE, FALSE, 4200, "yuv"},
180 [Y216] = {"Y216", "Packed 16-bit YUV 4:2:2 little-endian",
181 to_fourcc('Y','2','1','6'), 8, 2, 2, 16, FALSE, FALSE, FALSE, FALSE, 4220, "y216"},
182 [Y416] = {"Y416", "Packed 16-bit YUV 4:4:4:4 little-endian",
183 to_fourcc('Y','4','1','6'), 8, 1, 1, 16, FALSE, FALSE, FALSE, FALSE, 4444, "y416"},
184 [PRORES] = {"PRORES", "Apple ProRes",
185 0, 1, 1, 0, 8, FALSE, TRUE, TRUE, FALSE, 0, "pror"},
186 [PRORES_4444] = {"PRORES_4444", "Apple ProRes 4444",
187 to_fourcc('a','p','4','h'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "ap4h"},
188 [PRORES_4444_XQ] = {"PRORES_4444_XQ", "Apple ProRes 4444 (XQ)",
189 to_fourcc('a','p','4','x'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "ap4x"},
190 [PRORES_422_HQ] = {"PRORES_422_HQ", "Apple ProRes 422 (HQ)",
191 to_fourcc('a','p','c','h'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "apch"},
192 [PRORES_422] = {"PRORES_422", "Apple ProRes 422",
193 to_fourcc('a','p','c','n'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "apcn"},
194 [PRORES_422_PROXY] = {"PRORES_422_PROXY", "Apple ProRes 422 (Proxy)",
195 to_fourcc('a','p','c','o'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "apco"},
196 [PRORES_422_LT] = {"PRORES_422_LT", "Apple ProRes 422 (LT)",
197 to_fourcc('a','p','c','s'), 1, 1, 0, 8, FALSE, TRUE, FALSE, FALSE, 0, "apcs"},
198 [DRM_PRIME] = {"DRM_PRIME", "DRM Prime buffer",
199 to_fourcc('D', 'R', 'M', 'P'), sizeof(struct drm_prime_frame), 1, 0, 8, FALSE, TRUE, FALSE, TRUE, 0, "drm_prime"},
200};
201
204 int plane_info[8];
205};
206
207static const struct pixfmt_plane_info_t pixfmt_plane_info[] = {
208 [I420] = {{1, 1, 2, 2, 2, 2, 0, 0}},
209 [VIDEO_CODEC_END] = {{0}}, // end must be present to all codecs to have the metadata defined
210};
211
216 uint32_t alias;
217 uint32_t primary_fcc;
218};
219
223static const struct alternative_fourcc fourcc_aliases[] = {
224 // the following two are here because it was sent with wrong endiannes in past
225 {to_fourcc('A', 'B', 'G', 'R'), to_fourcc('R', 'G', 'B', 'A')},
226 {to_fourcc('2', 'B', 'G', 'R'), to_fourcc('R', 'G', 'B', '2')},
227 // following ones are rather for further compatibility (proposed codecs rename)
228 {to_fourcc('M', 'J', 'P', 'G'), to_fourcc('J', 'P', 'E', 'G')},
229
230 {to_fourcc('2', 'V', 'u', 'y'), to_fourcc('U', 'Y', 'V', 'Y')},
231 {to_fourcc('2', 'v', 'u', 'y'), to_fourcc('U', 'Y', 'V', 'Y')},
232 {to_fourcc('d', 'v', 's', '8'), to_fourcc('U', 'Y', 'V', 'Y')},
233 {to_fourcc('D', 'V', 'S', '8'), to_fourcc('U', 'Y', 'V', 'Y')},
234 {to_fourcc('y', 'u', 'v', '2'), to_fourcc('U', 'Y', 'V', 'Y')},
235 {to_fourcc('y', 'u', 'V', '2'), to_fourcc('U', 'Y', 'V', 'Y')},
236};
237
239 const char *alias;
240 const char *primary_name;
241};
242
244 {"2vuy", "UYVY"},
245 {"AVC", "H.264"},
246 {"H264", "H.264"},
247 {"HEVC", "H.265"},
248};
249
250void show_codec_help(const char *module, const codec_t *codecs8, const codec_t *codecs10, const codec_t *codecs_ge12)
251{
252 printf("Supported codecs (%s):\n", module);
253
254 if (codecs8) {
255 printf("\t8bits\n");
256
257 while (*codecs8 != VIDEO_CODEC_NONE) {
258 printf("\t\t'%s' - %s\n", codec_info[*codecs8].name, codec_info[*codecs8].name_long);
259 codecs8++;
260 }
261 }
262
263 if (codecs10) {
264 printf("\t10bits\n");
265 while (*codecs10 != VIDEO_CODEC_NONE) {
266 printf("\t\t'%s' - %s\n", codec_info[*codecs10].name, codec_info[*codecs10].name_long);
267 codecs10++;
268 }
269 }
270
271 if (codecs_ge12) {
272 printf("\t12+ bits\n");
273 while (*codecs_ge12 != VIDEO_CODEC_NONE) {
274 printf("\t\t'%s' - %s\n", codec_info[*codecs_ge12].name, codec_info[*codecs_ge12].name_long);
275 codecs_ge12++;
276 }
277 }
278}
279
281{
282 unsigned int i = (unsigned int) codec;
283
284 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
286 }
287 assert(0);
288}
289
292{
293 int subsampling = 0;
294 if (codec < sizeof codec_info / sizeof(struct codec_info_t)) {
296 }
297 assert(subsampling != 0);
298 return subsampling;
299}
300
302{
303 unsigned int i = (unsigned int) codec;
304 double bpp = 0;
305
306 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
307 bpp = (double) codec_info[i].block_size_bytes /
308 codec_info[i].block_size_pixels;
309 }
310 assert(bpp != 0);
311 return bpp;
312}
313
315{
316 unsigned int i = (unsigned int) codec;
317 uint32_t fourcc = 0;
318
319 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
320 fourcc = codec_info[i].fcc;
321 }
322 assert(fourcc != 0);
323 return fourcc;
324}
325
327{
328 unsigned int i = (unsigned int) codec;
329 const char *name = NULL;
330
331 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
332 name = codec_info[i].name;
333 }
334 assert(name != NULL);
335 return name;
336}
337
339{
340 unsigned int i = (unsigned int) codec;
341 const char *name_long = NULL;
342
343 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
344 name_long = codec_info[i].name_long;
345 }
346 assert(name_long != NULL);
347 return name_long;
348}
349
351{
352 for (unsigned int i = 0; i < sizeof codec_info / sizeof(struct codec_info_t); ++i) {
353 if (fourcc == codec_info[i].fcc)
354 return i;
355 }
356
357 // try to look through aliases
358 for (size_t i = 0; i < sizeof(fourcc_aliases) / sizeof(struct alternative_fourcc); ++i) {
359 if (fourcc == fourcc_aliases[i].alias) {
360 for (unsigned int j = 0; j < sizeof codec_info / sizeof(struct codec_info_t); ++j) {
361 if (fourcc_aliases[i].primary_fcc == codec_info[j].fcc)
362 return j;
363 }
364 }
365 }
366 return VIDEO_CODEC_NONE;
367}
368
377{
378 for (unsigned int i = 0; i < sizeof codec_info / sizeof(struct codec_info_t); ++i) {
379 if (codec_info[i].name && strcasecmp(codec_info[i].name, name) == 0) {
380 return i;
381 }
382 }
383
384 return VIDEO_CODEC_NONE;
385}
386
388{
390 if (ret != VIDEO_CODEC_NONE) {
391 return ret;
392 }
393
394 // try to find if this is not an alias
395 for (size_t i = 0; i < sizeof(codec_name_aliases) / sizeof(struct alternative_codec_name); ++i) {
396 if (strcasecmp(name, codec_name_aliases[i].alias) == 0) {
398 if (ret != VIDEO_CODEC_NONE) {
399 return ret;
400 }
401 }
402 }
403 return VIDEO_CODEC_NONE;
404}
405
407{
408 unsigned int i = (unsigned int) codec;
409
410 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
411 return codec_info[i].file_extension;
412 } else {
413 return 0;
414 }
415}
416
418{
419 for (unsigned int i = 0; i < sizeof codec_info / sizeof(struct codec_info_t); ++i) {
420 if (codec_info[i].file_extension && strcasecmp(codec_info[i].file_extension, ext) == 0) {
421 return i;
422 }
423 }
424
425 return VIDEO_CODEC_NONE;
426}
427
433{
434 unsigned int i = (unsigned int) codec;
435
436 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
437 return codec_info[i].opaque;
438 }
439 return false;
440}
441
449{
450 unsigned int i = (unsigned int) codec;
451
452 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
453 return codec_info[i].interframe;
454 }
455 return false;
456}
457
464{
465 unsigned int i = (unsigned int) codec;
466
467 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
468 return codec_info[i].rgb;
469 }
470 return false;
471}
472
480{
481 unsigned int i = (unsigned int) codec;
482
483 if (i < sizeof codec_info / sizeof(struct codec_info_t)) {
484 return codec_info[i].const_size;
485 }
486 return false;
487}
488
492
498int vc_get_linesize(unsigned int width, codec_t codec)
499{
500 if (codec >= sizeof codec_info / sizeof(struct codec_info_t)) {
501 return 0;
502 }
503
504 if (codec_info[codec].h_align) {
505 width =
506 ((width + codec_info[codec].h_align -
507 1) / codec_info[codec].h_align) *
509 }
511 return (width + pixs - 1) / pixs * codec_info[codec].block_size_bytes;
512}
513
521int vc_get_size(unsigned int width, codec_t codec)
522{
523 if (codec >= sizeof codec_info / sizeof(struct codec_info_t)) {
524 return 0;
525 }
526
528 return (width + pixs - 1) / pixs * codec_info[codec].block_size_bytes;
529}
530
534size_t vc_get_datalen(unsigned int width, unsigned int height, codec_t codec)
535{
536 if (!codec_is_planar(codec)) {
537 return vc_get_linesize(width, codec) * height;
538 }
539
540 assert(get_bits_per_component(codec) == 8);
541 size_t ret = 0;
542 int sub[8];
544 for (int i = 0; i < 4; ++i) {
545 if (sub[i * 2] == 0) { // less than 4 planes
546 break;
547 }
548 ret += ((width + sub[i * 2] - 1) / sub[i * 2])
549 * ((height + sub[i * 2 + 1] - 1) / sub[i * 2 + 1]);
550 }
551
552 return ret;
553}
554
557{
558 unsigned int i = (unsigned int) codec;
559
560 if (i >= sizeof codec_info / sizeof(struct codec_info_t)) {
561 abort();
562 }
563 assert(codec_info[i].block_size_bytes > 0);
565}
566
569{
570 unsigned int i = (unsigned int) codec;
571
572 if (i >= sizeof codec_info / sizeof(struct codec_info_t)) {
573 abort();
574 }
575 assert(codec_info[i].block_size_pixels > 0);
577}
578
588void vc_deinterlace(unsigned char *src, long src_linesize, int lines)
589{
590#ifdef __SSE2__
591 if(((uintptr_t) src & 0x0Fu) == 0u && src_linesize % 16 == 0) {
592 vc_deinterlace_aligned(src, src_linesize, lines);
593 } else {
594 vc_deinterlace_unaligned(src, src_linesize, lines);
595 }
596#else
597 for (int y = 0; y < lines; y += 2) {
598 for (int x = 0; x < src_linesize; ++x) {
599 int val = (*src + src[src_linesize] + 1) >> 1;
600 *src = src[src_linesize] = val;
601 src++;
602 }
603 src += src_linesize;
604 }
605#endif
606}
607
608#ifdef __SSE2__
615static void vc_deinterlace_aligned(unsigned char *src, long src_linesize, int lines)
616{
617 int i, j;
618 long pitch = src_linesize;
619 register long pitch2 = pitch * 2;
620 unsigned char *bline1, *bline2, *bline3;
621 register unsigned char *line1, *line2, *line3;
622
623 bline1 = src;
624 bline2 = src + pitch;
625 bline3 = src + 3 * pitch;
626 for (i = 0; i < src_linesize; i += 16) {
627 /* preload first two lines */
628 asm volatile ("movdqa (%0), %%xmm0\n"
629 "movdqa (%1), %%xmm1\n"::"r" ((unsigned long *)(void *)
630 bline1),
631 "r"((unsigned long *)(void *) bline2));
632 line1 = bline2;
633 line2 = bline2 + pitch;
634 line3 = bline3;
635 for (j = 0; j < lines - 4; j += 2) {
636 asm volatile ("movdqa (%1), %%xmm2\n"
637 "pavgb %%xmm2, %%xmm0\n"
638 "pavgb %%xmm1, %%xmm0\n"
639 "movdqa (%2), %%xmm1\n"
640 "movdqa %%xmm0, (%0)\n"
641 "pavgb %%xmm1, %%xmm0\n"
642 "pavgb %%xmm2, %%xmm0\n"
643 "movdqa %%xmm0, (%1)\n"::"r" ((unsigned
644 long *) (void *) line1),
645 "r"((unsigned long *) (void *) line2),
646 "r"((unsigned long *) (void *) line3)
647 );
648 line1 += pitch2;
649 line2 += pitch2;
650 line3 += pitch2;
651 }
652 bline1 += 16;
653 bline2 += 16;
654 bline3 += 16;
655 }
656}
663static void vc_deinterlace_unaligned(unsigned char *src, long src_linesize, int lines)
664{
665 int i, j;
666 long pitch = src_linesize;
667 register long pitch2 = pitch * 2;
668 unsigned char *bline1, *bline2, *bline3;
669 register unsigned char *line1, *line2, *line3;
670
671 bline1 = src;
672 bline2 = src + pitch;
673 bline3 = src + 3 * pitch;
674 for (i = 0; i < src_linesize; i += 16) {
675 /* preload first two lines */
676 asm volatile ("movdqu (%0), %%xmm0\n"
677 "movdqu (%1), %%xmm1\n"::"r" (bline1),
678 "r" (bline2));
679 line1 = bline2;
680 line2 = bline2 + pitch;
681 line3 = bline3;
682 for (j = 0; j < lines - 4; j += 2) {
683 asm volatile ("movdqu (%1), %%xmm2\n"
684 "pavgb %%xmm2, %%xmm0\n"
685 "pavgb %%xmm1, %%xmm0\n"
686 "movdqu (%2), %%xmm1\n"
687 "movdqu %%xmm0, (%0)\n"
688 "pavgb %%xmm1, %%xmm0\n"
689 "pavgb %%xmm2, %%xmm0\n"
690 "movdqu %%xmm0, (%1)\n"::"r" (line1),
691 "r" (line2),
692 "r" (line3)
693 );
694 line1 += pitch2;
695 line2 += pitch2;
696 line3 += pitch2;
697 }
698 bline1 += 16;
699 bline2 += 16;
700 bline3 += 16;
701 }
702}
703#endif
704
711// Sibling of this function is in double-framerate.cpp:avg_lines so consider
712// porting changes made here there.
713bool vc_deinterlace_ex(codec_t codec, unsigned char *src, size_t src_linesize, unsigned char *dst, size_t dst_pitch, size_t lines)
714{
716 return false;
717 }
718 if (lines == 1) {
719 memcpy(dst, src, src_linesize);
720 return true;
721 }
723 int bpp = get_bits_per_component(codec);
724 for (size_t y = 0; y < lines - 1; y += 1) {
725 unsigned char *s = src + y * src_linesize;
726 unsigned char *d = dst + y * dst_pitch;
727 if (bpp == 8 || bpp == 16) {
728 size_t x = 0;
729#ifdef __SSSE3__
730 if (bpp == 8) {
731 for ( ; x < src_linesize / 16; ++x) {
732 __m128i i1 = _mm_lddqu_si128((__m128i const*)(const void *) s);
733 __m128i i2 = _mm_lddqu_si128((__m128i const*)(const void *) (s + src_linesize));
734 __m128i res = _mm_avg_epu8(i1, i2);
735 _mm_storeu_si128((__m128i *)(void *) d, res);
736 s += 16;
737 d += 16;
738 }
739 } else {
740 for ( ; x < src_linesize / 16; ++x) {
741 __m128i i1 = _mm_lddqu_si128((__m128i const*)(const void *) s);
742 __m128i i2 = _mm_lddqu_si128((__m128i const*)(const void *) (s + src_linesize));
743 __m128i res = _mm_avg_epu16(i1, i2);
744 _mm_storeu_si128((__m128i *)(void *) d, res);
745 s += 16;
746 d += 16;
747 }
748 }
749#endif
750 x *= 16;
751 if (bpp == 8) {
752 for ( ; x < src_linesize; ++x) {
753 int val = (*s + s[src_linesize] + 1) >> 1;
754 *d++ = val;
755 s++;
756 }
757 } else {
758 uint16_t *d16 = (void *) d;
759 uint16_t *s16 = (void *) s;
760 for ( ; x < src_linesize / 2; ++x) {
761 int val = (*s16 + s16[src_linesize / 2] + 1) >> 1;
762 *d16++ = val;
763 s16++;
764 }
765 }
766 } else if (codec == v210) {
767 uint32_t *s32 = (void *) s;
768 uint32_t *d32 = (void *) d;
769 for (size_t x = 0; x < src_linesize / 16; ++x) {
770 #pragma GCC unroll 4
771 for (size_t y = 0; y < 4; ++y) {
772 uint32_t v1 = *s32;
773 uint32_t v2 = s32[src_linesize / 4];
774 uint32_t out =
775 (((v1 >> 20 ) + (v2 >> 20 ) + 1) / 2) << 20 |
776 (((v1 >> 10 & 0x3ff) + (v2 >> 10 & 0x3ff) + 1) / 2) << 10 |
777 (((v1 & 0x3ff) + (v2 & 0x3ff) + 1) / 2);
778 *d32++ = out;
779 s32++;
780 }
781 }
782 } else if (codec == R10k) {
783 uint32_t *s32 = (void *) s;
784 uint32_t *d32 = (void *) d;
785 for (size_t x = 0; x < src_linesize / 16; ++x) {
786 #pragma GCC unroll 4
787 for (size_t y = 0; y < 4; ++y) {
788 uint32_t v1 = ntohl(*s32);
789 uint32_t v2 = ntohl(s32[src_linesize / 4]);
790 uint32_t out =
791 (((v1 >> 22 ) + (v2 >> 22 ) + 1) / 2) << 22 |
792 (((v1 >> 12 & 0x3ff) + (v2 >> 12 & 0x3ff) + 1) / 2) << 12 |
793 (((v1 >> 2 & 0x3ff) + (v2 >> 2 & 0x3ff) + 1) / 2) << 2;
794 *d32++ = htonl(out);
795 s32++;
796 }
797 }
798 } else if (codec == R12L) {
799 uint32_t *s32 = (void *) s;
800 uint32_t *d32 = (void *) d;
801 int shift = 0;
802 uint32_t remain1 = 0;
803 uint32_t remain2 = 0;
804 uint32_t out = 0;
805 for (size_t x = 0; x < src_linesize / 36; ++x) {
806 #pragma GCC unroll 8
807 for (size_t y = 0; y < 8; ++y) {
808 uint32_t in1 = *s32;
809 uint32_t in2 = s32[src_linesize / 4];
810 if (shift > 0) {
811 remain1 = remain1 | (in1 & ((1<<((shift + 12) % 32)) - 1)) << (32-shift);
812 remain2 = remain2 | (in2 & ((1<<((shift + 12) % 32)) - 1)) << (32-shift);
813 uint32_t ret = (remain1 + remain2 + 1) / 2;
814 out |= ret << shift;
815 *d32++ = out;
816 out = ret >> (32-shift);
817 shift = (shift + 12) % 32;
818 in1 >>= shift;
819 in2 >>= shift;
820 }
821 while (shift <= 32 - 12) {
822 out |= ((((in1 & 0xfff) + (in2 & 0xfff)) + 1) / 2) << shift;
823 in1 >>= 12;
824 in2 >>= 12;
825 shift += 12;
826 }
827 if (shift == 32) {
828 *d32++ = out;
829 out = 0;
830 shift = 0;
831 } else {
832 remain1 = in1;
833 remain2 = in2;
834 }
835 s32++;
836 }
837 }
838 } else {
839 return false;
840 }
841 }
842 memcpy(dst + (lines - 1) * dst_pitch, dst + (lines - 2) * dst_pitch, src_linesize); // last line
844 return true;
845}
846
852{
853 assert (codec != VIDEO_CODEC_NONE);
854 assert (set != NULL);
855 while (*set != VIDEO_CODEC_NONE) {
856 if (*(set++) == codec)
857 return true;
858 }
859 return false;
860}
861
862bool clear_video_buffer(unsigned char *data, size_t linesize, size_t pitch, size_t height, codec_t color_spec)
863{
864 uint32_t pattern[4];
865
866 switch (color_spec) {
867 case BGR:
868 case RGB:
869 case RGBA:
870 memset(pattern, 0, sizeof(pattern));
871 break;
872 case UYVY:
873 for (int i = 0; i < 4; i++) {
874 pattern[i] = 0x00800080;
875 }
876 break;
877 case v210:
878 pattern[0] = 0x20000200;
879 pattern[1] = 0x00080000;
880 pattern[2] = 0x20000200;
881 pattern[3] = 0x00080000;
882 break;
883#ifdef HWACC_VDPAU
884 case HW_VDPAU:
885 memset(data, 0,sizeof(hw_vdpau_frame));
886 return true;
887#endif
888 default:
889 return false;
890 }
891
892 for (size_t y = 0; y < height; ++y) {
893 uintptr_t i;
894 for( i = 0; i < (linesize & (~15)); i+=16)
895 {
896 memcpy(data + i, pattern, 16);
897 }
898 for( ; i < linesize; i++ )
899 {
900 ((char*)data)[i] = ((char*)pattern)[i&15];
901 }
902
903 data += pitch;
904 }
905
906 return true;
907}
908
915
924void codec_get_planes_subsampling(codec_t pix_fmt, int *sub) {
925 for (size_t i = 0; i < 8; ++i) {
926 *sub++ = pixfmt_plane_info[pix_fmt].plane_info[i];
927 }
928}
929
931{
932 return pixfmt_plane_info[pix_fmt].plane_info[0] == 1 &&
933 pixfmt_plane_info[pix_fmt].plane_info[1] == 1 &&
934 pixfmt_plane_info[pix_fmt].plane_info[2] == 2 &&
935 pixfmt_plane_info[pix_fmt].plane_info[3] == 2 &&
936 pixfmt_plane_info[pix_fmt].plane_info[4] == 2 &&
937 pixfmt_plane_info[pix_fmt].plane_info[5] == 2;
938}
939
940void
941uyvy_to_i422(int width, int height, const unsigned char *in, unsigned char *out)
942{
943 unsigned char *out_y = out;
944 unsigned char *out_cb = out + width * height;
945 unsigned char *out_cr =
946 out + width * height + ((width + 1) / 2) * height;
947 for (int y = 0; y < height; ++y) {
948 for (int x = 0; x < width / 2; ++x) {
949 *out_cb++ = *in++;
950 *out_y++ = *in++;
951 *out_cr++ = *in++;
952 *out_y++ = *in++;
953 }
954 if (width % 2 == 1) {
955 *out_cb++ = *in++;
956 *out_y++ = *in++;
957 *out_cr++ = *in++;
958 }
959 }
960}
961
962void
963y416_to_i444(int width, int height, const unsigned char *in, unsigned char *out,
964 int depth)
965{
966 const uint16_t *inp = (const uint16_t *) (const void *) in;
967 uint16_t *out_y = (uint16_t *) (void *) out;
968 uint16_t *out_cb = (uint16_t *) (void *) out + width * height;
969 uint16_t *out_cr = (uint16_t *) (void *) out + 2 * width * height;
970 for (int y = 0; y < height; ++y) {
971 for (int x = 0; x < width; ++x) {
972 *out_cb++ = *inp++ >> (16 - depth);
973 *out_y++ = *inp++ >> (16 - depth);
974 *out_cr++ = *inp++ >> (16 - depth);
975 inp++; // alpha
976 }
977 }
978}
979
980void
981i444_16_to_y416(int width, int height, const unsigned char *in,
982 unsigned char *out, int in_depth)
983{
984 const uint16_t *in_y = (const uint16_t *)(const void *) in;
985 const uint16_t *in_cb = (const uint16_t *)(const void *) in + width * height;
986 const uint16_t *in_cr = (const uint16_t *)(const void *) in + 2 * width * height;
987 uint16_t *outp = (uint16_t *)(void *) out;
988 for (int y = 0; y < height; ++y) {
989 for (int x = 0; x < width; ++x) {
990 *outp++ = *in_cb++ << (16 - in_depth);
991 *outp++ = *in_y++ << (16 - in_depth);
992 *outp++ = *in_cr++ << (16 - in_depth);
993 *outp++ = 0xFFFFU; // alpha
994 }
995 }
996}
997
998void
999i422_16_to_y416(int width, int height, const unsigned char *in,
1000 unsigned char *out, int in_depth)
1001{
1002 enum { ALPHA16_OPAQUE = 0xFFFF };
1003 const uint16_t *in_y = (const uint16_t *) (const void *) in;
1004 const uint16_t *in_cb = in_y + (ptrdiff_t) width * height;
1005 const uint16_t *in_cr = in_cb + (ptrdiff_t) ((width + 1) / 2) * height;
1006 uint16_t *outp = (void *) out;
1007 for (int y = 0; y < height; ++y) {
1008 for (int x = 0; x < (width + 1) / 2; ++x) {
1009 *outp++ = *in_cb << (DEPTH16 - in_depth);
1010 *outp++ = *in_y++ << (DEPTH16 - in_depth);
1011 *outp++ = *in_cr << (DEPTH16 - in_depth);
1012 *outp++ = ALPHA16_OPAQUE;
1013 *outp++ = *in_cb++ << (DEPTH16 - in_depth);
1014 *outp++ = *in_y++ << (DEPTH16 - in_depth);
1015 *outp++ = *in_cr++ << (DEPTH16 - in_depth);
1016 *outp++ = ALPHA16_OPAQUE;
1017 }
1018 }
1019}
1020
1021void
1022i420_16_to_y416(int width, int height, const unsigned char *in,
1023 unsigned char *out, int in_depth)
1024{
1025 enum { ALPHA16_OPAQUE = 0xFFFF };
1026 const uint16_t *in_y1 = (const void *) in;
1027 const uint16_t *in_y2 = in_y1 + width;
1028 const uint16_t *in_cb =
1029 (const uint16_t *) (const void *) in + (ptrdiff_t) width * height;
1030 const uint16_t *in_cr =
1031 in_cb + (ptrdiff_t) ((width + 1) / 2) * ((height + 1) / 2);
1032 const size_t out_line_len = vc_get_linesize(width, Y416) / 2;
1033 uint16_t *outp1 = (void *) out;
1034 uint16_t *outp2 = outp1 + out_line_len;
1035 for (int y = 0; y < (height + 1) / 2; ++y) {
1036 for (int x = 0; x < (width + 1) / 2; ++x) {
1037 *outp1++ = *in_cb << (DEPTH16 - in_depth);
1038 *outp1++ = *in_y1++ << (DEPTH16 - in_depth);
1039 *outp1++ = *in_cr << (DEPTH16 - in_depth);
1040 *outp1++ = ALPHA16_OPAQUE;
1041
1042 *outp2++ = *in_cb << (DEPTH16 - in_depth);
1043 *outp2++ = *in_y2++ << (DEPTH16 - in_depth);
1044 *outp2++ = *in_cr << (DEPTH16 - in_depth);
1045 *outp2++ = ALPHA16_OPAQUE;
1046
1047 *outp1++ = *in_cb << (DEPTH16 - in_depth);
1048 *outp1++ = *in_y1++ << (DEPTH16 - in_depth);
1049 *outp1++ = *in_cr << (DEPTH16 - in_depth);
1050 *outp1++ = ALPHA16_OPAQUE;
1051
1052 *outp2++ = *in_cb++ << (DEPTH16 - in_depth);
1053 *outp2++ = *in_y2++ << (DEPTH16 - in_depth);
1054 *outp2++ = *in_cr++ << (DEPTH16 - in_depth);
1055 *outp2++ = ALPHA16_OPAQUE;
1056 }
1057 outp1 += out_line_len;
1058 outp2 += out_line_len;
1059 in_y1 += width;
1060 in_y2 += width;
1061 }
1062}
1063void
1064i420_8_to_uyvy(int width, int height, const unsigned char *in, unsigned char *out)
1065{
1066 const int uyvy_linesize = vc_get_linesize(width, UYVY);
1067 const unsigned char *const cb = in + (ptrdiff_t) width * height;
1068 const unsigned char *const cr =
1069 cb + (ptrdiff_t) (width / 2) * (height / 2);
1070
1071 for (ptrdiff_t y = 0; y < height; ++y) {
1072 const unsigned char *src_y = in + width * y;
1073 const unsigned char *src_cb = cb + (width / 2) * (y / 2);
1074 const unsigned char *src_cr = cr + (width / 2) * (y / 2);
1075 unsigned char *dst = out + y * uyvy_linesize;
1076
1077 OPTIMIZED_FOR(int x = 0; x < width / 2; ++x)
1078 {
1079 *dst++ = *src_cb++;
1080 *dst++ = *src_y++;
1081 *dst++ = *src_cr++;
1082 *dst++ = *src_y++;
1083 }
1084 }
1085}
1086
1087void
1088i422_8_to_uyvy(int width, int height, const unsigned char *in,
1089 unsigned char *out)
1090{
1091 const unsigned char *in_y = in;
1092 const unsigned char *in_cb = in + width * height;
1093 const unsigned char *in_cr = in_cb + (((width + 1) / 2) * height);
1094 unsigned char *outp = out;
1095 for (int y = 0; y < height; ++y) {
1096 for (int x = 0; x < (width + 1) / 2; ++x) {
1097 *outp++ = *in_cb++;
1098 *outp++ = *in_y++;
1099 *outp++ = *in_cr++;
1100 *outp++ = *in_y++;
1101 }
1102 }
1103}
1104
1105void
1106i444_8_to_uyvy(int width, int height, const unsigned char *in,
1107 unsigned char *out)
1108{
1109 const unsigned char *in_y = in;
1110 const unsigned char *in_cb = in + width * height;
1111 const unsigned char *in_cr = in_cb + width * height;
1112 unsigned char *outp = out;
1113 for (int y = 0; y < height; ++y) {
1114 for (int x = 0; x < (width + 1) / 2; ++x) {
1115 *outp++ = *in_cb;
1116 *outp++ = *in_y++;
1117 *outp++ = *in_cr;
1118 *outp++ = *in_y++;
1119 in_cb += 2;
1120 in_cr += 2;
1121 }
1122 }
1123}
1124
1126{
1127 assert(pixfmt >= VIDEO_CODEC_FIRST && pixfmt < VIDEO_CODEC_END);
1128 struct pixfmt_desc ret = { 0 };
1129 ret.depth = codec_info[pixfmt].bits_per_channel;
1130 ret.subsampling = codec_info[pixfmt].subsampling;
1131 ret.rgb = codec_info[pixfmt].rgb;
1132 return ret;
1133}
1134
1138int compare_pixdesc(const struct pixfmt_desc *desc_a, const struct pixfmt_desc *desc_b, const struct pixfmt_desc *src_desc)
1139{
1140 for (char *feature = pixfmt_conv_pref; *feature != '\0'; ++feature) {
1141 switch (*feature) {
1142 case 'd':
1143 if (desc_a->depth != desc_b->depth &&
1144 (desc_a->depth < src_desc->depth || desc_b->depth < src_desc->depth)) { // either a or b is lower than orig - sort higher bit depth first
1145 return desc_b->depth - desc_a->depth;
1146 }
1147 break;
1148 case 's':
1149 if (desc_a->subsampling != desc_b->subsampling &&
1150 (desc_a->subsampling < src_desc->subsampling || desc_b->subsampling < src_desc->subsampling)) {
1151 return desc_b->subsampling - desc_a->subsampling; // return better subs
1152 }
1153 break;
1154 case 'c':
1155 if (desc_a->rgb != desc_b->rgb) {
1156 return desc_a->rgb == src_desc->rgb ? -1 : 1;
1157 }
1158 break;
1159 }
1160 }
1161
1162 // if both A and B are either undistinguishable or better than src, return closer ("worse") pixfmt
1163 for (char *feature = pixfmt_conv_pref; *feature != '\0'; ++feature) {
1164 switch (*feature) {
1165 case 'd':
1166 if (desc_a->depth != desc_b->depth) {
1167 return desc_a->depth - desc_b->depth;
1168 }
1169 break;
1170 case 's':
1171 if (desc_a->subsampling != desc_b->subsampling) {
1172 return desc_a->subsampling - desc_b->subsampling;
1173 }
1174 break;
1175 case 'c':
1176 // will be a tie here
1177 break;
1178 }
1179 }
1180
1181 return 0;
1182}
1183
1184void watch_pixfmt_degrade(const char *mod_name, struct pixfmt_desc desc_src, struct pixfmt_desc desc_dst)
1185{
1186 char message[1024];
1187 message[0] = '\0';
1188 if (desc_dst.depth < desc_src.depth) {
1189 snprintf(message, sizeof message, "conversion is reducing bit depth from %d to %d", desc_src.depth, desc_dst.depth);
1190 }
1191 if (desc_dst.subsampling < desc_src.subsampling) {
1192 if (strlen(message) > 0) {
1193 snprintf(message + strlen(message), sizeof message - strlen(message), " and subsampling from %d to %d", desc_src.subsampling, desc_dst.subsampling);
1194 } else {
1195 snprintf(message, sizeof message, "conversion is reducing subsampling from %d to %d", desc_src.subsampling, desc_dst.subsampling);
1196 }
1197 }
1198 if (strlen(message) > 0) {
1199 log_msg(LOG_LEVEL_WARNING, "%s%s\n", mod_name, message);
1200 }
1201}
1202
1204{
1205 if (desc.depth == 0) {
1206 return "(undefined)";
1207 }
1208 _Thread_local static char buf[128];
1209 snprintf(buf, sizeof buf, "%s %d:%d:%d", desc.rgb ? "RGB" : "YCbCr", desc.subsampling / 1000, desc.subsampling % 1000 / 100, desc.subsampling % 100 / 10);
1210 if (desc.subsampling % 10 != 0) {
1211 snprintf(buf + strlen(buf), sizeof buf - strlen(buf), ":%d", desc.subsampling % 10);
1212 }
1213 snprintf(buf + strlen(buf), sizeof buf - strlen(buf), " %d bit", desc.depth);
1214 return buf;
1215}
1216
1217bool pixdesc_equals(struct pixfmt_desc desc_a, struct pixfmt_desc desc_b) {
1218 return desc_a.depth == desc_b.depth &&
1219 desc_a.subsampling == desc_b.subsampling &&
1220 desc_a.rgb == desc_b.rgb;
1221}
1222
1223/* vim: set expandtab sw=8: */
int void * val
struct video_desc desc
pattern
Definition testcard.c:94
#define TRUE
#define FALSE
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define DEBUG_TIMER_START(name)
Definition debug.h:324
#define DEBUG_TIMER_STOP(name)
Definition debug.h:325
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
This file contains functions related to hw acceleration.
#define OPTIMIZED_FOR
Definition macros.h:127
#define to_fourcc(a, b, c, d)
Creates FourCC word.
Definition macros.h:114
const char * name
Definition settings.cpp:193
const char * primary_name
unsigned interframe
Indicates if compression is interframe.
const char * name
displayed name
int subsampling
Decimal representation of subsampling in format 'JabA', eg. 4440 (last number is alpha),...
const char * name_long
more descriptive name
int h_align
Number of pixels each line is aligned to.
unsigned const_size
Indicates if data length is constant for all resolutions (hw surfaces)
unsigned rgb
Whether pixelformat is RGB.
int block_size_pixels
Bytes per pixel block (packed pixelformats only, otherwise set to 1)
int bits_per_channel
Number of bits per color channel.
const char * file_extension
Extension that should be added to name if frame is saved to file.
uint32_t fcc
FourCC.
unsigned opaque
If codec is opaque (= compressed)
int block_size_bytes
Bytes per pixel block (packed pixelformats only, otherwise set to 1)
int depth
bit depth; 0 means that whole struct is undefined
Definition types.h:140
bool rgb
Definition types.h:142
int subsampling
in 'JabA' format, eg. '4444'
Definition types.h:141
for planar pixel formats
int plane_info[8]
[1st comp H subsamp, 1st comp V subs., 2nd comp H....]
depth
Definition types.h:125
@ DEPTH16
Definition types.h:129
subsampling
Definition types.h:132
codec_t
Definition types.h:65
@ YUYV
YCbCr 422 8-bit - Y0 Cb Y1 Cr.
Definition types.h:72
@ VP8
VP8 frame.
Definition types.h:86
@ DXT1
S3 Texture Compression DXT1.
Definition types.h:77
@ PRORES_422_LT
Apple ProRes 422 (LT)
Definition types.h:106
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
Definition types.h:73
@ RGB
RGB 8-bit (packed into 24-bit word)
Definition types.h:80
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ PRORES
abstract Apple ProRes, must not be used in transmit
Definition types.h:100
@ PRORES_422_PROXY
Apple ProRes 422 (Proxy)
Definition types.h:105
@ BGR
8-bit BGR
Definition types.h:88
@ HW_VDPAU
VDPAU hardware surface.
Definition types.h:91
@ VIDEO_CODEC_FIRST
Definition types.h:68
@ RG48
16-bit RGB little-endian (RlRhGl...)
Definition types.h:95
@ AV1
AOMedia Video 1.
Definition types.h:96
@ Y416
interleaved little-endian YCbCr 4444 16-bit - UYVA
Definition types.h:99
@ J2KR
JPEG 2000 RGB.
Definition types.h:90
@ CFHD
Cineform.
Definition types.h:94
@ VIDEO_CODEC_END
Definition types.h:111
@ J2K
JPEG 2000.
Definition types.h:89
@ PRORES_422_HQ
Apple ProRes 422 (HQ)
Definition types.h:103
@ Y216
YCbCr 422 16-bit little-endian - Y0 Cb Y1 Cr.
Definition types.h:98
@ PRORES_4444
Apple ProRes 4444.
Definition types.h:101
@ JPEG
JPEG image, restart intervals may be used. Compatible with GPUJPEG.
Definition types.h:81
@ HFYU
HuffYUV.
Definition types.h:92
@ MJPG
JPEG image, without restart intervals.
Definition types.h:85
@ R12L
RGB 12-bit packed, little-endian.
Definition types.h:74
@ FFV1
FFV1.
Definition types.h:93
@ PRORES_422
Apple ProRes 422.
Definition types.h:104
@ DRM_PRIME
DRM Prime buffer, data contains struct drm_prime_frame.
Definition types.h:107
@ RAW
RAW HD-SDI frame.
Definition types.h:82
@ H264
H.264 frame.
Definition types.h:83
@ DVS10
DVS 10-bit format.
Definition types.h:76
@ VP9
VP9 frame.
Definition types.h:87
@ H265
H.264 frame.
Definition types.h:84
@ DXT5
S3 Texture Compression DXT5.
Definition types.h:79
@ I420
planar YCbCr 4:2:0
Definition types.h:97
@ PRORES_4444_XQ
Apple ProRes 4444 (XQ)
Definition types.h:102
@ DXT1_YUV
Structure same as DXT1, instead of RGB, YCbCr values are stored.
Definition types.h:78
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
Definition types.h:75
void vc_deinterlace(unsigned char *src, long src_linesize, int lines)
Deinterlaces framebuffer.
void i420_8_to_uyvy(int width, int height, const unsigned char *in, unsigned char *out)
bool codec_is_hw_accelerated(codec_t codec)
static const struct alternative_fourcc fourcc_aliases[]
bool codec_is_in_set(codec_t codec, const codec_t *set)
const char * get_pixdesc_desc(struct pixfmt_desc desc)
void codec_get_planes_subsampling(codec_t pix_fmt, int *sub)
#define HW_VDPAU_FRAME_SZ
void y416_to_i444(int width, int height, const unsigned char *in, unsigned char *out, int depth)
struct pixfmt_desc get_pixfmt_desc(codec_t pixfmt)
bool is_codec_opaque(codec_t codec)
static codec_t get_codec_from_name_wo_alias(const char *name)
bool vc_deinterlace_ex(codec_t codec, unsigned char *src, size_t src_linesize, unsigned char *dst, size_t dst_pitch, size_t lines)
void uyvy_to_i422(int width, int height, const unsigned char *in, unsigned char *out)
bool codec_is_a_rgb(codec_t codec)
Returns TRUE if specified pixelformat is some form of RGB (not YUV).
void i444_8_to_uyvy(int width, int height, const unsigned char *in, unsigned char *out)
int vc_get_size(unsigned int width, codec_t codec)
void i422_16_to_y416(int width, int height, const unsigned char *in, unsigned char *out, int in_depth)
int vc_get_linesize(unsigned int width, codec_t codec)
bool pixdesc_equals(struct pixfmt_desc desc_a, struct pixfmt_desc desc_b)
void watch_pixfmt_degrade(const char *mod_name, struct pixfmt_desc desc_src, struct pixfmt_desc desc_dst)
bool codec_is_const_size(codec_t codec)
Returns TRUE if specified pixelformat has constant size regardles of resolution. If so the block_size...
void i420_16_to_y416(int width, int height, const unsigned char *in, unsigned char *out, int in_depth)
bool is_codec_interframe(codec_t codec)
int get_pf_block_bytes(codec_t codec)
returns codec_info_t::block_size_bytes
double get_bpp(codec_t codec)
const char * get_codec_file_extension(codec_t codec)
void show_codec_help(const char *module, const codec_t *codecs8, const codec_t *codecs10, const codec_t *codecs_ge12)
Prints list of suppored codecs for video module.
uint32_t get_fourcc(codec_t codec)
char pixfmt_conv_pref[]
bitdepth, subsampling, color space
Definition video_codec.c:80
const char * get_codec_name(codec_t codec)
int get_subsampling(codec_t codec)
int get_pf_block_pixels(codec_t codec)
returns codec_info_t::block_size_pixels
void i422_8_to_uyvy(int width, int height, const unsigned char *in, unsigned char *out)
bool codec_is_planar(codec_t codec)
const char * get_codec_name_long(codec_t codec)
bool clear_video_buffer(unsigned char *data, size_t linesize, size_t pitch, size_t height, codec_t color_spec)
static const struct alternative_codec_name codec_name_aliases[]
int compare_pixdesc(const struct pixfmt_desc *desc_a, const struct pixfmt_desc *desc_b, const struct pixfmt_desc *src_desc)
size_t vc_get_datalen(unsigned int width, unsigned int height, codec_t codec)
codec_t get_codec_from_name(const char *name)
int get_bits_per_component(codec_t codec)
static const struct pixfmt_plane_info_t pixfmt_plane_info[]
static const struct codec_info_t codec_info[]
codec_t get_codec_from_fcc(uint32_t fourcc)
codec_t get_codec_from_file_extension(const char *ext)
void i444_16_to_y416(int width, int height, const unsigned char *in, unsigned char *out, int in_depth)
bool codec_is_420(codec_t pix_fmt)