X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=ycbcr_422interleaved_input_test.cpp;h=0d2c3fcba4189d52b3fb9a83352fdb6032740098;hp=d47bb905cb43e466350204cf69d775172134bb74;hb=8cd14c3d54e817f9ad83966409dd672bcbfb7555;hpb=ba60914d4e5eda7b28af700bf43e9699b7aa720d diff --git a/ycbcr_422interleaved_input_test.cpp b/ycbcr_422interleaved_input_test.cpp index d47bb90..0d2c3fc 100644 --- a/ycbcr_422interleaved_input_test.cpp +++ b/ycbcr_422interleaved_input_test.cpp @@ -3,12 +3,17 @@ #include #include +#include + #include "effect_chain.h" #include "gtest/gtest.h" #include "test_util.h" #include "util.h" +#include "resize_effect.h" #include "ycbcr_422interleaved_input.h" +using namespace std; + namespace movit { // Adapted from the Simple444 test from YCbCrInputTest. @@ -35,7 +40,7 @@ TEST(YCbCr422InterleavedInputTest, Simple422) { }; float out_data[4 * width * height]; - EffectChainTester tester(NULL, width, height); + EffectChainTester tester(nullptr, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; @@ -44,6 +49,7 @@ TEST(YCbCr422InterleavedInputTest, Simple422) { YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_601; ycbcr_format.full_range = false; + ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 2; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.0f; // Doesn't really matter here, since Y is constant. @@ -57,9 +63,81 @@ TEST(YCbCr422InterleavedInputTest, Simple422) { tester.run(out_data, GL_RGBA, 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, 4 * width, height, 0.025, 0.002); + // Y'CbCr isn't 100% accurate (the input values are rounded), + // so we need some leeway. + expect_equal(expected_data, out_data, 4 * width, height, 0.025, 0.002); +} + +// An effect that does nothing except changing its output sizes. +class VirtualResizeEffect : public Effect { +public: + VirtualResizeEffect(int width, int height, int virtual_width, int virtual_height) + : width(width), + height(height), + virtual_width(virtual_width), + virtual_height(virtual_height) {} + string effect_type_id() const override { return "VirtualResizeEffect"; } + string output_fragment_shader() override { return read_file("identity.frag"); } + + bool changes_output_size() const override { return true; } + + void get_output_size(unsigned *width, unsigned *height, + unsigned *virtual_width, unsigned *virtual_height) const override { + *width = this->width; + *height = this->height; + *virtual_width = this->virtual_width; + *virtual_height = this->virtual_height; + } + +private: + int width, height, virtual_width, virtual_height; +}; + +TEST(YCbCr422InterleavedInputTest, LumaLinearInterpolation) { + const int width = 4; + const int height = 1; + const int out_width = width * 3; + + // Black, white, black and then gray. + unsigned char uyvy[width * height * 2] = { + /*U=*/128, /*Y=*/ 16, + /*V=*/128, /*Y=*/235, + /*U=*/128, /*Y=*/ 16, + /*V=*/128, /*Y=*/128, + }; + + float expected_data[out_width * height] = { + 0.0, /**/0.0, 0.333, 0.667, /**/1.0, 0.667, 0.333, /**/0.0, 0.167, 0.333, /**/0.5, 0.5 + }; + float out_data[out_width * height]; + + EffectChainTester tester(nullptr, out_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.num_levels = 256; + ycbcr_format.chroma_subsampling_x = 2; + ycbcr_format.chroma_subsampling_y = 1; + ycbcr_format.cb_x_position = 0.0f; // Doesn't really matter here, since U/V are constant. + ycbcr_format.cb_y_position = 0.5f; + ycbcr_format.cr_x_position = 0.0f; + ycbcr_format.cr_y_position = 0.5f; + + YCbCr422InterleavedInput *input = new YCbCr422InterleavedInput(format, ycbcr_format, width, height); + input->set_pixel_data(uyvy); + tester.get_chain()->add_input(input); + tester.get_chain()->add_effect(new VirtualResizeEffect(out_width, height, out_width, height)); + + tester.run(out_data, GL_RED, 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, out_width, height, 0.025, 0.002); } // Adapted from the YCbCrInput test of the same name. @@ -90,7 +168,7 @@ TEST(YCbCr422InterleavedInputTest, DifferentCbAndCrPositioning) { }; float out_data[width * height]; - EffectChainTester tester(NULL, width, height); + EffectChainTester tester(nullptr, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; @@ -99,6 +177,7 @@ TEST(YCbCr422InterleavedInputTest, DifferentCbAndCrPositioning) { YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_601; ycbcr_format.full_range = false; + ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 2; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.0f; @@ -148,7 +227,7 @@ TEST(YCbCr422InterleavedInputTest, PBO) { glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 2, uyvy, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - EffectChainTester tester(NULL, width, height); + EffectChainTester tester(nullptr, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; @@ -157,6 +236,7 @@ TEST(YCbCr422InterleavedInputTest, PBO) { YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_601; ycbcr_format.full_range = false; + ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 2; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.0f; // Doesn't really matter here, since Y is constant.