]> git.sesse.net Git - nageru/blobdiff - nageru/theme.cpp
Fix a Clang 19 warning.
[nageru] / nageru / theme.cpp
index a88c6f61c70034bcf1c104804852b1e5364aaeca..192b27eabbe981581283cc6e111dddd7345134ff 100644 (file)
@@ -1,11 +1,16 @@
 #include "theme.h"
 
+#include <algorithm>
+#include <array>
 #include <assert.h>
 #include <bmusb/bmusb.h>
 #include <epoxy/gl.h>
+#include <mutex>
 #include <stdarg.h>
 #include <lauxlib.h>
 #include <lua.hpp>
+#include <math.h>
+#include <movit/blur_effect.h>
 #include <movit/deinterlace_effect.h>
 #include <movit/effect.h>
 #include <movit/effect_chain.h>
@@ -19,6 +24,7 @@
 #include <movit/resample_effect.h>
 #include <movit/resize_effect.h>
 #include <movit/util.h>
+#include <movit/unsharp_mask_effect.h>
 #include <movit/white_balance_effect.h>
 #include <movit/ycbcr.h>
 #include <movit/ycbcr_input.h>
 #include <stdlib.h>
 #include <cstddef>
 #include <memory>
-#include <new>
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "audio_mixer.h"
 #include "defs.h"
+#include "input_mapping.h"
+#include "lua.h"
+#include "lualib.h"
+#include "shared/shared_defs.h"
+#include "tweaked_inputs.h"
 #ifdef HAVE_CEF
 #include "cef_capture.h"
 #endif
@@ -42,6 +54,7 @@
 #include "mainwindow.h"
 #include "pbo_frame_allocator.h"
 #include "scene.h"
+#include "shared/context.h"
 
 class Mixer;
 
@@ -111,9 +124,9 @@ InputStateInfo::InputStateInfo(const InputState &input_state)
 // An effect that does nothing.
 class IdentityEffect : public Effect {
 public:
-        IdentityEffect() {}
-        string effect_type_id() const override { return "IdentityEffect"; }
-        string output_fragment_shader() override { return read_file("identity.frag"); }
+       IdentityEffect() {}
+       string effect_type_id() const override { return "IdentityEffect"; }
+       string output_fragment_shader() override { return read_file("identity.frag"); }
 };
 
 Effect *instantiate_effect(EffectChain *chain, EffectType effect_type)
@@ -140,6 +153,10 @@ Effect *instantiate_effect(EffectChain *chain, EffectType effect_type)
                return new MixEffect;
        case LIFT_GAMMA_GAIN_EFFECT:
                return new LiftGammaGainEffect;
+       case BLUR_EFFECT:
+               return new BlurEffect;
+       case UNSHARP_MASK_EFFECT:
+               return new UnsharpMaskEffect;
        default:
                fprintf(stderr, "Unhandled effect type %d\n", effect_type);
                abort();
@@ -434,6 +451,9 @@ int ImageInput_new(lua_State* L)
        return wrap_lua_object_nonowned<ImageInput>(L, "ImageInput", filename);
 }
 
+}  // namespace
+
+// Must be non-namespaced due to friend declaration.
 int VideoInput_new(lua_State* L)
 {
        assert(lua_gettop(L) == 2);
@@ -444,17 +464,19 @@ int VideoInput_new(lua_State* L)
                print_warning(L, "Invalid enum %d used for video format, choosing Y'CbCr.\n", pixel_format);
                pixel_format = bmusb::PixelFormat_8BitYCbCrPlanar;
        }
-       int ret = wrap_lua_object_nonowned<FFmpegCapture>(L, "VideoInput", filename, global_flags.width, global_flags.height);
+       Theme *theme = get_theme_updata(L);
+       int ret = wrap_lua_object_nonowned<FFmpegCapture>(L, "VideoInput", filename, global_flags.width, global_flags.height, create_surface_with_same_format(theme->surface));
        if (ret == 1) {
                FFmpegCapture **capture = (FFmpegCapture **)lua_touserdata(L, -1);
                (*capture)->set_pixel_format(bmusb::PixelFormat(pixel_format));
 
-               Theme *theme = get_theme_updata(L);
                theme->register_video_input(*capture);
        }
        return ret;
 }
 
