4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "denoisemjpeg.h"
32 #define _(String) gettext(String)
33 #define gettext_noop(String) String
34 #define N_(String) gettext_noop (String)
44 REGISTER_PLUGIN(DenoiseMJPEG)
48 DenoiseMJPEGConfig::DenoiseMJPEGConfig()
61 int DenoiseMJPEGConfig::equivalent(DenoiseMJPEGConfig &that)
64 that.radius == radius &&
65 that.threshold == threshold &&
66 that.threshold2 == threshold2 &&
67 that.sharpness == sharpness &&
68 that.lcontrast == lcontrast &&
69 that.ccontrast == ccontrast &&
70 that.deinterlace == deinterlace &&
75 void DenoiseMJPEGConfig::copy_from(DenoiseMJPEGConfig &that)
78 threshold = that.threshold;
79 threshold2 = that.threshold2;
80 sharpness = that.sharpness;
81 lcontrast = that.lcontrast;
82 ccontrast = that.ccontrast;
83 deinterlace = that.deinterlace;
88 void DenoiseMJPEGConfig::interpolate(DenoiseMJPEGConfig &prev,
89 DenoiseMJPEGConfig &next,
94 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
95 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
97 this->radius = (int)(prev.radius * prev_scale + next.radius * next_scale);
98 this->threshold = (int)(prev.threshold * prev_scale + next.threshold * next_scale);
99 this->threshold2 = (int)(prev.threshold2 * prev_scale + next.threshold2 * next_scale);
100 this->sharpness = (int)(prev.sharpness * prev_scale + next.sharpness * next_scale);
101 this->lcontrast = (int)(prev.lcontrast * prev_scale + next.lcontrast * next_scale);
102 this->ccontrast = (int)(prev.ccontrast * prev_scale + next.ccontrast * next_scale);
103 this->deinterlace = prev.deinterlace;
104 this->mode = prev.mode;
105 this->delay = (int)(prev.delay * prev_scale + next.delay * next_scale);
113 DenoiseMJPEGRadius::DenoiseMJPEGRadius(DenoiseMJPEG *plugin, int x, int y)
116 plugin->config.radius,
120 this->plugin = plugin;
123 int DenoiseMJPEGRadius::handle_event()
125 int result = get_value();
126 plugin->config.radius = result;
127 plugin->send_configure_change();
136 DenoiseMJPEGThresh::DenoiseMJPEGThresh(DenoiseMJPEG *plugin, int x, int y)
139 plugin->config.threshold,
143 this->plugin = plugin;
146 int DenoiseMJPEGThresh::handle_event()
148 int result = get_value();
149 plugin->config.threshold = result;
150 plugin->send_configure_change();
159 DenoiseMJPEGThresh2::DenoiseMJPEGThresh2(DenoiseMJPEG *plugin, int x, int y)
162 plugin->config.threshold2,
166 this->plugin = plugin;
169 int DenoiseMJPEGThresh2::handle_event()
171 int result = get_value();
172 plugin->config.threshold2 = result;
173 plugin->send_configure_change();
182 DenoiseMJPEGSharp::DenoiseMJPEGSharp(DenoiseMJPEG *plugin, int x, int y)
185 plugin->config.sharpness,
189 this->plugin = plugin;
192 int DenoiseMJPEGSharp::handle_event()
194 int result = get_value();
195 plugin->config.sharpness = result;
196 plugin->send_configure_change();
205 DenoiseMJPEGLContrast::DenoiseMJPEGLContrast(DenoiseMJPEG *plugin, int x, int y)
208 plugin->config.lcontrast,
212 this->plugin = plugin;
215 int DenoiseMJPEGLContrast::handle_event()
217 int result = get_value();
218 plugin->config.lcontrast = result;
219 plugin->send_configure_change();
228 DenoiseMJPEGCContrast::DenoiseMJPEGCContrast(DenoiseMJPEG *plugin, int x, int y)
231 plugin->config.ccontrast,
235 this->plugin = plugin;
238 int DenoiseMJPEGCContrast::handle_event()
240 int result = get_value();
241 plugin->config.ccontrast = result;
242 plugin->send_configure_change();
251 DenoiseMJPEGDeinterlace::DenoiseMJPEGDeinterlace(DenoiseMJPEG *plugin, int x, int y)
254 plugin->config.deinterlace,
257 this->plugin = plugin;
260 int DenoiseMJPEGDeinterlace::handle_event()
262 int result = get_value();
263 plugin->config.deinterlace = result;
264 plugin->send_configure_change();
273 DenoiseMJPEGModeProgressive::DenoiseMJPEGModeProgressive(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
276 plugin->config.mode == 0,
279 this->plugin = plugin;
283 int DenoiseMJPEGModeProgressive::handle_event()
285 int result = get_value();
286 if(result) gui->update_mode(0);
287 plugin->send_configure_change();
292 DenoiseMJPEGModeInterlaced::DenoiseMJPEGModeInterlaced(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
295 plugin->config.mode == 1,
298 this->plugin = plugin;
302 int DenoiseMJPEGModeInterlaced::handle_event()
304 int result = get_value();
305 if(result) gui->update_mode(1);
306 plugin->send_configure_change();
311 DenoiseMJPEGModeFast::DenoiseMJPEGModeFast(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
314 plugin->config.mode == 2,
317 this->plugin = plugin;
321 int DenoiseMJPEGModeFast::handle_event()
323 int result = get_value();
324 if(result) gui->update_mode(2);
325 plugin->send_configure_change();
334 DenoiseMJPEGDelay::DenoiseMJPEGDelay(DenoiseMJPEG *plugin, int x, int y)
337 plugin->config.delay,
341 this->plugin = plugin;
344 int DenoiseMJPEGDelay::handle_event()
346 int result = get_value();
347 plugin->config.delay = result;
348 plugin->send_configure_change();
362 DenoiseMJPEGWindow::DenoiseMJPEGWindow(DenoiseMJPEG *plugin)
363 : PluginClientWindow(plugin, 250, 350, 0, 0, 1)
365 this->plugin = plugin;
369 void DenoiseMJPEGWindow::create_objects()
371 int x1 = 10, y1 = 20, x2 = 140, x3 = 180, y2 = 10, margin = 30, margin2 = 25;
372 add_subwindow(new BC_Title(x1, y1, _("Search radius:")));
373 add_subwindow(radius = new DenoiseMJPEGRadius(plugin, x2, y2));
376 add_subwindow(new BC_Title(x1, y1, _("Pass 1 threshold:")));
377 add_subwindow(threshold1 = new DenoiseMJPEGThresh(plugin, x3, y2));
380 add_subwindow(new BC_Title(x1, y1, _("Pass 2 threshold:")));
381 add_subwindow(threshold2 = new DenoiseMJPEGThresh2(plugin, x2, y2));
384 add_subwindow(new BC_Title(x1, y1, _("Sharpness:")));
385 add_subwindow(sharpness = new DenoiseMJPEGSharp(plugin, x3, y2));
388 add_subwindow(new BC_Title(x1, y1, _("Luma contrast:")));
389 add_subwindow(lcontrast = new DenoiseMJPEGLContrast(plugin, x2, y2));
392 add_subwindow(new BC_Title(x1, y1, _("Chroma contrast:")));
393 add_subwindow(ccontrast = new DenoiseMJPEGCContrast(plugin, x3, y2));
396 add_subwindow(new BC_Title(x1, y1, _("Delay frames:")));
397 add_subwindow(delay = new DenoiseMJPEGDelay(plugin, x2, y2));
400 add_subwindow(new BC_Title(x1, y1, _("Mode:")));
401 add_subwindow(interlaced = new DenoiseMJPEGModeInterlaced(plugin, this, x2, y1));
404 add_subwindow(progressive = new DenoiseMJPEGModeProgressive(plugin, this, x2, y1));
407 add_subwindow(fast = new DenoiseMJPEGModeFast(plugin, this, x2, y1));
410 add_subwindow(deinterlace = new DenoiseMJPEGDeinterlace(plugin, x1, y1));
416 void DenoiseMJPEGWindow::update_mode(int value)
418 plugin->config.mode = value;
419 progressive->update(value == 0);
420 interlaced->update(value == 1);
421 fast->update(value == 2);
424 int DenoiseMJPEGWindow::close_event()
433 DenoiseMJPEG::DenoiseMJPEG(PluginServer *server)
434 : PluginVClient(server)
441 DenoiseMJPEG::~DenoiseMJPEG()
445 if(accumulation) delete [] accumulation;
448 int DenoiseMJPEG::process_realtime(VFrame *input, VFrame *output)
450 load_configuration();
454 const char* DenoiseMJPEG::plugin_title() { return N_("Denoise video2"); }
455 int DenoiseMJPEG::is_realtime() { return 1; }
457 void DenoiseMJPEG::update_gui()
461 load_configuration();
462 DenoiseMJPEGWindow *window = (DenoiseMJPEGWindow *)thread->window;
463 window->lock_window();
464 window->delay->update(config.delay);
465 window->threshold1->update(config.threshold);
466 window->unlock_window();
471 NEW_WINDOW_MACRO(DenoiseMJPEG, DenoiseMJPEGWindow)
472 LOAD_CONFIGURATION_MACRO(DenoiseMJPEG, DenoiseMJPEGConfig)
475 void DenoiseMJPEG::save_data(KeyFrame *keyframe)
479 // cause data to be stored directly in text
480 output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
481 output.tag.set_title("DENOISE_VIDEO2");
482 output.tag.set_property("RADIUS", config.radius);
483 output.tag.set_property("THRESHOLD", config.threshold);
484 output.tag.set_property("THRESHOLD2", config.threshold2);
485 output.tag.set_property("SHARPNESS", config.sharpness);
486 output.tag.set_property("LCONTRAST", config.lcontrast);
487 output.tag.set_property("CCONTRAST", config.ccontrast);
488 output.tag.set_property("DEINTERLACE", config.deinterlace);
489 output.tag.set_property("MODE", config.mode);
490 output.tag.set_property("DELAY", config.delay);
492 output.terminate_string();
495 void DenoiseMJPEG::read_data(KeyFrame *keyframe)
499 input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
501 while(!input.read_tag())
503 if(input.tag.title_is("DENOISE_VIDEO2"))
505 config.radius = input.tag.get_property("RADIUS", config.radius);
506 config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
507 config.threshold2 = input.tag.get_property("THRESHOLD2", config.threshold2);
508 config.sharpness = input.tag.get_property("SHARPNESS", config.sharpness);
509 config.lcontrast = input.tag.get_property("LCONTRAST", config.lcontrast);
510 config.ccontrast = input.tag.get_property("CCONTRAST", config.ccontrast);
511 config.deinterlace = input.tag.get_property("DEINTERLACE", config.deinterlace);
512 config.mode = input.tag.get_property("MODE", config.mode);
513 config.delay = input.tag.get_property("DELAY", config.delay);