added Y416 + basic conversions & testcard

This commit is contained in:
Martin Pulec
2022-05-19 15:44:19 +02:00
parent 0d2a354d50
commit df5901a286
5 changed files with 94 additions and 3 deletions

View File

@@ -95,6 +95,7 @@ typedef enum {
AV1, ///< AOMedia Video 1
I420, ///< planar YCbCr 4:2:0
Y216, ///< YCbCr 422 16-bit - Y0 Cb Y1 Cr
Y416, ///< interleaved little-endian YCbCr 4444 16-bit - UYVA
PRORES, ///< abstract Apple ProRes, must not be used in transmit
PRORES_4444, ///< Apple ProRes 4444
PRORES_4444_XQ, ///< Apple ProRes 4444 (XQ)

View File

@@ -302,7 +302,7 @@ static int configure_tiling(struct testcard_state *s, const char *fmt)
static const codec_t codecs_8b[] = {I420, RGBA, RGB, UYVY, YUYV, VIDEO_CODEC_NONE};
static const codec_t codecs_10b[] = {R10k, v210, VIDEO_CODEC_NONE};
static const codec_t codecs_ge12b[] = {Y216, RG48, R12L, VIDEO_CODEC_NONE};
static const codec_t codecs_ge12b[] = {Y216, Y416, RG48, R12L, VIDEO_CODEC_NONE};
static bool parse_fps(const char *fps, struct video_desc *desc) {
char *endptr = nullptr;

View File

@@ -113,7 +113,7 @@ static void toI420(unsigned char *out, const unsigned char *input, int width, in
void testcard_convert_buffer(codec_t in_c, codec_t out_c, unsigned char *out, unsigned const char *in, int width, int height)
{
unsigned char *tmp_buffer = NULL;
if (out_c == I420 || out_c == YUYV || out_c == Y216) {
if (out_c == I420 || out_c == YUYV || out_c == Y216 || out_c == Y416) {
decoder_t decoder = get_decoder_from_to(in_c, UYVY, true);
tmp_buffer = malloc(2L * ((width + 1U) ^ 1U) * height);
long in_linesize = vc_get_linesize(width, in_c);

View File

@@ -195,6 +195,8 @@ static const struct codec_info_t codec_info[] = {
to_fourcc('I','4','2','0'), 2, 3.0/2.0, 8, 1, FALSE, FALSE, FALSE, FALSE, 4200, "yuv"},
[Y216] = {"Y216", "Packed 16-bit YUV 4:2:2 little-endian",
to_fourcc('Y','2','1','6'), 2, 4.0, 16, 8, FALSE, FALSE, FALSE, FALSE, 4220, "y216"},
[Y416] = {"Y416", "Packed 16-bit YUV 4:4:4:4 little-endian",
to_fourcc('Y','4','1','6'), 1, 8.0, 16, 8, FALSE, FALSE, FALSE, FALSE, 4444, "y416"},
[PRORES] = {"PRORES", "Apple ProRes",
0, 0, 1.0, 8, 1, FALSE, TRUE, TRUE, FALSE, 0, "pror"},
[PRORES_4444] = {"PRORES_4444", "Apple ProRes 4444",
@@ -2495,6 +2497,44 @@ static void vc_copylineUYVYtoY216(unsigned char * __restrict dst, const unsigned
}
}
static void vc_copylineUYVYtoY416(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
int gshift, int bshift)
{
UNUSED(rshift);
UNUSED(gshift);
UNUSED(bshift);
while (dst_len >= 12) {
*dst++ = 0;
*dst++ = src[0]; // U
*dst++ = 0;
*dst++ = src[1]; // Y0
*dst++ = 0;
*dst++ = src[2]; // V
*dst++ = 0;
*dst++ = 0; // A
*dst++ = 0;
*dst++ = src[0]; // U
*dst++ = 0;
*dst++ = src[3]; // Y1
*dst++ = 0;
*dst++ = src[2]; // V
*dst++ = 0;
*dst++ = 0; // A
src += 4;
dst_len -= 16;
}
if (dst_len >= 8) {
*dst++ = 0;
*dst++ = src[0]; // U
*dst++ = 0;
*dst++ = src[1]; // Y0
*dst++ = 0;
*dst++ = src[2]; // V
*dst++ = 0;
*dst++ = 0; // A
}
}
static void vc_copylineY216toUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
int gshift, int bshift)
{
@@ -2511,6 +2551,22 @@ static void vc_copylineY216toUYVY(unsigned char * __restrict dst, const unsigned
}
}
static void vc_copylineY416toUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
int gshift, int bshift)
{
UNUSED(rshift);
UNUSED(gshift);
UNUSED(bshift);
while (dst_len >= 4) {
*dst++ = (src[1] + src[9]) / 2; // U
*dst++ = src[3]; // Y0
*dst++ = (src[5] + src[13]) / 2; // V
*dst++ = src[11]; // Y1
src += 16;
dst_len -= 4;
}
}
static void vc_copylineY216toV210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
int gshift, int bshift)
{
@@ -2542,6 +2598,37 @@ static void vc_copylineY216toV210(unsigned char * __restrict dst, const unsigned
}
}
static void vc_copylineY416toV210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
int gshift, int bshift)
{
UNUSED(rshift);
UNUSED(gshift);
UNUSED(bshift);
assert((uintptr_t) src % 2 == 0);
assert((uintptr_t) dst % 4 == 0);
OPTIMIZED_FOR (int x = 0; x < dst_len / 16; ++x) {
const uint16_t *s = (const uint16_t *)(const void *) (src + x * 48);
uint32_t *d = (uint32_t *)(void *) (dst + x * 16);
uint16_t y1, u, y2, v;
u = (s[0] + s[4]) / 2;
y1 = s[1];
v = (s[2] + s[6]) / 2;
y2 = s[5];
d[0] = u >> 6U | y1 >> 6U << 10U | v >> 6U << 20U;
y1 = s[9];
u = (s[8] + s[12]) / 2;
d[1] = y2 >> 6U | u >> 6U << 10U | y1 >> 6U << 20U;
y2 = s[13];
v = (s[10] + s[14]) / 2;
y1 = s[17];
u = (s[16] + s[20]) / 2;
d[2] = v >> 6U | y2 >> 6U << 10U | u >> 6U << 20U;
y2 = s[21];
v = (s[18] + s[22]) / 2;
d[3] = y1 >> 6U | v >> 6U << 10U | y2 >> 6U << 20U;
}
}
struct decoder_item {
decoder_t decoder;
codec_t in;
@@ -2583,8 +2670,11 @@ static const struct decoder_item decoders[] = {
{ vc_copylineRGBAtoR10k, RGBA, R10k, false },
{ vc_copylineUYVYtoV210, UYVY, v210, false },
{ vc_copylineUYVYtoY216, UYVY, Y216, false },
{ vc_copylineUYVYtoY416, UYVY, Y416, false },
{ vc_copylineY216toUYVY, Y216, UYVY, false },
{ vc_copylineY216toV210, Y216, v210, false },
{ vc_copylineY416toUYVY, Y416, UYVY, false },
{ vc_copylineY416toV210, Y416, v210, false },
};
/**

View File

@@ -57,7 +57,7 @@ extern "C" {
#define DEFAULT_G_SHIFT 8
#define DEFAULT_B_SHIFT 16
#define DEFAULT_RGB_SHIFT_INIT { DEFAULT_R_SHIFT, DEFAULT_G_SHIFT, DEFAULT_B_SHIFT }
#define MAX_BPS 6 /* for RG48 */ ///< maximal (average) number of pixels per know pixel formats (up-round if needed)
#define MAX_BPS 8 /* for Y416 */ ///< maximal (average) number of pixels per know pixel formats (up-round if needed)
#define MAX_PADDING 36 /* R12L */ ///< maximal padding that may be needed to align to pixfmt block size
/**