From 2ba69dc78d091ad92427389147365f39760e0b1f Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Fri, 21 Jun 2019 18:22:28 +0200 Subject: [PATCH] Move the handling of human-readable input resolution printing into C++; every theme should not need to care about this. --- nageru/theme.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ nageru/theme.lua | 51 ++++++-------------------------------- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/nageru/theme.cpp b/nageru/theme.cpp index c881dc6..8050003 100644 --- a/nageru/theme.cpp +++ b/nageru/theme.cpp @@ -700,6 +700,69 @@ int InputStateInfo_get_last_subtitle(lua_State* L) return 1; } +namespace { + +// Helper function to write e.g. “60” or “59.94”. +string format_frame_rate(int nom, int den) +{ + char buf[256]; + if (nom % den == 0) { + snprintf(buf, sizeof(buf), "%d", nom / den); + } else { + snprintf(buf, sizeof(buf), "%.2f", double(nom) / den); + } + return buf; +} + +// Helper function to write e.g. “720p60”. +string get_human_readable_resolution(const InputStateInfo *input_state_info, int signal_num) +{ + char buf[256]; + if (input_state_info->last_interlaced[signal_num]) { + snprintf(buf, sizeof(buf), "%di", input_state_info->last_height[signal_num] * 2); + + // Show field rate instead of frame rate; really for cosmetics only + // (and actually contrary to EBU recommendations, although in line + // with typical user expectations). + return buf + format_frame_rate(input_state_info->last_frame_rate_nom[signal_num] * 2, + input_state_info->last_frame_rate_den[signal_num]); + } else { + snprintf(buf, sizeof(buf), "%dp", input_state_info->last_height[signal_num]); + return buf + format_frame_rate(input_state_info->last_frame_rate_nom[signal_num], + input_state_info->last_frame_rate_den[signal_num]); + } +} + +} // namespace + +int InputStateInfo_get_human_readable_resolution(lua_State* L) +{ + assert(lua_gettop(L) == 2); + InputStateInfo *input_state_info = get_input_state_info(L, 1); + Theme *theme = get_theme_updata(L); + int signal_num = theme->map_signal(luaL_checknumber(L, 2)); + + string str; + if (!input_state_info->last_is_connected[signal_num]) { + str = "disconnected"; + } else if (input_state_info->last_height[signal_num]) { + str = "no signal"; + } else if (!input_state_info->last_has_signal[signal_num]) { + if (input_state_info->last_height[signal_num]) { + // Special mode for the USB3 cards. + str = "no signal"; + } else { + str = get_human_readable_resolution(input_state_info, signal_num) + ", no signal"; + } + } else { + str = get_human_readable_resolution(input_state_info, signal_num); + } + + lua_pushstring(L, str.c_str()); + return 1; +} + + int EffectBlueprint_set_int(lua_State *L) { assert(lua_gettop(L) == 3); @@ -921,6 +984,7 @@ const luaL_Reg InputStateInfo_funcs[] = { { "get_frame_rate_nom", InputStateInfo_get_frame_rate_nom }, { "get_frame_rate_den", InputStateInfo_get_frame_rate_den }, { "get_last_subtitle", InputStateInfo_get_last_subtitle }, + { "get_human_readable_resolution", InputStateInfo_get_human_readable_resolution }, { NULL, NULL } }; diff --git a/nageru/theme.lua b/nageru/theme.lua index 973e389..de8d252 100644 --- a/nageru/theme.lua +++ b/nageru/theme.lua @@ -126,48 +126,6 @@ function is_plain_signal(num) return num == INPUT0_SIGNAL_NUM or num == INPUT1_SIGNAL_NUM end --- Helper function to write e.g. “720p60”. The difference between this --- and get_channel_resolution_raw() is that this one also can say that --- there's no signal. -function get_channel_resolution(signal_num) - local res = last_resolution[signal_num] - if (not res) or not res.is_connected then - return "disconnected" - end - if res.height <= 0 then - return "no signal" - end - if not res.has_signal then - if res.height == 525 then - -- Special mode for the USB3 cards. - return "no signal" - end - return get_channel_resolution_raw(res) .. ", no signal" - else - return get_channel_resolution_raw(res) - end -end - --- Helper function to write e.g. “60” or “59.94”. -function get_frame_rate(res) - local nom = res.frame_rate_nom - local den = res.frame_rate_den - if nom % den == 0 then - return nom / den - else - return string.format("%.2f", nom / den) - end -end - --- Helper function to write e.g. “720p60”. -function get_channel_resolution_raw(res) - if res.interlaced then - return res.height .. "i" .. get_frame_rate(res) - else - return res.height .. "p" .. get_frame_rate(res) - end -end - -- API ENTRY POINT -- Returns the name for each additional channel (starting from 2). -- Called at the start of the program, and then each frame for live @@ -175,7 +133,11 @@ end function channel_name(channel) local signal_num = channel - 2 if is_plain_signal(signal_num) then - return "Input " .. (signal_num + 1) .. " (" .. get_channel_resolution(signal_num) .. ")" + if last_resolution[signal_num] then + return "Input " .. (signal_num + 1) .. " (" .. last_resolution[signal_num].human_readable_resolution .. ")" + else + return "Input " .. (signal_num + 1) + end elseif signal_num == SBS_SIGNAL_NUM then return "Side-by-side" elseif signal_num == STATIC_SIGNAL_NUM then @@ -435,7 +397,8 @@ function get_scene(num, t, width, height, signals) is_connected = signals:get_is_connected(signal_num), has_signal = signals:get_has_signal(signal_num), frame_rate_nom = signals:get_frame_rate_nom(signal_num), - frame_rate_den = signals:get_frame_rate_den(signal_num) + frame_rate_den = signals:get_frame_rate_den(signal_num), + human_readable_resolution = signals:get_human_readable_resolution(signal_num) } if res.interlaced then -- 2.39.2