]> git.sesse.net Git - movit/blobdiff - effect_chain_test.cpp
In resizing effects, add the notion of a “virtual output size”.
[movit] / effect_chain_test.cpp
index 762447aad99018bcb885fc3651fb00a46df89a48..5fa81d3e559ce3fb51b67c59944a0f3a1e129e5b 100644 (file)
@@ -767,10 +767,42 @@ public:
                input_width = width;
                input_height = height;
        }
+       virtual std::string effect_type_id() const { return "SizeStoringEffect"; }
 
        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,
@@ -815,3 +847,53 @@ TEST(EffectChainTest, AspectRatioConversion) {
        EXPECT_EQ(9, input_store->input_width);
        EXPECT_EQ(7, input_store->input_height);
 }
+
+// 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) {}
+       virtual std::string effect_type_id() const { return "VirtualResizeEffect"; }
+       std::string output_fragment_shader() { return read_file("identity.frag"); }
+
+       virtual bool changes_output_size() const { return true; }
+
+       virtual void get_output_size(unsigned *width, unsigned *height,
+                                    unsigned *virtual_width, unsigned *virtual_height) const {
+               *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(EffectChainTest, VirtualSizeIsSentOnToInputs) {
+       const int size = 2, bigger_size = 3;
+       float data[size * size] = {
+               1.0f, 0.0f,
+               0.0f, 1.0f,
+       };
+       float out_data[size * size];
+       
+       EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       SizeStoringEffect *size_store = new SizeStoringEffect();
+
+       tester.get_chain()->add_effect(new VirtualResizeEffect(size, size, bigger_size, bigger_size));
+       tester.get_chain()->add_effect(size_store);
+       tester.get_chain()->add_effect(new VirtualResizeEffect(size, size, size, size));
+       tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       EXPECT_EQ(bigger_size, size_store->input_width);
+       EXPECT_EQ(bigger_size, size_store->input_height);
+
+       // If the resize is implemented as non-virtual, we'll fail here,
+       // since bilinear scaling from 2x2 → 3x3 → 2x2 is not very exact.
+       expect_equal(data, out_data, size, size);
+}