opengl dot() fix, add file dates, sort file name/time, fix icon image lookup, sync...
[goodguy/history.git] / cinelerra-5.1 / plugins / chromakey / chromakey.C
index adc1528c839ddabf54a10235a57d199f758c1520..fe52fec66e0601302ada2b326646100ddab20857 100644 (file)
@@ -2,23 +2,24 @@
 /*
  * CINELERRA
  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
 
+#include "bccolors.h"
 #include "bcdisplayinfo.h"
 #include "bcsignals.h"
 #include "chromakey.h"
@@ -30,7 +31,7 @@
 #include "language.h"
 #include "loadbalance.h"
 #include "playback3d.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "vframe.h"
 
 
 
 
+ChromaKeyConfig::ChromaKeyConfig()
+{
+       reset();
+}
 
+void ChromaKeyConfig::reset()
 
-ChromaKeyConfig::ChromaKeyConfig()
 {
        red = 0.0;
        green = 0.0;
@@ -72,10 +77,10 @@ int ChromaKeyConfig::equivalent(ChromaKeyConfig &src)
                use_value == src.use_value);
 }
 
-void ChromaKeyConfig::interpolate(ChromaKeyConfig &prev, 
-       ChromaKeyConfig &next, 
-       int64_t prev_frame, 
-       int64_t next_frame, 
+void ChromaKeyConfig::interpolate(ChromaKeyConfig &prev,
+       ChromaKeyConfig &next,
+       int64_t prev_frame,
+       int64_t next_frame,
        int64_t current_frame)
 {
        double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
@@ -104,11 +109,11 @@ int ChromaKeyConfig::get_color()
 
 
 ChromaKeyWindow::ChromaKeyWindow(ChromaKey *plugin)
- : PluginClientWindow(plugin, 
-       320, 
-       220, 
-       320, 
-       220, 
+ : PluginClientWindow(plugin,
+       320,
+       220,
+       320,
+       220,
        0)
 {
        this->plugin = plugin;
@@ -147,6 +152,9 @@ void ChromaKeyWindow::create_objects()
        y += 30;
        add_subwindow(use_colorpicker = new ChromaKeyUseColorPicker(plugin, this, x1, y));
 
+       y += use_colorpicker->get_h() + 10;
+       add_subwindow(new ChromaKeyReset(plugin, this, x, y));
+
        color_thread = new ChromaKeyColorThread(plugin, this);
 
        update_sample();
@@ -157,18 +165,23 @@ void ChromaKeyWindow::create_objects()
 void ChromaKeyWindow::update_sample()
 {
        sample->set_color(plugin->config.get_color());
-       sample->draw_box(0, 
-               0, 
-               sample->get_w(), 
+       sample->draw_box(0,
+               0,
+               sample->get_w(),
                sample->get_h());
        sample->set_color(BLACK);
-       sample->draw_rectangle(0, 
-               0, 
-               sample->get_w(), 
+       sample->draw_rectangle(0,
+               0,
+               sample->get_w(),
                sample->get_h());
        sample->flash();
 }
 
+void ChromaKeyWindow::done_event(int result)
+{
+       color_thread->close_window();
+}
+
 
 
 
@@ -177,11 +190,11 @@ void ChromaKeyWindow::update_sample()
 
 
 
-ChromaKeyColor::ChromaKeyColor(ChromaKey *plugin, 
-       ChromaKeyWindow *gui, 
-       int x, 
+ChromaKeyColor::ChromaKeyColor(ChromaKey *plugin,
+       ChromaKeyWindow *gui,
+       int x,
        int y)
- : BC_GenericButton(x, 
+ : BC_GenericButton(x,
        y,
        _("Color..."))
 {
@@ -200,13 +213,13 @@ int ChromaKeyColor::handle_event()
 
 
 ChromaKeyThreshold::ChromaKeyThreshold(ChromaKey *plugin, int x, int y)
- : BC_FSlider(x, 
+ : BC_FSlider(x,
                        y,
                        0,
-                       200, 
-                       200, 
-                       (float)0, 
-                       (float)100, 
+                       200,
+                       200,
+                       (float)0,
+                       (float)100,
                        plugin->config.threshold)
 {
        this->plugin = plugin;
@@ -221,13 +234,13 @@ int ChromaKeyThreshold::handle_event()
 
 
 ChromaKeySlope::ChromaKeySlope(ChromaKey *plugin, int x, int y)
- : BC_FSlider(x, 
+ : BC_FSlider(x,
                        y,
                        0,
-                       200, 
-                       200, 
-                       (float)0, 
-                       (float)100, 
+                       200,
+                       200,
+                       (float)0,
+                       (float)100,
                        plugin->config.slope)
 {
        this->plugin = plugin;
@@ -241,7 +254,6 @@ int ChromaKeySlope::handle_event()
        return 1;
 }
 
-
 ChromaKeyUseValue::ChromaKeyUseValue(ChromaKey *plugin, int x, int y)
  : BC_CheckBox(x, y, plugin->config.use_value, _("Use value"))
 {
@@ -254,10 +266,24 @@ int ChromaKeyUseValue::handle_event()
        return 1;
 }
 
+ChromaKeyReset::ChromaKeyReset(ChromaKey *plugin, ChromaKeyWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Reset"))
+{
+       this->plugin = plugin;
+       this->gui = gui;
+}
+
+int ChromaKeyReset::handle_event()
+{
+       plugin->config.reset();
+       gui->update_gui();
+       plugin->send_configure_change();
+       return 1;
+}
 
-ChromaKeyUseColorPicker::ChromaKeyUseColorPicker(ChromaKey *plugin, 
+ChromaKeyUseColorPicker::ChromaKeyUseColorPicker(ChromaKey *plugin,
        ChromaKeyWindow *gui,
-       int x, 
+       int x,
        int y)
  : BC_GenericButton(x, y, _("Use color picker"))
 {
@@ -279,7 +305,7 @@ int ChromaKeyUseColorPicker::handle_event()
 
 
 ChromaKeyColorThread::ChromaKeyColorThread(ChromaKey *plugin, ChromaKeyWindow *gui)
- : ColorThread(1, _("Inner color"))
+ : ColorPicker(1, _("Inner color"))
 {
        this->plugin = plugin;
        this->gui = gui;
@@ -317,7 +343,7 @@ void ChromaKeyServer::init_packages()
                pkg->y1 = plugin->input->get_h() * i / get_total_packages();
                pkg->y2 = plugin->input->get_h() * (i + 1) / get_total_packages();
        }
-       
+
 }
 LoadClient* ChromaKeyServer::new_client()
 {
@@ -349,7 +375,7 @@ void ChromaKeyUnit::process_package(LoadPackage *package)
        int w = plugin->input->get_w();
 
        float h, s, v;
-       HSV::rgb_to_hsv(plugin->config.red, 
+       HSV::rgb_to_hsv(plugin->config.red,
                plugin->config.green,
                plugin->config.blue,
                h,
@@ -359,12 +385,9 @@ void ChromaKeyUnit::process_package(LoadPackage *package)
        //float max_hue = h + plugin->config.threshold * 360 / 100;
 
 
-#define RGB_TO_VALUE(r, g, b) \
-((r) * R_TO_Y + (g) * G_TO_Y + (b) * B_TO_Y)
-
+#define RGB_TO_VALUE(r, g, b) YUV::yuv.rgb_to_y_f((r),(g),(b))
 
 #define OUTER_VARIABLES(plugin) \
-       YUV yuv; \
        float value = RGB_TO_VALUE(plugin->config.red, \
                plugin->config.green, \
                plugin->config.blue); \
@@ -375,7 +398,9 @@ void ChromaKeyUnit::process_package(LoadPackage *package)
        float g_key = plugin->config.green; \
        float b_key = plugin->config.blue; \
        int y_key, u_key, v_key; \
-       yuv.rgb_to_yuv_8((int)(r_key * 0xff), (int)(g_key * 0xff), (int)(b_key * 0xff), y_key, u_key, v_key); \
+       YUV::yuv.rgb_to_yuv_8( \
+               (int)(r_key * 0xff), (int)(g_key * 0xff), (int)(b_key * 0xff), \
+               y_key, u_key, v_key); \
        float run = plugin->config.slope / 100; \
        float threshold_run = threshold + run;
 
@@ -528,13 +553,13 @@ REGISTER_PLUGIN(ChromaKey)
 ChromaKey::ChromaKey(PluginServer *server)
  : PluginVClient(server)
 {
-       
+
        engine = 0;
 }
 
 ChromaKey::~ChromaKey()
 {
-       
+
        delete engine;
 }
 
@@ -549,9 +574,9 @@ SET_TRACE
        this->input = frame;
        this->output = frame;
 
-       read_frame(frame, 
-               0, 
-               start_position, 
+       read_frame(frame,
+               0,
+               start_position,
                frame_rate,
                get_use_opengl());
 
@@ -625,20 +650,25 @@ void ChromaKey::update_gui()
        {
                load_configuration();
                thread->window->lock_window();
-               ((ChromaKeyWindow*)thread->window)->threshold->update(config.threshold);
-               ((ChromaKeyWindow*)thread->window)->slope->update(config.slope);
-               ((ChromaKeyWindow*)thread->window)->use_value->update(config.use_value);
-               ((ChromaKeyWindow*)thread->window)->update_sample();
-
+               ((ChromaKeyWindow *)(thread->window))->update_gui();
                thread->window->unlock_window();
        }
 }
 
+void ChromaKeyWindow::update_gui()
+{
+       ChromaKeyConfig &config = plugin->config;
+       threshold->update(config.threshold);
+       slope->update(config.slope);
+       use_value->update(config.use_value);
+       update_sample();
+}
+
 int ChromaKey::handle_opengl()
 {
 #ifdef HAVE_GL
        OUTER_VARIABLES(this)
-       
+
 
 
        static const char *uniform_frag =
@@ -655,11 +685,13 @@ int ChromaKey::handle_opengl()
                "{\n"
                "       return abs(color.r);\n"
                "}\n";
-               
-       static const char *get_rgbvalue_frag = 
+
+       static const char *get_rgbvalue_frag =
+               "uniform vec3 rgb_to_y_vector;\n"
+               "uniform float yminf;\n"
                "float get_value(vec4 color)\n"
                "{\n"
-               "       return dot(color.rgb, vec3(0.29900, 0.58700, 0.11400));\n"
+               "       return dot(color.rgb, rgb_to_y_vector) + yminf;\n"
                "}\n";
 
        static const char *value_frag =
@@ -684,7 +716,7 @@ int ChromaKey::handle_opengl()
                "       gl_FragColor = vec4(color.rgb, alpha);\n"
                "}\n";
 
-       static const char *cube_frag = 
+       static const char *cube_frag =
                "void main()\n"
                "{\n"
                "       vec4 color = texture2D(tex, gl_TexCoord[0].st);\n"
@@ -703,64 +735,56 @@ int ChromaKey::handle_opengl()
        get_output()->to_texture();
        get_output()->enable_opengl();
        get_output()->init_screen();
-       const char *shader_stack[] = { 0, 0, 0, 0, 0 };
-       int current_shader = 0;
 
+        const char *shader_stack[16];
+        memset(shader_stack,0, sizeof(shader_stack));
+        int current_shader = 0;
        shader_stack[current_shader++] = uniform_frag;
-       switch(get_output()->get_color_model())
-       {
-               case BC_YUV888:
-               case BC_YUVA8888:
-                       if(config.use_value)
-                       {
-                               shader_stack[current_shader++] = get_yuvvalue_frag;
-                               shader_stack[current_shader++] = value_frag;
-                       }
-                       else
-                       {
-                               shader_stack[current_shader++] = cube_frag;
-                       }
-                       break;
 
-               default:
-                       if(config.use_value)
-                       {
-                               shader_stack[current_shader++] = get_rgbvalue_frag;
-                               shader_stack[current_shader++] = value_frag;
-                       }
-                       else
-                       {
-                               shader_stack[current_shader++] = cube_frag;
-                       }
-                       break;
+       switch(get_output()->get_color_model()) {
+       case BC_YUV888:
+       case BC_YUVA8888:
+               if( config.use_value ) {
+                       shader_stack[current_shader++] = get_yuvvalue_frag;
+                       shader_stack[current_shader++] = value_frag;
+               }
+               else {
+                       shader_stack[current_shader++] = cube_frag;
+               }
+               break;
+
+       default:
+               if(config.use_value) {
+                       shader_stack[current_shader++] = get_rgbvalue_frag;
+                       shader_stack[current_shader++] = value_frag;
+               }
+               else {
+                       shader_stack[current_shader++] = cube_frag;
+               }
+               break;
        }
 SET_TRACE
 
-       unsigned int frag = VFrame::make_shader(0, 
-               shader_stack[0], 
-               shader_stack[1], 
-               shader_stack[2], 
-               shader_stack[3], 
-               0);
-       get_output()->bind_texture(0);
-
-       if(frag)
-       {
-               glUseProgram(frag);
-               glUniform1i(glGetUniformLocation(frag, "tex"), 0);
-               glUniform1f(glGetUniformLocation(frag, "min_v"), min_v);
-               glUniform1f(glGetUniformLocation(frag, "max_v"), max_v);
-               glUniform1f(glGetUniformLocation(frag, "run"), run);
-               glUniform1f(glGetUniformLocation(frag, "threshold"), threshold);
-               glUniform1f(glGetUniformLocation(frag, "threshold_run"), threshold_run);
+       shader_stack[current_shader] = 0;
+       unsigned int shader = VFrame::make_shader(shader_stack);
+       if( shader > 0 ) {
+               get_output()->bind_texture(0);
+               glUseProgram(shader);
+               glUniform1i(glGetUniformLocation(shader, "tex"), 0);
+               glUniform1f(glGetUniformLocation(shader, "min_v"), min_v);
+               glUniform1f(glGetUniformLocation(shader, "max_v"), max_v);
+               glUniform1f(glGetUniformLocation(shader, "run"), run);
+               glUniform1f(glGetUniformLocation(shader, "threshold"), threshold);
+               glUniform1f(glGetUniformLocation(shader, "threshold_run"), threshold_run);
                if(get_output()->get_color_model() != BC_YUV888 &&
                        get_output()->get_color_model() != BC_YUVA8888)
-                       glUniform3f(glGetUniformLocation(frag, "key"), 
+                       glUniform3f(glGetUniformLocation(shader, "key"),
                                r_key, g_key, b_key);
                else
-                       glUniform3f(glGetUniformLocation(frag, "key"), 
+                       glUniform3f(glGetUniformLocation(shader, "key"),
                                (float)y_key / 0xff, (float)u_key / 0xff, (float)v_key / 0xff);
-               
+               if(config.use_value)
+                       BC_GL_RGB_TO_Y(shader);
        }
 SET_TRACE