X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=ycbcr_conversion_effect.cpp;h=64d23cd3d675ab26758bce38f804ce775d44cada;hp=8d11acfd4abc08f214c5a1e93f90f02887169d69;hb=90ac46cdc5845432df13385f946c63b5496c685e;hpb=e8499e3e9892a74c7882af4be14ccdc1e3d92c2b diff --git a/ycbcr_conversion_effect.cpp b/ycbcr_conversion_effect.cpp index 8d11acf..64d23cd 100644 --- a/ycbcr_conversion_effect.cpp +++ b/ycbcr_conversion_effect.cpp @@ -15,8 +15,8 @@ using namespace Eigen; namespace movit { -YCbCrConversionEffect::YCbCrConversionEffect(const YCbCrFormat &ycbcr_format) - : ycbcr_format(ycbcr_format) +YCbCrConversionEffect::YCbCrConversionEffect(const YCbCrFormat &ycbcr_format, GLenum type) + : ycbcr_format(ycbcr_format), type(type) { register_uniform_mat3("ycbcr_matrix", &uniform_ycbcr_matrix); register_uniform_vec3("offset", uniform_offset); @@ -37,7 +37,8 @@ void YCbCrConversionEffect::set_gl_state(GLuint glsl_program_num, const string & Effect::set_gl_state(glsl_program_num, prefix, sampler_num); Matrix3d ycbcr_to_rgb; - compute_ycbcr_matrix(ycbcr_format, uniform_offset, &ycbcr_to_rgb); + double scale_factor; + compute_ycbcr_matrix(ycbcr_format, uniform_offset, &ycbcr_to_rgb, type, &scale_factor); uniform_ycbcr_matrix = ycbcr_to_rgb.inverse(); @@ -47,14 +48,36 @@ void YCbCrConversionEffect::set_gl_state(GLuint glsl_program_num, const string & } else { uniform_clamp_range = true; - // These limits come from BT.601 page 8, or BT.701, page 5. - // TODO: Use num_levels. Currently we support 8-bit levels only. - uniform_ycbcr_min[0] = 16.0 / 255.0; - uniform_ycbcr_min[1] = 16.0 / 255.0; - uniform_ycbcr_min[2] = 16.0 / 255.0; - uniform_ycbcr_max[0] = 235.0 / 255.0; - uniform_ycbcr_max[1] = 240.0 / 255.0; - uniform_ycbcr_max[2] = 240.0 / 255.0; + if (ycbcr_format.num_levels == 0 || ycbcr_format.num_levels == 256) { // 8-bit. + // These limits come from BT.601 page 8, or BT.709, page 5. + uniform_ycbcr_min[0] = 16.0 / 255.0; + uniform_ycbcr_min[1] = 16.0 / 255.0; + uniform_ycbcr_min[2] = 16.0 / 255.0; + uniform_ycbcr_max[0] = 235.0 / 255.0; + uniform_ycbcr_max[1] = 240.0 / 255.0; + uniform_ycbcr_max[2] = 240.0 / 255.0; + } else if (ycbcr_format.num_levels == 1024) { // 10-bit. + // BT.709, page 5, or BT.2020, page 6. + uniform_ycbcr_min[0] = 64.0 / 1023.0; + uniform_ycbcr_min[1] = 64.0 / 1023.0; + uniform_ycbcr_min[2] = 64.0 / 1023.0; + uniform_ycbcr_max[0] = 940.0 / 1023.0; + uniform_ycbcr_max[1] = 960.0 / 1023.0; + uniform_ycbcr_max[2] = 960.0 / 1023.0; + } else if (ycbcr_format.num_levels == 4096) { // 12-bit. + // BT.2020, page 6. + uniform_ycbcr_min[0] = 256.0 / 4095.0; + uniform_ycbcr_min[1] = 256.0 / 4095.0; + uniform_ycbcr_min[2] = 256.0 / 4095.0; + uniform_ycbcr_max[0] = 3760.0 / 4095.0; + uniform_ycbcr_max[1] = 3840.0 / 4095.0; + uniform_ycbcr_max[2] = 3840.0 / 4095.0; + } else { + assert(false); + } + uniform_ycbcr_min[0] /= scale_factor; + uniform_ycbcr_min[1] /= scale_factor; + uniform_ycbcr_min[2] /= scale_factor; } }