+namespace {
+
 int VideoInput_rewind(lua_State* L)
 {
        assert(lua_gettop(L) == 1);
@@ -622,6 +644,18 @@ int LiftGammaGainEffect_new(lua_State* L)
        return wrap_lua_object_nonowned<EffectBlueprint>(L, "EffectBlueprint", LIFT_GAMMA_GAIN_EFFECT);
 }
 
+int BlurEffect_new(lua_State* L)
+{
+       assert(lua_gettop(L) == 0);
+       return wrap_lua_object_nonowned<EffectBlueprint>(L, "EffectBlueprint", BLUR_EFFECT);
+}
+
+int UnsharpMaskEffect_new(lua_State* L)
+{
+       assert(lua_gettop(L) == 0);
+       return wrap_lua_object_nonowned<EffectBlueprint>(L, "EffectBlueprint", UNSHARP_MASK_EFFECT);
+}
+
 int InputStateInfo_get_width(lua_State* L)
 {
        assert(lua_gettop(L) == 2);
@@ -997,6 +1031,16 @@ const luaL_Reg LiftGammaGainEffect_funcs[] = {
        { NULL, NULL }
 };
 
+const luaL_Reg BlurEffect_funcs[] = {
+       { "new", BlurEffect_new },
+       { NULL, NULL }
+};
+
+const luaL_Reg UnsharpMaskEffect_funcs[] = {
+       { "new", UnsharpMaskEffect_new },
+       { NULL, NULL }
+};
+
 // End of effects.
 
 const luaL_Reg InputStateInfo_funcs[] = {
@@ -1420,6 +1464,15 @@ int Nageru_set_audio_bus_mute(lua_State *L)
        return 0;
 }
 
+int Nageru_schedule_cut(lua_State *L)
+{
+       if (global_mixer == nullptr) {
+               luaL_error(L, "Cuts can not be scheduled before the theme is done initializing.");
+       }
+       global_mixer->schedule_cut();
+       return 0;
+}
+
 int Nageru_get_audio_bus_eq_level_db(lua_State *L)
 {
        if (global_audio_mixer == nullptr) {
@@ -1466,15 +1519,15 @@ int Nageru_set_audio_bus_eq_level_db(lua_State *L)
        return 0;
 }
 
-Theme::Theme(const string &filename, const vector<string> &search_dirs, ResourcePool *resource_pool)
-       : resource_pool(resource_pool), signal_to_card_mapping(global_flags.default_stream_mapping)
+Theme::Theme(const string &filename, const vector<string> &search_dirs, ResourcePool *resource_pool, QSurface *surface)
+       : resource_pool(resource_pool), signal_to_card_mapping(global_flags.default_stream_mapping), surface(surface)
 {
        // Defaults.
        channel_names[0] = "Live";
        channel_names[1] = "Preview";
 
        L = luaL_newstate();
-        luaL_openlibs(L);
+       luaL_openlibs(L);
 
        // Search through all directories until we find a file that will load
        // (as in, does not return LUA_ERRFILE); then run it. We store load errors
@@ -1558,6 +1611,8 @@ Theme::Theme(const string &filename, const vector<string> &search_dirs, Resource
        register_class("ResizeEffect", ResizeEffect_funcs, RESIZE_EFFECT);
        register_class("MultiplyEffect", MultiplyEffect_funcs, MULTIPLY_EFFECT);
        register_class("MixEffect", MixEffect_funcs, MIX_EFFECT);
+       register_class("BlurEffect", BlurEffect_funcs, BLUR_EFFECT);
+       register_class("UnsharpMaskEffect", UnsharpMaskEffect_funcs, UNSHARP_MASK_EFFECT);
        register_class("LiftGammaGainEffect", LiftGammaGainEffect_funcs, LIFT_GAMMA_GAIN_EFFECT);
        register_class("InputStateInfo", InputStateInfo_funcs);
        register_class("ThemeMenu", ThemeMenu_funcs);
@@ -1582,6 +1637,7 @@ Theme::~Theme()
 {
        theme_menu.reset();
        lua_close(L);
+       // Leak the surface.
 }
 
 void Theme::register_globals()
@@ -1630,6 +1686,9 @@ void Theme::register_globals()
                { "get_audio_bus_mute", Nageru_get_audio_bus_mute },
                { "set_audio_bus_mute", Nageru_set_audio_bus_mute },
 
+               // Misc.
+               { "schedule_cut", Nageru_schedule_cut },
+
                { nullptr, nullptr }
        };
        lua_pushlightuserdata(L, this);
@@ -2044,8 +2103,8 @@ unique_ptr<Theme::MenuEntry> create_theme_menu_entry(lua_State *L, int index)
        lua_pop(L, 1);
 
        unsigned flags = 0;
-       if (lua_objlen(L, -1) > 2) {
-               lua_rawgeti(L, -1, 3);
+       if (lua_objlen(L, index) > 2) {
+               lua_rawgeti(L, index, 3);
                flags = luaL_checknumber(L, -1);
                lua_pop(L, 1);
        }