/*
* 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"
#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;
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);
ChromaKeyWindow::ChromaKeyWindow(ChromaKey *plugin)
- : PluginClientWindow(plugin,
- 320,
- 220,
- 320,
- 220,
+ : PluginClientWindow(plugin,
+ 320,
+ 220,
+ 320,
+ 220,
0)
{
this->plugin = plugin;
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();
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();
+}
+
-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..."))
{
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;
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;
return 1;
}
-
ChromaKeyUseValue::ChromaKeyUseValue(ChromaKey *plugin, int x, int y)
: BC_CheckBox(x, y, plugin->config.use_value, _("Use value"))
{
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"))
{
ChromaKeyColorThread::ChromaKeyColorThread(ChromaKey *plugin, ChromaKeyWindow *gui)
- : ColorThread(1, _("Inner color"))
+ : ColorPicker(1, _("Inner color"))
{
this->plugin = plugin;
this->gui = gui;
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()
{
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,
//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); \
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;
ChromaKey::ChromaKey(PluginServer *server)
: PluginVClient(server)
{
-
+
engine = 0;
}
ChromaKey::~ChromaKey()
{
-
+
delete engine;
}
this->input = frame;
this->output = frame;
- read_frame(frame,
- 0,
- start_position,
+ read_frame(frame,
+ 0,
+ start_position,
frame_rate,
get_use_opengl());
return 1;
}
-const char* ChromaKey::plugin_title() { return _("Chroma key"); }
+const char* ChromaKey::plugin_title() { return N_("Chroma key"); }
int ChromaKey::is_realtime() { return 1; }
NEW_WINDOW_MACRO(ChromaKey, ChromaKeyWindow)
void ChromaKey::save_data(KeyFrame *keyframe)
{
FileXML output;
- output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+ output.set_shared_output(keyframe->xbuf);
output.tag.set_title("CHROMAKEY");
output.tag.set_property("RED", config.red);
output.tag.set_property("GREEN", config.green);
{
FileXML input;
- input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+ input.set_shared_input(keyframe->xbuf);
while(!input.read_tag())
{
{
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 =
"{\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 =
" 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"
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