From: Steinar H. Gunderson Date: Mon, 15 Oct 2012 18:04:42 +0000 (+0200) Subject: Add a unit test for 4:2:0 YCbCr input. X-Git-Tag: 1.0~231 X-Git-Url: https://git.sesse.net/?p=movit;a=commitdiff_plain;h=6f0ec2d7c127b139ed7cc42348bf518236e12dbd Add a unit test for 4:2:0 YCbCr input. --- diff --git a/ycbcr_input_test.cpp b/ycbcr_input_test.cpp index 53b8289..70cbc12 100644 --- a/ycbcr_input_test.cpp +++ b/ycbcr_input_test.cpp @@ -107,3 +107,121 @@ TEST(YCbCrInput, FullRangeRec601) { // so we need some leeway. expect_equal(expected_data, out_data, 4 * width, height, 0.025, 0.002); } + +TEST(YCbCrInput, Subsampling420) { + const int width = 4; + const int height = 4; + + unsigned char y[width * height] = { + 126, 126, 126, 126, + 126, 126, 126, 126, + 126, 126, 126, 126, + 126, 126, 126, 126, + }; + unsigned char cb[(width/2) * (height/2)] = { + 64, 128, + 128, 192, + }; + unsigned char cr[(width/2) * (height/2)] = { + 128, 128, + 128, 128, + }; + + // Note: This is only the blue channel. The chroma samples (with associated + // values for blue) are marked off in comments. + float expected_data[width * height] = { + 0.000, 0.125, 0.375, 0.500, + /* 0.0 */ /* 0.5 */ + 0.125, 0.250, 0.500, 0.625, + + 0.375, 0.500, 0.750, 0.875, + /* 0.5 */ /* 1.0 */ + 0.500, 0.625, 0.875, 1.000, + }; + float out_data[width * height]; + + EffectChainTester tester(NULL, width, height); + + ImageFormat format; + format.color_space = COLORSPACE_sRGB; + format.gamma_curve = GAMMA_sRGB; + + YCbCrFormat ycbcr_format; + ycbcr_format.luma_coefficients = YCBCR_REC_601; + ycbcr_format.full_range = false; + ycbcr_format.chroma_subsampling_x = 2; + ycbcr_format.chroma_subsampling_y = 2; + ycbcr_format.chroma_x_position = 0.5f; + ycbcr_format.chroma_y_position = 0.5f; + + YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height); + input->set_pixel_data(0, y); + input->set_pixel_data(1, cb); + input->set_pixel_data(2, cr); + tester.get_chain()->add_input(input); + + tester.run(out_data, GL_BLUE, COLORSPACE_sRGB, GAMMA_sRGB); + + // Y'CbCr isn't 100% accurate (the input values are rounded), + // so we need some leeway. + expect_equal(expected_data, out_data, width, height, 0.01, 0.001); +} + +TEST(YCbCrInput, Subsampling420WithNonCenteredSamples) { + const int width = 4; + const int height = 4; + + unsigned char y[width * height] = { + 126, 126, 126, 126, + 126, 126, 126, 126, + 126, 126, 126, 126, + 126, 126, 126, 126, + }; + unsigned char cb[(width/2) * (height/2)] = { + 64, 128, + 128, 192, + }; + unsigned char cr[(width/2) * (height/2)] = { + 128, 128, + 128, 128, + }; + + // Note: This is only the blue channel. The chroma samples (with associated + // values for blue) are marked off in comments. + float expected_data[width * height] = { + 0.000, 0.250, 0.500, 0.500, + /* 0.0 */ /* 0.5 */ + 0.125, 0.375, 0.625, 0.625, + + 0.375, 0.625, 0.875, 0.875, + /* 0.5 */ /* 1.0 */ + 0.500, 0.750, 1.000, 1.000, + }; + float out_data[width * height]; + + EffectChainTester tester(NULL, width, height); + + ImageFormat format; + format.color_space = COLORSPACE_sRGB; + format.gamma_curve = GAMMA_sRGB; + + YCbCrFormat ycbcr_format; + ycbcr_format.luma_coefficients = YCBCR_REC_601; + ycbcr_format.full_range = false; + ycbcr_format.chroma_subsampling_x = 2; + ycbcr_format.chroma_subsampling_y = 2; + ycbcr_format.chroma_x_position = 0.0f; + ycbcr_format.chroma_y_position = 0.5f; + + YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height); + input->set_pixel_data(0, y); + input->set_pixel_data(1, cb); + input->set_pixel_data(2, cr); + tester.get_chain()->add_input(input); + + tester.run(out_data, GL_BLUE, COLORSPACE_sRGB, GAMMA_sRGB); + + // Y'CbCr isn't 100% accurate (the input values are rounded), + // so we need some leeway. + expect_equal(expected_data, out_data, width, height, 0.01, 0.001); +}