Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions video/scaler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ void VideoScaler::set_ycbcr_chroma_midpoint(float midpoint)
ycbcr_chroma_midpoint = midpoint;
}

void VideoScaler::set_ycbcr_range(VkSamplerYcbcrRange range, unsigned bit_depth)
{
ycbcr_range = range;
ycbcr_range_bit_depth = bit_depth;
}

void VideoScaler::rescale(CommandBuffer &cmd, const RescaleInfo &info)
{
if (!recognized_color_space(info.input_color_space) || !recognized_color_space(info.output_color_space))
Expand Down Expand Up @@ -349,20 +355,35 @@ void VideoScaler::rescale(CommandBuffer &cmd, const RescaleInfo &info)
};
auto *ubo = cmd.allocate_typed_constant_data<UBO>(0, 4, 1);

vec3 cr_row, y_row, cb_row;
if (info.output_color_space == VK_COLOR_SPACE_HDR10_ST2084_EXT)
{
ubo->gamma_space_transform[0] = vec4(0.5f, -0.459786f, -0.0402143f, ycbcr_chroma_midpoint);
ubo->gamma_space_transform[1] = vec4(0.2627f, 0.678f, 0.0593f, 0.0f);
ubo->gamma_space_transform[2] = vec4(-0.13963f, -0.36037f, 0.5f, ycbcr_chroma_midpoint);
cr_row = vec3(0.5f, -0.459786f, -0.0402143f);
y_row = vec3(0.2627f, 0.678f, 0.0593f);
cb_row = vec3(-0.13963f, -0.36037f, 0.5f);
}
else
{
// Everything else is standard BT.709.
ubo->gamma_space_transform[0] = vec4(0.5f, -0.454153f, -0.0458471f, ycbcr_chroma_midpoint);
ubo->gamma_space_transform[1] = vec4(0.2126f, 0.7152f, 0.0722f, 0.0f);
ubo->gamma_space_transform[2] = vec4(-0.114572f, -0.385428f, 0.5f, ycbcr_chroma_midpoint);
cr_row = vec3(0.5f, -0.454153f, -0.0458471f);
y_row = vec3(0.2126f, 0.7152f, 0.0722f);
cb_row = vec3(-0.114572f, -0.385428f, 0.5f);
}

float luma_scale = 1.0f, luma_offset = 0.0f, chroma_scale = 1.0f;
if (ycbcr_range == VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
{
// H.273 narrow range: 16..235 luma and 16..240 chroma at 8 bits, scaled up for higher bit depths.
float code_unit = float(1u << (ycbcr_range_bit_depth - 8u)) / float((1u << ycbcr_range_bit_depth) - 1u);
luma_scale = 219.0f * code_unit;
luma_offset = 16.0f * code_unit;
chroma_scale = 224.0f * code_unit;
}

ubo->gamma_space_transform[0] = vec4(cr_row * chroma_scale, ycbcr_chroma_midpoint);
ubo->gamma_space_transform[1] = vec4(y_row * luma_scale, luma_offset);
ubo->gamma_space_transform[2] = vec4(cb_row * chroma_scale, ycbcr_chroma_midpoint);

const Primaries bt709 = {
{ 0.640f, 0.330f },
{ 0.300f, 0.600f },
Expand Down
5 changes: 5 additions & 0 deletions video/scaler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class VideoScaler
};

void set_ycbcr_chroma_midpoint(float midpoint);
// Narrow range follows H.273 at the given bit depth (8 to 16), expressed as normalized UNORM values.
// Full range (the default) ignores bit_depth.
void set_ycbcr_range(VkSamplerYcbcrRange range, unsigned bit_depth);
void rescale(Vulkan::CommandBuffer &cmd, const RescaleInfo &info);

private:
Expand All @@ -58,6 +61,8 @@ class VideoScaler
uint32_t last_input_width = 0, last_input_height = 0;
uint32_t last_output_width = 0, last_output_height = 0;
float ycbcr_chroma_midpoint = 0.5f;
VkSamplerYcbcrRange ycbcr_range = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
unsigned ycbcr_range_bit_depth = 8;

void update_weights(Vulkan::CommandBuffer &cmd, const RescaleInfo &info);
};
Expand Down
Loading