From 1bf2b3e600dc5485f4957a419459b997d721e5fa Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 29 Feb 2020 22:44:07 +0100 Subject: [PATCH] Make so that auto white balance is stored per (physical) card, not per signal. This fixes an issue where auto white balance would be completely off if any signals were remapped out of the default. It means you no longer can duplicate a signal and have different white balance on it, but that seems narrow enough that one could use manual white balance for that (I can't really imagine what the use case would be). --- nageru/mixer.cpp | 4 ++-- nageru/scene.cpp | 32 ++++++++++++++++---------------- nageru/scene.h | 4 ++-- nageru/theme.cpp | 23 ++++++++++++----------- nageru/theme.h | 8 ++++---- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/nageru/mixer.cpp b/nageru/mixer.cpp index 464b920..63d1f72 100644 --- a/nageru/mixer.cpp +++ b/nageru/mixer.cpp @@ -1134,12 +1134,12 @@ void Mixer::thread_func() if (fabs(new_frame->neutral_color.r - last_received_neutral_color[card_index].r) > 1e-3 || fabs(new_frame->neutral_color.g - last_received_neutral_color[card_index].g) > 1e-3 || fabs(new_frame->neutral_color.b - last_received_neutral_color[card_index].b) > 1e-3) { - theme->set_wb_for_signal(card_index, new_frame->neutral_color.r, new_frame->neutral_color.g, new_frame->neutral_color.b); + theme->set_wb_for_card(card_index, new_frame->neutral_color.r, new_frame->neutral_color.g, new_frame->neutral_color.b); last_received_neutral_color[card_index] = new_frame->neutral_color; } if (new_frame->frame->data_copy != nullptr && mjpeg_encoder->should_encode_mjpeg_for_card(card_index)) { - RGBTriplet neutral_color = theme->get_white_balance_for_signal(card_index); + RGBTriplet neutral_color = theme->get_white_balance_for_card(card_index); mjpeg_encoder->upload_frame(pts_int, card_index, new_frame->frame, new_frame->video_format, new_frame->y_offset, new_frame->cbcr_offset, move(raw_audio[card_index]), neutral_color); } diff --git a/nageru/scene.cpp b/nageru/scene.cpp index ca6cc70..53a64a0 100644 --- a/nageru/scene.cpp +++ b/nageru/scene.cpp @@ -495,10 +495,10 @@ int Scene::finalize(lua_State* L) return 0; } -int find_signal_to_connect(lua_State *L, const Block *block) +int find_card_to_connect(lua_State *L, const Block *block) { - if (block->signal_type_to_connect == Block::CONNECT_SIGNAL) { - return block->signal_to_connect; + if (block->signal_type_to_connect == Block::CONNECT_CARD) { + return block->card_to_connect; #ifdef HAVE_CEF } else if (block->signal_type_to_connect == Block::CONNECT_CEF) { return block->cef_to_connect->get_card_index(); @@ -520,10 +520,10 @@ Scene::get_chain(Theme *theme, lua_State *L, unsigned num, const InputState &inp // based on the current state of the signals. InputStateInfo info(input_state); for (Block *block : blocks) { - if (block->is_input && block->signal_type_to_connect == Block::CONNECT_SIGNAL) { + if (block->is_input && block->signal_type_to_connect == Block::CONNECT_CARD) { EffectType chosen_type = current_type(block); assert(chosen_type == LIVE_INPUT_YCBCR || chosen_type == LIVE_INPUT_YCBCR_WITH_DEINTERLACE); - if (info.last_interlaced[block->signal_to_connect]) { + if (info.last_interlaced[block->card_to_connect]) { block->currently_chosen_alternative = find_index_of(block, LIVE_INPUT_YCBCR_WITH_DEINTERLACE); } else { block->currently_chosen_alternative = find_index_of(block, LIVE_INPUT_YCBCR); @@ -552,8 +552,8 @@ Scene::get_chain(Theme *theme, lua_State *L, unsigned num, const InputState &inp chosen_type == LIVE_INPUT_YCBCR_WITH_DEINTERLACE || chosen_type == LIVE_INPUT_YCBCR_PLANAR || chosen_type == LIVE_INPUT_BGRA); - int signal = find_signal_to_connect(L, input); - RGBTriplet wb = theme->get_white_balance_for_signal(signal); + int card_idx = find_card_to_connect(L, input); + RGBTriplet wb = theme->get_white_balance_for_card(card_idx); if (fabs(wb.r - 1.0) < 1e-3 && fabs(wb.g - 1.0) < 1e-3 && fabs(wb.b - 1.0) < 1e-3) { // Neutral white balance. block->currently_chosen_alternative = find_index_of(block, IDENTITY_EFFECT); @@ -589,7 +589,7 @@ Scene::get_chain(Theme *theme, lua_State *L, unsigned num, const InputState &inp const Scene::Instantiation &instantiation = chains[chain_idx]; EffectChain *effect_chain = instantiation.chain.get(); - map signals_to_connect; + map cards_to_connect; map images_to_select; map, int> int_to_set; map, float> float_to_set; @@ -603,7 +603,7 @@ Scene::get_chain(Theme *theme, lua_State *L, unsigned num, const InputState &inp chosen_type == LIVE_INPUT_YCBCR_PLANAR || chosen_type == LIVE_INPUT_BGRA) { LiveInputWrapper *input = index_and_input.second; - signals_to_connect.emplace(input, find_signal_to_connect(L, block)); + cards_to_connect.emplace(input, find_card_to_connect(L, block)); } } for (const auto &index_and_input : instantiation.image_inputs) { @@ -682,13 +682,13 @@ Scene::get_chain(Theme *theme, lua_State *L, unsigned num, const InputState &inp lua_pop(L, 1); - auto setup_chain = [L, theme, signals_to_connect, images_to_select, int_to_set, float_to_set, vec3_to_set, vec4_to_set, input_state]{ + auto setup_chain = [L, theme, cards_to_connect, images_to_select, int_to_set, float_to_set, vec3_to_set, vec4_to_set, input_state]{ lock_guard lock(theme->m); - // Set up state, including connecting signals. - for (const auto &input_and_signal : signals_to_connect) { - LiveInputWrapper *input = input_and_signal.first; - input->connect_signal_raw(input_and_signal.second, input_state); + // Set up state, including connecting cards. + for (const auto &input_and_card : cards_to_connect) { + LiveInputWrapper *input = input_and_card.first; + input->connect_card(input_and_card.second, input_state); } for (const auto &input_and_filename : images_to_select) { input_and_filename.first->switch_image(input_and_filename.second); @@ -736,8 +736,8 @@ bool display(Block *block, lua_State *L, int idx) if (lua_isnumber(L, idx)) { Theme *theme = get_theme_updata(L); int signal_idx = luaL_checknumber(L, idx); - block->signal_type_to_connect = Block::CONNECT_SIGNAL; - block->signal_to_connect = theme->map_signal_to_card(signal_idx); // FIXME: Assigning a card to something named about signals. + block->signal_type_to_connect = Block::CONNECT_CARD; + block->card_to_connect = theme->map_signal_to_card(signal_idx); block->currently_chosen_alternative = find_index_of(block, LIVE_INPUT_YCBCR); // Will be changed to deinterlaced at get_chain() time if needed. return true; #ifdef HAVE_CEF diff --git a/nageru/scene.h b/nageru/scene.h index 4e1181b..e126ca3 100644 --- a/nageru/scene.h +++ b/nageru/scene.h @@ -113,8 +113,8 @@ struct Block { // For LIVE_INPUT* only. We can't just always populate signal_to_connect, // since when we set this, CEF and video signals may not have numbers yet. // FIXME: Perhaps it would be simpler if they just did? - enum { CONNECT_NONE, CONNECT_SIGNAL, CONNECT_CEF, CONNECT_VIDEO } signal_type_to_connect = CONNECT_NONE; - int signal_to_connect = 0; // For CONNECT_SIGNAL. + enum { CONNECT_NONE, CONNECT_CARD, CONNECT_CEF, CONNECT_VIDEO } signal_type_to_connect = CONNECT_NONE; + int card_to_connect = 0; // For CONNECT_CARD. #ifdef HAVE_CEF CEFCapture *cef_to_connect = nullptr; // For CONNECT_CEF. #endif diff --git a/nageru/theme.cpp b/nageru/theme.cpp index 65d82da..d63c853 100644 --- a/nageru/theme.cpp +++ b/nageru/theme.cpp @@ -1124,11 +1124,11 @@ bool LiveInputWrapper::connect_signal(int signal_num) } int card_idx = theme->map_signal_to_card(signal_num); - connect_signal_raw(card_idx, *theme->input_state); + connect_card(card_idx, *theme->input_state); return true; } -void LiveInputWrapper::connect_signal_raw(int card_idx, const InputState &input_state) +void LiveInputWrapper::connect_card(int card_idx, const InputState &input_state) { BufferedFrame first_frame = input_state.buffered_frames[card_idx][0]; if (first_frame.frame == nullptr) { @@ -1677,13 +1677,13 @@ Theme::Chain Theme::get_chain_from_effect_chain(EffectChain *effect_chain, unsig // each FFmpeg or CEF input, so we'll do it here. if (video_signal_connections.count(effect_chain)) { for (const VideoSignalConnection &conn : video_signal_connections[effect_chain]) { - conn.wrapper->connect_signal_raw(conn.source->get_card_index(), input_state); + conn.wrapper->connect_card(conn.source->get_card_index(), input_state); } } #ifdef HAVE_CEF if (html_signal_connections.count(effect_chain)) { for (const CEFSignalConnection &conn : html_signal_connections[effect_chain]) { - conn.wrapper->connect_signal_raw(conn.source->get_card_index(), input_state); + conn.wrapper->connect_card(conn.source->get_card_index(), input_state); } } #endif @@ -1868,19 +1868,20 @@ void Theme::set_wb(unsigned channel, float r, float g, float b) lock_guard lock(m); if (signal != -1) { - white_balance_for_signal[signal] = RGBTriplet{ r, g, b }; + int card_idx = map_signal_to_card(signal); + white_balance_for_card[card_idx] = RGBTriplet{ r, g, b }; } call_lua_wb_callback(channel, r, g, b); } -void Theme::set_wb_for_signal(int signal, float r, float g, float b) +void Theme::set_wb_for_card(int card_idx, float r, float g, float b) { lock_guard lock(m); - white_balance_for_signal[signal] = RGBTriplet{ r, g, b }; + white_balance_for_card[card_idx] = RGBTriplet{ r, g, b }; for (const auto &channel_and_signal : channel_signals) { - if (channel_and_signal.second == signal) { + if (map_signal_to_card(channel_and_signal.second) == card_idx) { call_lua_wb_callback(channel_and_signal.first, r, g, b); } } @@ -1907,10 +1908,10 @@ void Theme::call_lua_wb_callback(unsigned channel, float r, float g, float b) assert(lua_gettop(L) == 0); } -RGBTriplet Theme::get_white_balance_for_signal(int signal) +RGBTriplet Theme::get_white_balance_for_card(int card_idx) { - if (white_balance_for_signal.count(signal)) { - return white_balance_for_signal[signal]; + if (white_balance_for_card.count(card_idx)) { + return white_balance_for_card[card_idx]; } else { return RGBTriplet{ 1.0, 1.0, 1.0 }; } diff --git a/nageru/theme.h b/nageru/theme.h index 2be6689..fe713ef 100644 --- a/nageru/theme.h +++ b/nageru/theme.h @@ -105,11 +105,11 @@ public: int map_channel_to_signal(unsigned channel); bool get_supports_set_wb(unsigned channel); void set_wb(unsigned channel, float r, float g, float b); - void set_wb_for_signal(int signal, float r, float g, float b); - movit::RGBTriplet get_white_balance_for_signal(int signal); + void set_wb_for_card(int card_idx, float r, float g, float b); + movit::RGBTriplet get_white_balance_for_card(int card_idx); std::string get_channel_color(unsigned channel); - std::unordered_map white_balance_for_signal; + std::unordered_map white_balance_for_card; std::vector get_transition_names(float t); @@ -255,7 +255,7 @@ public: LiveInputWrapper(Theme *theme, movit::EffectChain *chain, bmusb::PixelFormat pixel_format, bool override_bounce, bool deinterlace, bool user_connectable); bool connect_signal(int signal_num); // Must be called with the theme's lock held, since it accesses theme->input_state. Returns false on error. - void connect_signal_raw(int signal_num, const InputState &input_state); + void connect_card(int signal_num, const InputState &input_state); movit::Effect *get_effect() const { if (deinterlace) { -- 2.39.2