video pattern generator: add full-depth Y216/Y416

This commit is contained in:
Martin Pulec
2022-05-25 13:29:09 +02:00
parent 0d7ab91bd9
commit 5b0c8ca268
3 changed files with 61 additions and 3 deletions

View File

@@ -61,6 +61,7 @@
#include <array>
#include <iostream>
#include <random>
#include <set>
#include <utility>
#include <vector>
@@ -86,6 +87,7 @@ using std::make_unique;
using std::max;
using std::min;
using std::move;
using std::set;
using std::string;
using std::swap;
using std::unique_ptr;
@@ -97,6 +99,8 @@ enum class generator_depth {
bits16
};
static const set<codec_t> native_16b{ RG48, R12L, R10k, v210, Y416, Y216 };
class image_pattern {
public:
static unique_ptr<image_pattern> create(string const & config);
@@ -334,7 +338,11 @@ class image_pattern_raw : public image_pattern {
unique_ptr<image_pattern> image_pattern::create(string const &config) {
if (config == "help") {
cout << "Pattern to use, one of: " << BOLD("bars, blank, ebu_bars, gradient[=0x<AABBGGRR>], gradient2, noise, raw=0xXX[YYZZ..], smpte_bars, 0x<AABBGGRR>\n");
cout << "\t\t- patterns 'gradient2' and 'noise' generate full bit-depth patterns with " << BOLD("RG48") << ", " << BOLD("R12L") << ", " << BOLD("R10k") << " and " << BOLD("v210") << "\n";
cout << "\t\t- patterns 'gradient2' and 'noise' generate full bit-depth patterns with";
for (auto & c : native_16b) {
cout << " " << BOLD(get_codec_name(c));
}
cout << "\n";
cout << "\t\t- pattern 'raw' generates repeating sequence of given bytes without any color conversion\n";
cout << "\t\t- pattern 'smpte' uses the top bars from top 2 thirds only (doesn't render bottom third differently)\n";
return {};
@@ -411,7 +419,7 @@ video_pattern_generate(std::string const & config, int width, int height, codec_
auto data = generator->init(width, height, generator_depth::bits8);
codec_t codec_src = RGBA;
if (color_spec == RG48 || color_spec == R12L || color_spec == R10k || color_spec == v210) {
if (native_16b.find(color_spec) != native_16b.end()) {
data = generator->init(width, height, generator_depth::bits16);
codec_src = RG48;
}

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 || out_c == Y416) {
if (out_c == I420 || out_c == YUYV) {
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

@@ -2314,6 +2314,54 @@ static void vc_copylineRG48toV210(unsigned char * __restrict dst, const unsigned
#undef FETCH_BLOCK
}
static void vc_copylineRG48toY216(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 % 2 == 0);
const uint16_t *in = (const void *) src;
uint16_t *d = (void *) dst;
OPTIMIZED_FOR (int x = 0; x < dst_len; x += 8) {
comp_type_t r, g, b;
comp_type_t u, v;
r = *in++;
g = *in++;
b = *in++;
*d++ = CLAMP_LIMITED_Y((RGB_TO_Y_709_SCALED(r, g, b) >> COMP_BASE) + (1<<12), 16); // Y
u = (RGB_TO_CB_709_SCALED(r, g, b) >> COMP_BASE);
v = (RGB_TO_CR_709_SCALED(r, g, b) >> COMP_BASE);
r = *in++;
g = *in++;
b = *in++;
*d++ = CLAMP_LIMITED_CBCR((u + (RGB_TO_CB_709_SCALED(r, g, b) >> COMP_BASE) / 2) + (1<<15), 16); // U
*d++ = CLAMP_LIMITED_Y((RGB_TO_Y_709_SCALED(r, g, b) >> COMP_BASE) + (1<<12), 16); // Y
*d++ = CLAMP_LIMITED_CBCR((v + (RGB_TO_CR_709_SCALED(r, g, b) >> COMP_BASE) / 2) + (1<<15), 16); // V
}
}
static void vc_copylineRG48toY416(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 % 2 == 0);
const uint16_t *in = (const void *) src;
uint16_t *d = (void *) dst;
OPTIMIZED_FOR (int x = 0; x < dst_len; x += 8) {
comp_type_t r, g, b;
r = *in++;
g = *in++;
b = *in++;
*d++ = CLAMP_LIMITED_CBCR((RGB_TO_CB_709_SCALED(r, g, b) >> COMP_BASE) + (1<<15), 16);
*d++ = CLAMP_LIMITED_Y((RGB_TO_Y_709_SCALED(r, g, b) >> COMP_BASE) + (1<<12), 16);
*d++ = CLAMP_LIMITED_CBCR((RGB_TO_CR_709_SCALED(r, g, b) >> COMP_BASE) + (1<<15), 16);
*d++ = 0xFFFFU;
}
}
/**
* Converts BGR to RGB.
* @copydetails vc_copylinev210
@@ -2658,6 +2706,8 @@ static const struct decoder_item decoders[] = {
{ (decoder_t) vc_copylineRG48toRGB, RG48, RGB, false },
{ (decoder_t) vc_copylineRG48toUYVY, RG48, UYVY, true },
{ (decoder_t) vc_copylineRG48toV210, RG48, v210, true },
{ (decoder_t) vc_copylineRG48toY216, RG48, Y216, true },
{ (decoder_t) vc_copylineRG48toY416, RG48, Y416, true },
{ vc_copylineRGBA, RGBA, RGBA, false },
{ (decoder_t) vc_copylineDVS10toV210, DVS10, v210, false },
{ (decoder_t) vc_copylineRGBAtoRGB, RGBA, RGB, false },