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"
37 REGISTER_PLUGIN(DenoiseMJPEG)
41 DenoiseMJPEGConfig::DenoiseMJPEGConfig()
54 int DenoiseMJPEGConfig::equivalent(DenoiseMJPEGConfig &that)
57 that.radius == radius &&
58 that.threshold == threshold &&
59 that.threshold2 == threshold2 &&
60 that.sharpness == sharpness &&
61 that.lcontrast == lcontrast &&
62 that.ccontrast == ccontrast &&
63 that.deinterlace == deinterlace &&
68 void DenoiseMJPEGConfig::copy_from(DenoiseMJPEGConfig &that)
71 threshold = that.threshold;
72 threshold2 = that.threshold2;
73 sharpness = that.sharpness;
74 lcontrast = that.lcontrast;
75 ccontrast = that.ccontrast;
76 deinterlace = that.deinterlace;
81 void DenoiseMJPEGConfig::interpolate(DenoiseMJPEGConfig &prev,
82 DenoiseMJPEGConfig &next,
87 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
88 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
90 this->radius = (int)(prev.radius * prev_scale + next.radius * next_scale);
91 this->threshold = (int)(prev.threshold * prev_scale + next.threshold * next_scale);
92 this->threshold2 = (int)(prev.threshold2 * prev_scale + next.threshold2 * next_scale);
93 this->sharpness = (int)(prev.sharpness * prev_scale + next.sharpness * next_scale);
94 this->lcontrast = (int)(prev.lcontrast * prev_scale + next.lcontrast * next_scale);
95 this->ccontrast = (int)(prev.ccontrast * prev_scale + next.ccontrast * next_scale);
96 this->deinterlace = prev.deinterlace;
97 this->mode = prev.mode;
98 this->delay = (int)(prev.delay * prev_scale + next.delay * next_scale);
106 DenoiseMJPEGRadius::DenoiseMJPEGRadius(DenoiseMJPEG *plugin, int x, int y)
109 plugin->config.radius,
113 this->plugin = plugin;
116 int DenoiseMJPEGRadius::handle_event()
118 int result = get_value();
119 plugin->config.radius = result;
120 plugin->send_configure_change();
129 DenoiseMJPEGThresh::DenoiseMJPEGThresh(DenoiseMJPEG *plugin, int x, int y)
132 plugin->config.threshold,
136 this->plugin = plugin;
139 int DenoiseMJPEGThresh::handle_event()
141 int result = get_value();
142 plugin->config.threshold = result;
143 plugin->send_configure_change();
152 DenoiseMJPEGThresh2::DenoiseMJPEGThresh2(DenoiseMJPEG *plugin, int x, int y)
155 plugin->config.threshold2,
159 this->plugin = plugin;
162 int DenoiseMJPEGThresh2::handle_event()
164 int result = get_value();
165 plugin->config.threshold2 = result;
166 plugin->send_configure_change();
175 DenoiseMJPEGSharp::DenoiseMJPEGSharp(DenoiseMJPEG *plugin, int x, int y)
178 plugin->config.sharpness,
182 this->plugin = plugin;
185 int DenoiseMJPEGSharp::handle_event()
187 int result = get_value();
188 plugin->config.sharpness = result;
189 plugin->send_configure_change();
198 DenoiseMJPEGLContrast::DenoiseMJPEGLContrast(DenoiseMJPEG *plugin, int x, int y)
201 plugin->config.lcontrast,
205 this->plugin = plugin;
208 int DenoiseMJPEGLContrast::handle_event()
210 int result = get_value();
211 plugin->config.lcontrast = result;
212 plugin->send_configure_change();
221 DenoiseMJPEGCContrast::DenoiseMJPEGCContrast(DenoiseMJPEG *plugin, int x, int y)
224 plugin->config.ccontrast,
228 this->plugin = plugin;
231 int DenoiseMJPEGCContrast::handle_event()
233 int result = get_value();
234 plugin->config.ccontrast = result;
235 plugin->send_configure_change();
244 DenoiseMJPEGDeinterlace::DenoiseMJPEGDeinterlace(DenoiseMJPEG *plugin, int x, int y)
247 plugin->config.deinterlace,
250 this->plugin = plugin;
253 int DenoiseMJPEGDeinterlace::handle_event()
255 int result = get_value();
256 plugin->config.deinterlace = result;
257 plugin->send_configure_change();
266 DenoiseMJPEGModeProgressive::DenoiseMJPEGModeProgressive(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
269 plugin->config.mode == 0,
272 this->plugin = plugin;
276 int DenoiseMJPEGModeProgressive::handle_event()
278 int result = get_value();
279 if(result) gui->update_mode(0);
280 plugin->send_configure_change();
285 DenoiseMJPEGModeInterlaced::DenoiseMJPEGModeInterlaced(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
288 plugin->config.mode == 1,
291 this->plugin = plugin;
295 int DenoiseMJPEGModeInterlaced::handle_event()
297 int result = get_value();
298 if(result) gui->update_mode(1);
299 plugin->send_configure_change();
304 DenoiseMJPEGModeFast::DenoiseMJPEGModeFast(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
307 plugin->config.mode == 2,
310 this->plugin = plugin;
314 int DenoiseMJPEGModeFast::handle_event()
316 int result = get_value();
317 if(result) gui->update_mode(2);
318 plugin->send_configure_change();
327 DenoiseMJPEGDelay::DenoiseMJPEGDelay(DenoiseMJPEG *plugin, int x, int y)
330 plugin->config.delay,
334 this->plugin = plugin;
337 int DenoiseMJPEGDelay::handle_event()
339 int result = get_value();
340 plugin->config.delay = result;
341 plugin->send_configure_change();
355 DenoiseMJPEGWindow::DenoiseMJPEGWindow(DenoiseMJPEG *plugin)
356 : PluginClientWindow(plugin, xS(250), yS(350), 0, 0, 1)
358 this->plugin = plugin;
362 void DenoiseMJPEGWindow::create_objects()
364 int xs10 = xS(10), xs25 = xS(25), xs30 = xS(30), xs140 = xS(140), xs180 = xS(180);
365 int ys10 = yS(10), ys20 = yS(20);
366 int x1 = xs10, y1 = ys20, x2 = xs140, x3 = xs180, y2 = ys10, margin = xs30, margin2 = xs25;
367 add_subwindow(new BC_Title(x1, y1, _("Search radius:")));
368 add_subwindow(radius = new DenoiseMJPEGRadius(plugin, x2, y2));
371 add_subwindow(new BC_Title(x1, y1, _("Pass 1 threshold:")));
372 add_subwindow(threshold1 = new DenoiseMJPEGThresh(plugin, x3, y2));
375 add_subwindow(new BC_Title(x1, y1, _("Pass 2 threshold:")));
376 add_subwindow(threshold2 = new DenoiseMJPEGThresh2(plugin, x2, y2));
379 add_subwindow(new BC_Title(x1, y1, _("Sharpness:")));
380 add_subwindow(sharpness = new DenoiseMJPEGSharp(plugin, x3, y2));
383 add_subwindow(new BC_Title(x1, y1, _("Luma contrast:")));
384 add_subwindow(lcontrast = new DenoiseMJPEGLContrast(plugin, x2, y2));
387 add_subwindow(new BC_Title(x1, y1, _("Chroma contrast:")));
388 add_subwindow(ccontrast = new DenoiseMJPEGCContrast(plugin, x3, y2));
391 add_subwindow(new BC_Title(x1, y1, _("Delay frames:")));
392 add_subwindow(delay = new DenoiseMJPEGDelay(plugin, x2, y2));
395 add_subwindow(new BC_Title(x1, y1, _("Mode:")));
396 add_subwindow(interlaced = new DenoiseMJPEGModeInterlaced(plugin, this, x2, y1));
399 add_subwindow(progressive = new DenoiseMJPEGModeProgressive(plugin, this, x2, y1));
402 add_subwindow(fast = new DenoiseMJPEGModeFast(plugin, this, x2, y1));
405 add_subwindow(deinterlace = new DenoiseMJPEGDeinterlace(plugin, x1, y1));
411 void DenoiseMJPEGWindow::update_mode(int value)
413 plugin->config.mode = value;
414 progressive->update(value == 0);
415 interlaced->update(value == 1);
416 fast->update(value == 2);
419 int DenoiseMJPEGWindow::close_event()
428 DenoiseMJPEG::DenoiseMJPEG(PluginServer *server)
429 : PluginVClient(server)
436 DenoiseMJPEG::~DenoiseMJPEG()
440 if(accumulation) delete [] accumulation;
443 int DenoiseMJPEG::process_realtime(VFrame *input, VFrame *output)
445 load_configuration();
449 const char* DenoiseMJPEG::plugin_title() { return N_("Denoise video2"); }
450 int DenoiseMJPEG::is_realtime() { return 1; }
452 void DenoiseMJPEG::update_gui()
456 load_configuration();
457 DenoiseMJPEGWindow *window = (DenoiseMJPEGWindow *)thread->window;
458 window->lock_window();
459 window->delay->update(config.delay);
460 window->threshold1->update(config.threshold);
461 window->unlock_window();
466 NEW_WINDOW_MACRO(DenoiseMJPEG, DenoiseMJPEGWindow)
467 LOAD_CONFIGURATION_MACRO(DenoiseMJPEG, DenoiseMJPEGConfig)
470 void DenoiseMJPEG::save_data(KeyFrame *keyframe)
474 // cause data to be stored directly in text
475 output.set_shared_output(keyframe->xbuf);
476 output.tag.set_title("DENOISE_VIDEO2");
477 output.tag.set_property("RADIUS", config.radius);
478 output.tag.set_property("THRESHOLD", config.threshold);
479 output.tag.set_property("THRESHOLD2", config.threshold2);
480 output.tag.set_property("SHARPNESS", config.sharpness);
481 output.tag.set_property("LCONTRAST", config.lcontrast);
482 output.tag.set_property("CCONTRAST", config.ccontrast);
483 output.tag.set_property("DEINTERLACE", config.deinterlace);
484 output.tag.set_property("MODE", config.mode);
485 output.tag.set_property("DELAY", config.delay);
487 output.tag.set_title("/DENOISE_VIDEO2");
489 output.append_newline();
490 output.terminate_string();
493 void DenoiseMJPEG::read_data(KeyFrame *keyframe)
497 input.set_shared_input(keyframe->xbuf);
499 while(!input.read_tag())
501 if(input.tag.title_is("DENOISE_VIDEO2"))
503 config.radius = input.tag.get_property("RADIUS", config.radius);
504 config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
505 config.threshold2 = input.tag.get_property("THRESHOLD2", config.threshold2);
506 config.sharpness = input.tag.get_property("SHARPNESS", config.sharpness);
507 config.lcontrast = input.tag.get_property("LCONTRAST", config.lcontrast);
508 config.ccontrast = input.tag.get_property("CCONTRAST", config.ccontrast);
509 config.deinterlace = input.tag.get_property("DEINTERLACE", config.deinterlace);
510 config.mode = input.tag.get_property("MODE", config.mode);
511 config.delay = input.tag.get_property("DELAY", config.delay);