X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fchromakeyhsv%2Fchromakey.C;h=b96b172a4707aeb92819ab080b2359f3100ec341;hb=a88121d876acc81c5a28dbd2cc71e7c6856e2ac0;hp=3541143cd180204f883e03aac90a68027c3f5289;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C index 3541143c..b96b172a 100644 --- a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C +++ b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C @@ -2,21 +2,21 @@ /* * CINELERRA * Copyright (C) 2012 Adam Williams - * + * * 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 "bcdisplayinfo.h" @@ -30,7 +30,7 @@ #include "language.h" #include "loadbalance.h" #include "playback3d.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "vframe.h" @@ -41,6 +41,12 @@ ChromaKeyConfig::ChromaKeyConfig () +{ + reset(); +} + +void ChromaKeyConfig::reset() + { red = 0.0; green = 1.0; @@ -149,11 +155,11 @@ ChromaKeyConfig::get_color () ChromaKeyWindow::ChromaKeyWindow (ChromaKeyHSV * plugin) - : PluginClientWindow(plugin, - 400, - 450, - 400, - 450, + : PluginClientWindow(plugin, + 400, + 450, + 400, + 450, 0) { this->plugin = plugin; @@ -187,6 +193,8 @@ ChromaKeyWindow::create_objects () add_subwindow (use_colorpicker = new ChromaKeyUseColorPicker (plugin, this, x, y)); y += use_colorpicker->get_h() + 10; + + add_subwindow (new ChromaKeyReset (plugin, this, x2+240, y)); add_subwindow (show_mask = new ChromaKeyShowMask (plugin, x2, y)); y += show_mask->get_h() + 5; @@ -287,6 +295,10 @@ ChromaKeyWindow::update_sample () sample->flash (); } +void ChromaKeyWindow::done_event(int result) +{ + color_thread->close_window(); +} ChromaKeyColor::ChromaKeyColor (ChromaKeyHSV * plugin, @@ -461,6 +473,21 @@ ChromaKeyShowMask::handle_event () return 1; } +ChromaKeyReset::ChromaKeyReset (ChromaKeyHSV *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 (ChromaKeyHSV * plugin, ChromaKeyWindow * gui, int x, int y) : BC_GenericButton (x, y, _ @@ -525,7 +552,7 @@ ChromaKeySpillAmount::handle_event () ChromaKeyColorThread::ChromaKeyColorThread (ChromaKeyHSV * plugin, ChromaKeyWindow * gui) - : ColorThread (1, _("Inner color")) + : ColorPicker (1, _("Inner color")) { this->plugin = plugin; this->gui = gui; @@ -643,12 +670,12 @@ ChromaKeyUnit::ChromaKeyUnit (ChromaKeyHSV * plugin, ChromaKeyServer * server):L value_key); -template -void ChromaKeyUnit::process_chromakey(int components, - component_type max, - bool use_yuv, - ChromaKeyPackage *pkg) -{ +template +void ChromaKeyUnit::process_chromakey(int components, + component_type max, + bool use_yuv, + ChromaKeyPackage *pkg) +{ OUTER_VARIABLES int w = plugin->input->get_w(); @@ -659,51 +686,45 @@ void ChromaKeyUnit::process_chromakey(int components, for (int j = 0; j < w; j++) { - float a = 1; - - float r = (float) row[0] / max; - float g = (float) row[1] / max; - float b = (float) row[2] / max; + float r, g, b, a = 1; + if (!use_yuv) { + r = (float) row[0] / max; + g = (float) row[1] / max; + b = (float) row[2] / max; + } + else + YUV::yuv.yuv_to_rgb_f (r, g, b, row[0], row[1], row[2]); float h, s, v; float av = 1, ah = 1, as = 1, avm = 1; bool has_match = true; - if (use_yuv) - { -/* Convert pixel to RGB float */ - float y = r; - float u = g; - float v = b; - YUV::yuv_to_rgb_f (r, g, b, y, u - 0.5, v - 0.5); - } - HSV::rgb_to_hsv (r, g, b, h, s, v); // First, test if the hue is in range /* Hue wrap */ if(h <= hue_key - tolerance_in * 180.0) - h += 360; + h += 360.0; else if(h >= hue_key + tolerance_in * 180.0) - h -= 360; + h -= 360.0; if (tolerance == 0) ah = 1.0; - else + else if (ABS (h - hue_key) < tolerance_in * 180) ah = 0; - else + else if ((out_slope != 0) && (ABS (h - hue_key) < tolerance * 180)) /* we scale alpha between 0 and 1/2 */ - ah = ABS (h - hue_key) / tolerance / 360; - else + ah = ABS (h - hue_key) / tolerance / 360; + else if (ABS (h - hue_key) < tolerance_out * 180) /* we scale alpha between 1/2 and 1 */ - ah = ABS (h - hue_key) / tolerance_out / 360; + ah = ABS (h - hue_key) / tolerance_out / 360; else has_match = false; @@ -756,7 +777,7 @@ void ChromaKeyUnit::process_chromakey(int components, if (has_match) a = MAX (MAX (ah, av), MAX (as, avm)); - // Spill light processing + // Spill light processing if ((ABS (h - hue_key) < spill_threshold * 180) || ((ABS (h - hue_key) > 360) && (ABS (h - hue_key) - 360 < spill_threshold * 180))) @@ -765,29 +786,14 @@ void ChromaKeyUnit::process_chromakey(int components, HSV::hsv_to_rgb (r, g, b, h, s, v); - if (use_yuv) - { - float y; - float u; - float v; - YUV::rgb_to_yuv_f (r, g, b, y, u, v); - CLAMP (y, 0, 1.0); - CLAMP (u, 0, 1.0); - CLAMP (v, 0, 1.0); - row[0] = (component_type) ((float) y * max); - row[1] = (component_type) ((float) (u + 0.5) * max); - row[2] = (component_type) ((float) (v + 0.5) * max); + if (!use_yuv) { + row[0] = (component_type) ((float) r * max); + row[1] = (component_type) ((float) g * max); + row[2] = (component_type) ((float) b * max); } - else - { - CLAMP (r, 0, 1.0); - CLAMP (g, 0, 1.0); - CLAMP (b, 0, 1.0); - row[0] = (component_type) ((float) r * max); - row[1] = (component_type) ((float) g * max); - row[2] = (component_type) ((float) b * max); - } - } + else + YUV::yuv.rgb_to_yuv_f(r, g, b, row[0], row[1], row[2]); + } a += alpha_offset; CLAMP (a, 0.0, 1.0); @@ -885,13 +891,13 @@ REGISTER_PLUGIN(ChromaKeyHSV) ChromaKeyHSV::ChromaKeyHSV(PluginServer *server) : PluginVClient(server) { - + engine = 0; } ChromaKeyHSV::~ChromaKeyHSV() { - + if(engine) delete engine; } @@ -905,9 +911,9 @@ int ChromaKeyHSV::process_buffer(VFrame *frame, this->output = frame; - read_frame(frame, - 0, - start_position, + read_frame(frame, + 0, + start_position, frame_rate, get_use_opengl()); if(get_use_opengl()) return run_opengl(); @@ -999,22 +1005,27 @@ void ChromaKeyHSV::update_gui() load_configuration(); ChromaKeyWindow *window = (ChromaKeyWindow*)thread->window; window->lock_window(); - window->min_brightness->update(config.min_brightness); - window->max_brightness->update(config.max_brightness); - window->saturation->update(config.saturation); - window->min_saturation->update(config.min_saturation); - window->tolerance->update(config.tolerance); - window->in_slope->update(config.in_slope); - window->out_slope->update(config.out_slope); - window->alpha_offset->update(config.alpha_offset); - window->spill_threshold->update(config.spill_threshold); - window->spill_amount->update(config.spill_amount); - window->show_mask->update(config.show_mask); - window->update_sample(); + window->update_gui(); window->unlock_window(); } } +void ChromaKeyWindow::update_gui() +{ + ChromaKeyConfig &config = plugin->config; + min_brightness->update(config.min_brightness); + max_brightness->update(config.max_brightness); + saturation->update(config.saturation); + min_saturation->update(config.min_saturation); + tolerance->update(config.tolerance); + in_slope->update(config.in_slope); + out_slope->update(config.out_slope); + alpha_offset->update(config.alpha_offset); + spill_threshold->update(config.spill_threshold); + spill_amount->update(config.spill_amount); + show_mask->update(config.show_mask); + update_sample(); +} @@ -1025,22 +1036,27 @@ int ChromaKeyHSV::handle_opengl() ChromaKeyHSV *plugin = this; OUTER_VARIABLES - static const char *yuv_shader = + static const char *yuv_shader = "const vec3 black = vec3(0.0, 0.5, 0.5);\n" + "uniform mat3 yuv_to_rgb_matrix;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "\n" "vec4 yuv_to_rgb(vec4 color)\n" "{\n" - YUV_TO_RGB_FRAG("color") + " color.rgb -= vec3(yminf, 0.5, 0.5);\n" + " color.rgb = yuv_to_rgb_matrix * color.rgb;\n" " return color;\n" "}\n" "\n" "vec4 rgb_to_yuv(vec4 color)\n" "{\n" - RGB_TO_YUV_FRAG("color") + " color.rgb = rgb_to_yuv_matrix * color.rgb;\n" + " color.rgb += vec3(yminf, 0.5, 0.5);\n" " return color;\n" "}\n"; - static const char *rgb_shader = + static const char *rgb_shader = "const vec3 black = vec3(0.0, 0.0, 0.0);\n" "\n" "vec4 yuv_to_rgb(vec4 color)\n" @@ -1052,7 +1068,7 @@ int ChromaKeyHSV::handle_opengl() " return color;\n" "}\n"; - static const char *hsv_shader = + static const char *hsv_shader = "vec4 rgb_to_hsv(vec4 color)\n" "{\n" RGB_TO_HSV_FRAG("color") @@ -1066,96 +1082,76 @@ int ChromaKeyHSV::handle_opengl() "}\n" "\n"; - static const char *show_rgbmask_shader = + static const char *show_rgbmask_shader = "vec4 show_mask(vec4 color, vec4 color2)\n" "{\n" " return vec4(1.0, 1.0, 1.0, min(color.a, color2.a));" "}\n"; - static const char *show_yuvmask_shader = + static const char *show_yuvmask_shader = "vec4 show_mask(vec4 color, vec4 color2)\n" "{\n" " return vec4(1.0, 0.5, 0.5, min(color.a, color2.a));" "}\n"; - static const char *nomask_shader = + static const char *nomask_shader = "vec4 show_mask(vec4 color, vec4 color2)\n" "{\n" " return vec4(color.rgb, min(color.a, color2.a));" "}\n"; - extern unsigned char _binary_chromakey_sl_start[]; - static const char *shader = (char*)_binary_chromakey_sl_start; - get_output()->to_texture(); get_output()->enable_opengl(); get_output()->init_screen(); - const char* shader_stack[] = { 0, 0, 0, 0, 0 }; - - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - shader_stack[0] = yuv_shader; - shader_stack[1] = hsv_shader; - if(config.show_mask) - shader_stack[2] = show_yuvmask_shader; - else - shader_stack[2] = nomask_shader; - shader_stack[3] = shader; - break; - - default: - shader_stack[0] = rgb_shader; - shader_stack[1] = hsv_shader; - if(config.show_mask) - shader_stack[2] = show_rgbmask_shader; - else - shader_stack[2] = nomask_shader; - shader_stack[3] = shader; - break; - } - - - unsigned int frag = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - 0); - - if(frag) - { - glUseProgram(frag); - glUniform1i(glGetUniformLocation(frag, "tex"), 0); - glUniform1f(glGetUniformLocation(frag, "red"), red); - glUniform1f(glGetUniformLocation(frag, "green"), green); - glUniform1f(glGetUniformLocation(frag, "blue"), blue); - glUniform1f(glGetUniformLocation(frag, "in_slope"), in_slope); - glUniform1f(glGetUniformLocation(frag, "out_slope"), out_slope); - glUniform1f(glGetUniformLocation(frag, "tolerance"), tolerance); - glUniform1f(glGetUniformLocation(frag, "tolerance_in"), tolerance_in); - glUniform1f(glGetUniformLocation(frag, "tolerance_out"), tolerance_out); - glUniform1f(glGetUniformLocation(frag, "sat"), sat); - glUniform1f(glGetUniformLocation(frag, "min_s"), min_s); - glUniform1f(glGetUniformLocation(frag, "min_s_in"), min_s_in); - glUniform1f(glGetUniformLocation(frag, "min_s_out"), min_s_out); - glUniform1f(glGetUniformLocation(frag, "min_v"), min_v); - glUniform1f(glGetUniformLocation(frag, "min_v_in"), min_v_in); - glUniform1f(glGetUniformLocation(frag, "min_v_out"), min_v_out); - glUniform1f(glGetUniformLocation(frag, "max_v"), max_v); - glUniform1f(glGetUniformLocation(frag, "max_v_in"), max_v_in); - glUniform1f(glGetUniformLocation(frag, "max_v_out"), max_v_out); - glUniform1f(glGetUniformLocation(frag, "spill_threshold"), spill_threshold); - glUniform1f(glGetUniformLocation(frag, "spill_amount"), spill_amount); - glUniform1f(glGetUniformLocation(frag, "alpha_offset"), alpha_offset); - glUniform1f(glGetUniformLocation(frag, "hue_key"), hue_key); - glUniform1f(glGetUniformLocation(frag, "saturation_key"), saturation_key); - glUniform1f(glGetUniformLocation(frag, "value_key"), value_key); + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + shader_stack[current_shader++] = \ + !BC_CModels::is_yuv(get_output()->get_color_model()) ? + rgb_shader : yuv_shader; + shader_stack[current_shader++] = hsv_shader; + shader_stack[current_shader++] = !config.show_mask ? nomask_shader : + !BC_CModels::is_yuv(get_output()->get_color_model()) ? + show_rgbmask_shader : show_yuvmask_shader ; + extern unsigned char _binary_chromakey_sl_start[]; + static const char *shader_frag = (char*)_binary_chromakey_sl_start; + shader_stack[current_shader++] = shader_frag; + + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); + if( shader > 0 ) { + glUseProgram(shader); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + glUniform1f(glGetUniformLocation(shader, "red"), red); + glUniform1f(glGetUniformLocation(shader, "green"), green); + glUniform1f(glGetUniformLocation(shader, "blue"), blue); + glUniform1f(glGetUniformLocation(shader, "in_slope"), in_slope); + glUniform1f(glGetUniformLocation(shader, "out_slope"), out_slope); + glUniform1f(glGetUniformLocation(shader, "tolerance"), tolerance); + glUniform1f(glGetUniformLocation(shader, "tolerance_in"), tolerance_in); + glUniform1f(glGetUniformLocation(shader, "tolerance_out"), tolerance_out); + glUniform1f(glGetUniformLocation(shader, "sat"), sat); + glUniform1f(glGetUniformLocation(shader, "min_s"), min_s); + glUniform1f(glGetUniformLocation(shader, "min_s_in"), min_s_in); + glUniform1f(glGetUniformLocation(shader, "min_s_out"), min_s_out); + glUniform1f(glGetUniformLocation(shader, "min_v"), min_v); + glUniform1f(glGetUniformLocation(shader, "min_v_in"), min_v_in); + glUniform1f(glGetUniformLocation(shader, "min_v_out"), min_v_out); + glUniform1f(glGetUniformLocation(shader, "max_v"), max_v); + glUniform1f(glGetUniformLocation(shader, "max_v_in"), max_v_in); + glUniform1f(glGetUniformLocation(shader, "max_v_out"), max_v_out); + glUniform1f(glGetUniformLocation(shader, "spill_threshold"), spill_threshold); + glUniform1f(glGetUniformLocation(shader, "spill_amount"), spill_amount); + glUniform1f(glGetUniformLocation(shader, "alpha_offset"), alpha_offset); + glUniform1f(glGetUniformLocation(shader, "hue_key"), hue_key); + glUniform1f(glGetUniformLocation(shader, "saturation_key"), saturation_key); + glUniform1f(glGetUniformLocation(shader, "value_key"), value_key); + if( BC_CModels::is_yuv(get_output()->get_color_model()) ) + BC_GL_COLORS(shader); } - get_output()->bind_texture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);