case IDENTITY_EFFECT:
return new IdentityEffect;
case WHITE_BALANCE_EFFECT:
+ case AUTO_WHITE_BALANCE_EFFECT:
return new WhiteBalanceEffect;
case RESAMPLE_EFFECT:
return new ResampleEffect;
return 1;
}
+int InputStateInfo_get_frame_height(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));
+ unsigned height = input_state_info->last_height[signal_num];
+ if (input_state_info->last_interlaced[signal_num]) {
+ height *= 2;
+ }
+ lua_pushnumber(L, height);
+ return 1;
+}
+
int InputStateInfo_get_interlaced(lua_State* L)
{
assert(lua_gettop(L) == 2);
string str;
if (!input_state_info->last_is_connected[signal_num]) {
str = "disconnected";
- } else if (input_state_info->last_height[signal_num]) {
+ } else if (input_state_info->last_height[signal_num] <= 0) {
str = "no signal";
} else if (!input_state_info->last_has_signal[signal_num]) {
- if (input_state_info->last_height[signal_num]) {
+ if (input_state_info->last_height[signal_num] == 525) {
// Special mode for the USB3 cards.
str = "no signal";
} else {
{ "new", Scene_new },
{ "__gc", Scene_gc },
{ "add_input", Scene::add_input },
+ { "add_auto_white_balance", Scene::add_auto_white_balance },
{ "add_effect", Scene::add_effect },
{ "add_optional_effect", Scene::add_optional_effect },
{ "finalize", Scene::finalize },
{ "enable_if", Block_enable_if },
{ "disable", Block_disable },
{ "always_disable_if_disabled", Block_always_disable_if_disabled },
+ { "promise_to_disable_if_enabled", Block_promise_to_disable_if_enabled },
{ "set_int", Block_set_int },
{ "set_float", Block_set_float },
{ "set_vec3", Block_set_vec3 },
const luaL_Reg InputStateInfo_funcs[] = {
{ "get_width", InputStateInfo_get_width },
{ "get_height", InputStateInfo_get_height },
+ { "get_frame_width", InputStateInfo_get_width }, // Same as get_width().
+ { "get_frame_height", InputStateInfo_get_frame_height },
{ "get_interlaced", InputStateInfo_get_interlaced },
{ "get_has_signal", InputStateInfo_get_has_signal },
{ "get_is_connected", InputStateInfo_get_is_connected },
Theme::Theme(const string &filename, const vector<string> &search_dirs, ResourcePool *resource_pool, unsigned num_cards)
: resource_pool(resource_pool), num_cards(num_cards), signal_to_card_mapping(global_flags.default_stream_mapping)
{
+ // Defaults.
+ channel_names[0] = "Live";
+ channel_names[1] = "Preview";
+
L = luaL_newstate();
luaL_openlibs(L);
const vector<pair<string, int>> num_constants = {
{ "VIDEO_FORMAT_BGRA", bmusb::PixelFormat_8BitBGRA },
{ "VIDEO_FORMAT_YCBCR", bmusb::PixelFormat_8BitYCbCrPlanar },
+ { "CHECKABLE", MenuEntry::CHECKABLE },
+ { "CHECKED", MenuEntry::CHECKED },
};
const vector<pair<string, string>> str_constants = {
{ "THEME_PATH", theme_path },
{
lock_guard<mutex> lock(m);
+ // We never ask the legacy channel_name() about live and preview.
+ // The defaults are set in our constructor.
+ if (channel == 0 || channel == 1) {
+ return channel_names[channel];
+ }
+
lua_getglobal(L, "channel_name");
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
return ret;
}
-void Theme::set_wb(unsigned channel, double r, double g, double b)
+void Theme::set_wb(unsigned channel, float r, float g, float b)
+{
+ int signal = get_channel_signal(channel);
+
+ lock_guard<mutex> lock(m);
+ if (signal != -1) {
+ white_balance_for_signal[signal] = 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)
{
lock_guard<mutex> lock(m);
+ white_balance_for_signal[signal] = RGBTriplet{ r, g, b };
+
+ for (const auto &channel_and_signal : channel_signals) {
+ if (channel_and_signal.second == signal) {
+ call_lua_wb_callback(channel_and_signal.first, r, g, b);
+ }
+ }
+}
+
+void Theme::call_lua_wb_callback(unsigned channel, float r, float g, float b)
+{
lua_getglobal(L, "set_wb");
+ if (lua_isnil(L, -1)) {
+ // The function doesn't exist, to just ignore. We've stored the white balance,
+ // and most likely, it will be picked up by auto white balance instead.
+ lua_pop(L, 1);
+ return;
+ }
lua_pushnumber(L, channel);
lua_pushnumber(L, r);
lua_pushnumber(L, g);
assert(lua_gettop(L) == 0);
}
+RGBTriplet Theme::get_white_balance_for_signal(int signal)
+{
+ if (white_balance_for_signal.count(signal)) {
+ return white_balance_for_signal[signal];
+ } else {
+ return RGBTriplet{ 1.0, 1.0, 1.0 };
+ }
+}
+
vector<string> Theme::get_transition_names(float t)
{
lock_guard<mutex> lock(m);
Theme::MenuEntry::~MenuEntry()
{
if (is_submenu) {
- luaL_unref(entry.L, LUA_REGISTRYINDEX, entry.lua_ref);
- } else {
destroy(submenu);
+ } else {
+ luaL_unref(entry.L, LUA_REGISTRYINDEX, entry.lua_ref);
}
}
const string text = checkstdstring(L, -1);
lua_pop(L, 1);
+ unsigned flags = 0;
+ if (lua_objlen(L, -1) > 2) {
+ lua_rawgeti(L, -1, 3);
+ flags = luaL_checknumber(L, -1);
+ lua_pop(L, 1);
+ }
+
lua_rawgeti(L, index, 2);
if (lua_istable(L, -1)) {
vector<unique_ptr<Theme::MenuEntry>> submenu = create_recursive_theme_menu(L);
} else {
luaL_checktype(L, -1, LUA_TFUNCTION);
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
- entry.reset(new Theme::MenuEntry{ text, L, ref });
+ entry.reset(new Theme::MenuEntry{ text, L, ref, flags });
}
return entry;
}
for (int i = 1; i <= num_elements; ++i) {
root_menu.emplace_back(create_theme_menu_entry(L, i));
}
- fprintf(stderr, "now creating a new one\n");
theme_menu.reset(new MenuEntry("", move(root_menu)));
- fprintf(stderr, "DONE reset\n");
lua_pop(L, num_elements);
assert(lua_gettop(L) == 0);
abort();
}
}
+
+string Theme::format_status_line(const string &disk_space_left_text, double file_length_seconds)
+{
+ lock_guard<mutex> lock(m);
+ lua_getglobal(L, "format_status_line");
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1);
+ return disk_space_left_text;
+ }
+
+ lua_pushstring(L, disk_space_left_text.c_str());
+ lua_pushnumber(L, file_length_seconds);
+ if (lua_pcall(L, 2, 1, 0) != 0) {
+ fprintf(stderr, "error running function format_status_line(): %s\n", lua_tostring(L, -1));
+ abort();
+ }
+ string text = checkstdstring(L, 1);
+ lua_pop(L, 1);
+ assert(lua_gettop(L) == 0);
+ return text;
+}