From 7689bddf417c9a9da111ef58a08a67dd278fa7c1 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Wed, 12 Feb 2020 17:59:12 +0100 Subject: [PATCH] Make it possible for auto white balance to be controlled by another input. This is useful if you want to run white balance on something that could e.g. have an overlay. --- nageru/scene.cpp | 67 ++++++++++++++++++++++++++++-------------------- nageru/scene.h | 3 ++- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/nageru/scene.cpp b/nageru/scene.cpp index a926836..f4320b4 100644 --- a/nageru/scene.cpp +++ b/nageru/scene.cpp @@ -178,8 +178,8 @@ bool Scene::is_noncanonical_chain(size_t chain_idx) const } // Auto white balance is always disabled for image inputs. - if (block->root_input_block != nullptr) { - const Block *input = block->root_input_block; + if (block->white_balance_controller_block != nullptr) { + const Block *input = block->white_balance_controller_block; if (input->alternatives[input->chosen_alternative(chain_idx)]->effect_type == IMAGE_INPUT) { return true; } @@ -235,6 +235,24 @@ int Scene::add_input(lua_State* L) return wrap_lua_existing_object_nonowned(L, "Block", block); } +Block *Scene::find_block_from_arg(lua_State *L, Scene *scene, int idx) +{ + if (luaL_testudata(L, idx, "Block")) { + return *(Block **)luaL_checkudata(L, idx, "Block"); + } else { + EffectBlueprint *blueprint = *(EffectBlueprint **)luaL_checkudata(L, idx, "EffectBlueprint"); + + // Search through all the blocks to figure out which one contains this effect. + for (Block *block : scene->blocks) { + if (find(block->alternatives.begin(), block->alternatives.end(), blueprint) != block->alternatives.end()) { + return block; + } + } + luaL_error(L, "Input effect in parameter #%d has not been added to this scene", idx - 1); + return nullptr; // Dead code. + } +} + void Scene::find_inputs_for_block(lua_State *L, Scene *scene, Block *block, int first_input_idx) { if (lua_gettop(L) == first_input_idx - 1) { @@ -245,24 +263,7 @@ void Scene::find_inputs_for_block(lua_State *L, Scene *scene, Block *block, int } for (int idx = first_input_idx; idx <= lua_gettop(L); ++idx) { - Block *input_block = nullptr; - if (luaL_testudata(L, idx, "Block")) { - input_block = *(Block **)luaL_checkudata(L, idx, "Block"); - } else { - EffectBlueprint *blueprint = *(EffectBlueprint **)luaL_checkudata(L, idx, "EffectBlueprint"); - - // Search through all the blocks to figure out which one contains this effect. - for (Block *block : scene->blocks) { - if (find(block->alternatives.begin(), block->alternatives.end(), blueprint) != block->alternatives.end()) { - input_block = block; - break; - } - } - if (input_block == nullptr) { - luaL_error(L, "Input effect in parameter #%d has not been added to this scene", idx - 1); - } - } - block->inputs.push_back(input_block->idx); + block->inputs.push_back(find_block_from_arg(L, scene, idx)->idx); } } @@ -360,14 +361,24 @@ int Scene::add_auto_white_balance(lua_State* L) block->canonical_alternative = 1; - find_inputs_for_block(L, scene, block, /*first_input_idx=*/2); - - if (block->inputs.size() != 1) { - luaL_error(L, "add_auto_white_balance() needs exactly one input"); + if (lua_gettop(L) == 1) { + // The last added effect is implicitly both the input and gives the white balance controller. + assert(!scene->blocks.empty()); + block->inputs.push_back(scene->blocks.size() - 1); + block->white_balance_controller_block = scene->find_root_input_block(L, block); + } else if (lua_gettop(L) == 2) { + // The given effect is both the input and the white balance controller. + block->inputs.push_back(find_block_from_arg(L, scene, 2)->idx); + block->white_balance_controller_block = scene->find_root_input_block(L, block); + } else if (lua_gettop(L) == 3) { + // We have explicit input and white balance controller. + block->inputs.push_back(find_block_from_arg(L, scene, 2)->idx); + block->white_balance_controller_block = find_block_from_arg(L, scene, 3); + } else { + luaL_error(L, "add_auto_white_balance([input], [white_balance_controller]) takes zero, one or two arguments"); } - block->root_input_block = scene->find_root_input_block(L, block); - if (block->root_input_block == nullptr) { - luaL_error(L, "add_auto_white_balance() was not connected to an input"); + if (block->white_balance_controller_block == nullptr || !block->white_balance_controller_block->is_input) { + luaL_error(L, "add_auto_white_balance() does not get its white balance from an input"); } scene->blocks.push_back(block); @@ -525,7 +536,7 @@ Scene::get_chain(Theme *theme, lua_State *L, unsigned num, const InputState &inp map> white_balance; for (size_t block_idx = 0; block_idx < blocks.size(); ++block_idx) { Block *block = blocks[block_idx]; - const Block *input = block->root_input_block; + const Block *input = block->white_balance_controller_block; if (input == nullptr) { continue; // Not an auto white balance block. } diff --git a/nageru/scene.h b/nageru/scene.h index 8cff06a..4e1181b 100644 --- a/nageru/scene.h +++ b/nageru/scene.h @@ -134,7 +134,7 @@ struct Block { // Only for AUTO_WHITE_BALANCE_EFFECT. Points to the parent block with is_input = true, // so that we know which signal to get the white balance from. - const Block *root_input_block = nullptr; + const Block *white_balance_controller_block = nullptr; }; int Block_display(lua_State* L); @@ -167,6 +167,7 @@ private: movit::Effect *instantiate_effects(const Block *block, size_t chain_idx, Instantiation *instantiation); size_t compute_chain_number_for_block(size_t block_idx, const std::bitset<256> &disabled) const; static void find_inputs_for_block(lua_State *L, Scene *scene, Block *block, int first_input_idx = 3); + static Block *find_block_from_arg(lua_State *L, Scene *scene, int idx); // Find out which blocks (indexed by position in the “blocks” array), // if any, are disabled in a given instantiation. A disabled block is -- 2.39.2