X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=nageru%2Ftheme.lua;h=de8d25222e9492e1118d94897bc7c0fc9743750f;hb=2ba69dc78d091ad92427389147365f39760e0b1f;hp=e117e62949f4472e736fe03574fbfaf5fc50e8ea;hpb=ca090e45b28fed464008086fbe3db19437c115dd;p=nageru diff --git a/nageru/theme.lua b/nageru/theme.lua index e117e62..de8d252 100644 --- a/nageru/theme.lua +++ b/nageru/theme.lua @@ -42,13 +42,9 @@ local FADE_TRANSITION = 2 local last_resolution = {} function make_sbs_input(scene) - local resample_effect = ResampleEffect.new() - local resize_effect = ResizeEffect.new() return { input = scene:add_input(), - resample_effect = resample_effect, - resize_effect = resize_effect, - resample_switcher = scene:add_effect({resample_effect, resize_effect}), + resample_effect = scene:add_effect({ResampleEffect.new(), ResizeEffect.new()}), wb_effect = scene:add_effect(WhiteBalanceEffect.new()), padding_effect = scene:add_effect(IntegralPaddingEffect.new()) } @@ -130,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 @@ -179,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 @@ -401,14 +359,14 @@ function setup_simple_input(state, signals, signal_num, width, height, hq) simple_scene.input:display(signal_num) if needs_scale(signals, signal_num, width, height) then if hq then - simple_scene.resample_effect:choose_alternative(ResampleEffect) -- High-quality resampling. + simple_scene.resample_effect:choose(ResampleEffect) -- High-quality resampling. else - simple_scene.resample_effect:choose_alternative(ResizeEffect) -- Low-quality resampling. + simple_scene.resample_effect:choose(ResizeEffect) -- Low-quality resampling. end simple_scene.resample_effect:set_int("width", width) simple_scene.resample_effect:set_int("height", height) else - simple_scene.resample_effect:choose_alternative(2) -- No scaling. + simple_scene.resample_effect:disable() -- No scaling. end set_neutral_color_from_signal(state, simple_scene.wb_effect, signal_num) end @@ -439,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 @@ -509,9 +468,9 @@ function place_rectangle(input, x0, y0, x1, y1, screen_width, screen_height, inp -- Cull. if x0 > screen_width or x1 < 0.0 or y0 > screen_height or y1 < 0.0 then - input.resample_switcher:choose_alternative(ResizeEffect) -- Low-quality resizing. - input.resize_effect:set_int("width", 1) - input.resize_effect:set_int("height", 1) + input.resample_effect:choose(ResizeEffect) -- Low-quality resizing. + input.resample_effect:set_int("width", 1) + input.resample_effect:set_int("height", 1) input.padding_effect:set_int("left", screen_width + 100) input.padding_effect:set_int("top", screen_height + 100) return @@ -541,8 +500,9 @@ function place_rectangle(input, x0, y0, x1, y1, screen_width, screen_height, inp end if hq then - -- High-quality resampling. - input.resample_switcher:choose_alternative(ResampleEffect) + -- High-quality resampling. Go for the actual effect (returned by choose()) + -- since we want to set zoom_*, which will give an error if set on ResizeEffect. + local resample_effect = input.resample_effect:choose(ResampleEffect) local x_subpixel_offset = x0 - math.floor(x0) local y_subpixel_offset = y0 - math.floor(y0) @@ -551,25 +511,25 @@ function place_rectangle(input, x0, y0, x1, y1, screen_width, screen_height, inp -- and then add an extra pixel so we have some leeway for the border. local width = math.ceil(x1 - x0) + 1 local height = math.ceil(y1 - y0) + 1 - input.resample_effect:set_int("width", width) - input.resample_effect:set_int("height", height) + resample_effect:set_int("width", width) + resample_effect:set_int("height", height) -- Correct the discrepancy with zoom. (This will leave a small -- excess edge of pixels and subpixels, which we'll correct for soon.) local zoom_x = (x1 - x0) / (width * (srcx1 - srcx0)) local zoom_y = (y1 - y0) / (height * (srcy1 - srcy0)) - input.resample_effect:set_float("zoom_x", zoom_x) - input.resample_effect:set_float("zoom_y", zoom_y) - input.resample_effect:set_float("zoom_center_x", 0.0) - input.resample_effect:set_float("zoom_center_y", 0.0) + resample_effect:set_float("zoom_x", zoom_x) + resample_effect:set_float("zoom_y", zoom_y) + resample_effect:set_float("zoom_center_x", 0.0) + resample_effect:set_float("zoom_center_y", 0.0) -- Padding must also be to a whole-pixel offset. input.padding_effect:set_int("left", math.floor(x0)) input.padding_effect:set_int("top", math.floor(y0)) -- Correct _that_ discrepancy by subpixel offset in the resampling. - input.resample_effect:set_float("left", srcx0 * input_width - x_subpixel_offset / zoom_x) - input.resample_effect:set_float("top", srcy0 * input_height - y_subpixel_offset / zoom_y) + resample_effect:set_float("left", srcx0 * input_width - x_subpixel_offset / zoom_x) + resample_effect:set_float("top", srcy0 * input_height - y_subpixel_offset / zoom_y) -- Finally, adjust the border so it is exactly where we want it. input.padding_effect:set_float("border_offset_left", x_subpixel_offset) @@ -578,12 +538,12 @@ function place_rectangle(input, x0, y0, x1, y1, screen_width, screen_height, inp input.padding_effect:set_float("border_offset_bottom", y1 - (math.floor(y0) + height)) else -- Lower-quality simple resizing. - input.resample_switcher:choose_alternative(ResizeEffect) + input.resample_effect:choose(ResizeEffect) local width = round(x1 - x0) local height = round(y1 - y0) - input.resize_effect:set_int("width", width) - input.resize_effect:set_int("height", height) + input.resample_effect:set_int("width", width) + input.resample_effect:set_int("height", height) -- Padding must also be to a whole-pixel offset. input.padding_effect:set_int("left", math.floor(x0))