From: Steinar H. Gunderson Date: Tue, 29 Jan 2013 19:11:23 +0000 (+0100) Subject: If all inputs to an effect have the same input size, use that instead of fitting... X-Git-Tag: 1.0~146 X-Git-Url: https://git.sesse.net/?p=movit;a=commitdiff_plain;h=c59abdb997a1d1d703ac5dd71513dea03628a53e;ds=sidebyside If all inputs to an effect have the same input size, use that instead of fitting to the aspect. The common case here is one-input effects on overlays. Reported by Christophe Thommeret. --- diff --git a/effect_chain.cpp b/effect_chain.cpp index f6266d7..9aaa748 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -666,10 +666,49 @@ void EffectChain::find_output_size(Phase *phase) return; } + // If all effects have the same size, use that. unsigned output_width = 0, output_height = 0; + bool all_inputs_same_size = true; - // If not, look at the input phases and textures. - // We select the largest one (by fit into the current aspect). + for (unsigned i = 0; i < phase->inputs.size(); ++i) { + Node *input = phase->inputs[i]; + assert(input->phase->output_width != 0); + assert(input->phase->output_height != 0); + if (output_width == 0 && output_height == 0) { + output_width = input->phase->output_width; + output_height = input->phase->output_height; + } else if (output_width != input->phase->output_width || + output_height != input->phase->output_height) { + all_inputs_same_size = false; + } + } + for (unsigned i = 0; i < phase->effects.size(); ++i) { + Effect *effect = phase->effects[i]->effect; + if (effect->num_inputs() != 0) { + continue; + } + + Input *input = static_cast(effect); + if (output_width == 0 && output_height == 0) { + output_width = input->get_width(); + output_height = input->get_height(); + } else if (output_width != input->get_width() || + output_height != input->get_height()) { + all_inputs_same_size = false; + } + } + + if (all_inputs_same_size) { + assert(output_width != 0); + assert(output_height != 0); + phase->output_width = output_width; + phase->output_height = output_height; + return; + } + + // If not, fit all the inputs into the current aspect, and select the largest one. + output_width = 0; + output_height = 0; for (unsigned i = 0; i < phase->inputs.size(); ++i) { Node *input = phase->inputs[i]; assert(input->phase->output_width != 0); diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index 762447a..c17ec89 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -771,6 +771,37 @@ public: int input_width, input_height; }; +TEST(EffectChainTest, SameInputsGiveSameOutputs) { + float data[2 * 2] = { + 0.0f, 0.0f, + 0.0f, 0.0f, + }; + float out_data[2 * 2]; + + EffectChainTester tester(NULL, 4, 3); // Note non-square aspect. + + ImageFormat format; + format.color_space = COLORSPACE_sRGB; + format.gamma_curve = GAMMA_LINEAR; + + FlatInput *input1 = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2); + input1->set_pixel_data(data); + + FlatInput *input2 = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2); + input2->set_pixel_data(data); + + SizeStoringEffect *input_store = new SizeStoringEffect(); + + tester.get_chain()->add_input(input1); + tester.get_chain()->add_input(input2); + tester.get_chain()->add_effect(new AddEffect(), input1, input2); + tester.get_chain()->add_effect(input_store); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); + + EXPECT_EQ(2, input_store->input_width); + EXPECT_EQ(2, input_store->input_height); +} + TEST(EffectChainTest, AspectRatioConversion) { float data1[4 * 3] = { 0.0f, 0.0f, 0.0f, 0.0f,