]> git.sesse.net Git - movit/blobdiff - effect_chain.cpp
FlatInput can only auto-expand from linear or sRGB, not e.g. Rec. 601/709 gamma.
[movit] / effect_chain.cpp
index b4be1489189405abcd04afb2c42f34e82a3f63fb..aae2941f791ca86faf9ce16cea4912cd9c05fd1b 100644 (file)
@@ -74,9 +74,9 @@ void EffectChain::add_effect_raw(Effect *effect, const std::vector<Effect *> &in
        node_map[effect] = node;
 }
 
-void EffectChain::find_all_nonlinear_inputs(EffectChain::Node *node,
-                                            std::vector<EffectChain::Node *> *nonlinear_inputs,
-                                            std::vector<EffectChain::Node *> *intermediates)
+void EffectChain::find_all_nonlinear_inputs(Node *node,
+                                            std::vector<Node *> *nonlinear_inputs,
+                                            std::vector<Node *> *intermediates)
 {
        if (node->output_gamma_curve == GAMMA_LINEAR) {
                return;
@@ -92,7 +92,7 @@ void EffectChain::find_all_nonlinear_inputs(EffectChain::Node *node,
        }
 }
 
-EffectChain::Node *EffectChain::normalize_to_linear_gamma(EffectChain::Node *input)
+Node *EffectChain::normalize_to_linear_gamma(Node *input)
 {
        // Find out if all the inputs can be set to deliver sRGB inputs.
        // If so, we can just ask them to do that instead of inserting a
@@ -140,7 +140,7 @@ EffectChain::Node *EffectChain::normalize_to_linear_gamma(EffectChain::Node *inp
        return node;
 }
 
-EffectChain::Node *EffectChain::normalize_to_srgb(EffectChain::Node *input)
+Node *EffectChain::normalize_to_srgb(Node *input)
 {
        assert(input->output_gamma_curve == GAMMA_LINEAR);
        ColorSpaceConversionEffect *colorspace_conversion = new ColorSpaceConversionEffect();
@@ -218,9 +218,9 @@ std::string replace_prefix(const std::string &text, const std::string &prefix)
        return output;
 }
 
-EffectChain::Phase *EffectChain::compile_glsl_program(
-       const std::vector<EffectChain::Node *> &inputs,
-       const std::vector<EffectChain::Node *> &effects)
+Phase *EffectChain::compile_glsl_program(
+       const std::vector<Node *> &inputs,
+       const std::vector<Node *> &effects)
 {
        assert(!effects.empty());
 
@@ -312,7 +312,7 @@ EffectChain::Phase *EffectChain::compile_glsl_program(
 //
 // We follow a quite simple depth-first search from the output, although
 // without any explicit recursion.
-void EffectChain::construct_glsl_programs(EffectChain::Node *output)
+void EffectChain::construct_glsl_programs(Node *output)
 {
        // Which effects have already been completed in this phase?
        // We need to keep track of it, as an effect with multiple outputs
@@ -414,7 +414,66 @@ void EffectChain::construct_glsl_programs(EffectChain::Node *output)
        std::reverse(phases.begin(), phases.end());
 }
 
-void EffectChain::find_output_size(EffectChain::Phase *phase)
+void EffectChain::output_dot(const char *filename)
+{
+       FILE *fp = fopen(filename, "w");
+       if (fp == NULL) {
+               perror(filename);
+               exit(1);
+       }
+
+       fprintf(fp, "digraph G {\n");
+       for (unsigned i = 0; i < nodes.size(); ++i) {
+               fprintf(fp, "  n%ld [label=\"%s\"];\n", (long)nodes[i], nodes[i]->effect->effect_type_id().c_str());
+               for (unsigned j = 0; j < nodes[i]->outgoing_links.size(); ++j) {
+                       std::vector<std::string> labels;
+
+                       if (nodes[i]->outgoing_links[j]->effect->needs_texture_bounce()) {
+                               labels.push_back("needs_bounce");
+                       }
+                       if (nodes[i]->effect->changes_output_size()) {
+                               labels.push_back("resize");
+                       }
+
+                       switch (nodes[i]->output_color_space) {
+                       case COLORSPACE_REC_601_525:
+                               labels.push_back("spc[rec601-525]");
+                               break;
+                       case COLORSPACE_REC_601_625:
+                               labels.push_back("spc[rec601-625]");
+                               break;
+                       default:
+                               break;
+                       }
+
+                       switch (nodes[i]->output_gamma_curve) {
+                       case GAMMA_sRGB:
+                               labels.push_back("gamma[sRGB]");
+                               break;
+                       case GAMMA_REC_601:  // and GAMMA_REC_709
+                               labels.push_back("gamma[rec601/709]");
+                               break;
+                       default:
+                               break;
+                       }
+
+                       if (labels.empty()) {
+                               fprintf(fp, "  n%ld -> n%ld;\n", (long)nodes[i], (long)nodes[i]->outgoing_links[j]);
+                       } else {
+                               std::string label = labels[0];
+                               for (unsigned k = 1; k < labels.size(); ++k) {
+                                       label += ", " + labels[k];
+                               }
+                               fprintf(fp, "  n%ld -> n%ld [label=\"%s\"];\n", (long)nodes[i], (long)nodes[i]->outgoing_links[j], label.c_str());
+                       }
+               }
+       }
+       fprintf(fp, "}\n");
+
+       fclose(fp);
+}
+
+void EffectChain::find_output_size(Phase *phase)
 {
        Node *output_node = phase->effects.back();
 
@@ -453,6 +512,8 @@ void EffectChain::find_output_size(EffectChain::Phase *phase)
 
 void EffectChain::finalize()
 {
+       output_dot("final.dot");
+
        // Find the output effect. This is, simply, one that has no outgoing links.
        // If there are multiple ones, the graph is malformed (we do not support
        // multiple outputs right now).