00001 #include "clip.h"
00002 #include "bchash.h"
00003 #include "denoisemjpeg.h"
00004 #include "filexml.h"
00005 #include "guicast.h"
00006 #include "keyframe.h"
00007 #include "picon_png.h"
00008 #include "vframe.h"
00009
00010
00011 #include <libintl.h>
00012 #define _(String) gettext(String)
00013 #define gettext_noop(String) String
00014 #define N_(String) gettext_noop (String)
00015
00016
00017
00018
00019 #include <stdint.h>
00020 #include <string.h>
00021
00022
00023
00024 REGISTER_PLUGIN(DenoiseMJPEG)
00025
00026
00027
00028
00029
00030
00031 DenoiseMJPEGConfig::DenoiseMJPEGConfig()
00032 {
00033 radius = 8;
00034 threshold = 5;
00035 threshold2 = 4;
00036 sharpness = 125;
00037 lcontrast = 100;
00038 ccontrast = 100;
00039 deinterlace = 0;
00040 mode = 0;
00041 delay = 3;
00042 }
00043
00044 int DenoiseMJPEGConfig::equivalent(DenoiseMJPEGConfig &that)
00045 {
00046 return
00047 that.radius == radius &&
00048 that.threshold == threshold &&
00049 that.threshold2 == threshold2 &&
00050 that.sharpness == sharpness &&
00051 that.lcontrast == lcontrast &&
00052 that.ccontrast == ccontrast &&
00053 that.deinterlace == deinterlace &&
00054 that.mode == mode &&
00055 that.delay == delay;
00056 }
00057
00058 void DenoiseMJPEGConfig::copy_from(DenoiseMJPEGConfig &that)
00059 {
00060 radius = that.radius;
00061 threshold = that.threshold;
00062 threshold2 = that.threshold2;
00063 sharpness = that.sharpness;
00064 lcontrast = that.lcontrast;
00065 ccontrast = that.ccontrast;
00066 deinterlace = that.deinterlace;
00067 mode = that.mode;
00068 delay = that.delay;
00069 }
00070
00071 void DenoiseMJPEGConfig::interpolate(DenoiseMJPEGConfig &prev,
00072 DenoiseMJPEGConfig &next,
00073 long prev_frame,
00074 long next_frame,
00075 long current_frame)
00076 {
00077 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
00078 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
00079
00080 this->radius = (int)(prev.radius * prev_scale + next.radius * next_scale);
00081 this->threshold = (int)(prev.threshold * prev_scale + next.threshold * next_scale);
00082 this->threshold2 = (int)(prev.threshold2 * prev_scale + next.threshold2 * next_scale);
00083 this->sharpness = (int)(prev.sharpness * prev_scale + next.sharpness * next_scale);
00084 this->lcontrast = (int)(prev.lcontrast * prev_scale + next.lcontrast * next_scale);
00085 this->ccontrast = (int)(prev.ccontrast * prev_scale + next.ccontrast * next_scale);
00086 this->deinterlace = prev.deinterlace;
00087 this->mode = prev.mode;
00088 this->delay = (int)(prev.delay * prev_scale + next.delay * next_scale);
00089 }
00090
00091
00092
00093
00094
00095
00096 DenoiseMJPEGRadius::DenoiseMJPEGRadius(DenoiseMJPEG *plugin, int x, int y)
00097 : BC_IPot(x,
00098 y,
00099 plugin->config.radius,
00100 8,
00101 24)
00102 {
00103 this->plugin = plugin;
00104 }
00105
00106 int DenoiseMJPEGRadius::handle_event()
00107 {
00108 int result = get_value();
00109 plugin->config.radius = result;
00110 plugin->send_configure_change();
00111 return 1;
00112 }
00113
00114
00115
00116
00117
00118
00119 DenoiseMJPEGThresh::DenoiseMJPEGThresh(DenoiseMJPEG *plugin, int x, int y)
00120 : BC_IPot(x,
00121 y,
00122 plugin->config.threshold,
00123 0,
00124 255)
00125 {
00126 this->plugin = plugin;
00127 }
00128
00129 int DenoiseMJPEGThresh::handle_event()
00130 {
00131 int result = get_value();
00132 plugin->config.threshold = result;
00133 plugin->send_configure_change();
00134 return 1;
00135 }
00136
00137
00138
00139
00140
00141
00142 DenoiseMJPEGThresh2::DenoiseMJPEGThresh2(DenoiseMJPEG *plugin, int x, int y)
00143 : BC_IPot(x,
00144 y,
00145 plugin->config.threshold2,
00146 0,
00147 255)
00148 {
00149 this->plugin = plugin;
00150 }
00151
00152 int DenoiseMJPEGThresh2::handle_event()
00153 {
00154 int result = get_value();
00155 plugin->config.threshold2 = result;
00156 plugin->send_configure_change();
00157 return 1;
00158 }
00159
00160
00161
00162
00163
00164
00165 DenoiseMJPEGSharp::DenoiseMJPEGSharp(DenoiseMJPEG *plugin, int x, int y)
00166 : BC_IPot(x,
00167 y,
00168 plugin->config.sharpness,
00169 0,
00170 255)
00171 {
00172 this->plugin = plugin;
00173 }
00174
00175 int DenoiseMJPEGSharp::handle_event()
00176 {
00177 int result = get_value();
00178 plugin->config.sharpness = result;
00179 plugin->send_configure_change();
00180 return 1;
00181 }
00182
00183
00184
00185
00186
00187
00188 DenoiseMJPEGLContrast::DenoiseMJPEGLContrast(DenoiseMJPEG *plugin, int x, int y)
00189 : BC_IPot(x,
00190 y,
00191 plugin->config.lcontrast,
00192 0,
00193 255)
00194 {
00195 this->plugin = plugin;
00196 }
00197
00198 int DenoiseMJPEGLContrast::handle_event()
00199 {
00200 int result = get_value();
00201 plugin->config.lcontrast = result;
00202 plugin->send_configure_change();
00203 return 1;
00204 }
00205
00206
00207
00208
00209
00210
00211 DenoiseMJPEGCContrast::DenoiseMJPEGCContrast(DenoiseMJPEG *plugin, int x, int y)
00212 : BC_IPot(x,
00213 y,
00214 plugin->config.ccontrast,
00215 0,
00216 255)
00217 {
00218 this->plugin = plugin;
00219 }
00220
00221 int DenoiseMJPEGCContrast::handle_event()
00222 {
00223 int result = get_value();
00224 plugin->config.ccontrast = result;
00225 plugin->send_configure_change();
00226 return 1;
00227 }
00228
00229
00230
00231
00232
00233
00234 DenoiseMJPEGDeinterlace::DenoiseMJPEGDeinterlace(DenoiseMJPEG *plugin, int x, int y)
00235 : BC_CheckBox(x,
00236 y,
00237 plugin->config.deinterlace,
00238 _("Deinterlace"))
00239 {
00240 this->plugin = plugin;
00241 }
00242
00243 int DenoiseMJPEGDeinterlace::handle_event()
00244 {
00245 int result = get_value();
00246 plugin->config.deinterlace = result;
00247 plugin->send_configure_change();
00248 return 1;
00249 }
00250
00251
00252
00253
00254
00255
00256 DenoiseMJPEGModeProgressive::DenoiseMJPEGModeProgressive(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
00257 : BC_Radial(x,
00258 y,
00259 plugin->config.mode == 0,
00260 _("Progressive"))
00261 {
00262 this->plugin = plugin;
00263 this->gui = gui;
00264 }
00265
00266 int DenoiseMJPEGModeProgressive::handle_event()
00267 {
00268 int result = get_value();
00269 if(result) gui->update_mode(0);
00270 plugin->send_configure_change();
00271 return 1;
00272 }
00273
00274
00275 DenoiseMJPEGModeInterlaced::DenoiseMJPEGModeInterlaced(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
00276 : BC_Radial(x,
00277 y,
00278 plugin->config.mode == 1,
00279 _("Interlaced"))
00280 {
00281 this->plugin = plugin;
00282 this->gui = gui;
00283 }
00284
00285 int DenoiseMJPEGModeInterlaced::handle_event()
00286 {
00287 int result = get_value();
00288 if(result) gui->update_mode(1);
00289 plugin->send_configure_change();
00290 return 1;
00291 }
00292
00293
00294 DenoiseMJPEGModeFast::DenoiseMJPEGModeFast(DenoiseMJPEG *plugin, DenoiseMJPEGWindow *gui, int x, int y)
00295 : BC_Radial(x,
00296 y,
00297 plugin->config.mode == 2,
00298 _("Fast"))
00299 {
00300 this->plugin = plugin;
00301 this->gui = gui;
00302 }
00303
00304 int DenoiseMJPEGModeFast::handle_event()
00305 {
00306 int result = get_value();
00307 if(result) gui->update_mode(2);
00308 plugin->send_configure_change();
00309 return 1;
00310 }
00311
00312
00313
00314
00315
00316
00317 DenoiseMJPEGDelay::DenoiseMJPEGDelay(DenoiseMJPEG *plugin, int x, int y)
00318 : BC_IPot(x,
00319 y,
00320 plugin->config.delay,
00321 1,
00322 8)
00323 {
00324 this->plugin = plugin;
00325 }
00326
00327 int DenoiseMJPEGDelay::handle_event()
00328 {
00329 int result = get_value();
00330 plugin->config.delay = result;
00331 plugin->send_configure_change();
00332 return 1;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 DenoiseMJPEGWindow::DenoiseMJPEGWindow(DenoiseMJPEG *plugin, int x, int y)
00346 : BC_Window(plugin->gui_string,
00347 x,
00348 y,
00349 250,
00350 350,
00351 250,
00352 350,
00353 0,
00354 0,
00355 1)
00356 {
00357 this->plugin = plugin;
00358 }
00359
00360
00361 void DenoiseMJPEGWindow::create_objects()
00362 {
00363 int x1 = 10, y1 = 20, x2 = 140, x3 = 180, y2 = 10, margin = 30, margin2 = 25;
00364 add_subwindow(new BC_Title(x1, y1, _("Search radius:")));
00365 add_subwindow(radius = new DenoiseMJPEGRadius(plugin, x2, y2));
00366 y1 += margin;
00367 y2 += margin;
00368 add_subwindow(new BC_Title(x1, y1, _("Pass 1 threshold:")));
00369 add_subwindow(threshold1 = new DenoiseMJPEGThresh(plugin, x3, y2));
00370 y1 += margin;
00371 y2 += margin;
00372 add_subwindow(new BC_Title(x1, y1, _("Pass 2 threshold:")));
00373 add_subwindow(threshold2 = new DenoiseMJPEGThresh2(plugin, x2, y2));
00374 y1 += margin;
00375 y2 += margin;
00376 add_subwindow(new BC_Title(x1, y1, _("Sharpness:")));
00377 add_subwindow(sharpness = new DenoiseMJPEGSharp(plugin, x3, y2));
00378 y1 += margin;
00379 y2 += margin;
00380 add_subwindow(new BC_Title(x1, y1, _("Luma contrast:")));
00381 add_subwindow(lcontrast = new DenoiseMJPEGLContrast(plugin, x2, y2));
00382 y1 += margin;
00383 y2 += margin;
00384 add_subwindow(new BC_Title(x1, y1, _("Chroma contrast:")));
00385 add_subwindow(ccontrast = new DenoiseMJPEGCContrast(plugin, x3, y2));
00386 y1 += margin;
00387 y2 += margin;
00388 add_subwindow(new BC_Title(x1, y1, _("Delay frames:")));
00389 add_subwindow(delay = new DenoiseMJPEGDelay(plugin, x2, y2));
00390 y1 += margin;
00391 y2 += margin;
00392 add_subwindow(new BC_Title(x1, y1, _("Mode:")));
00393 add_subwindow(interlaced = new DenoiseMJPEGModeInterlaced(plugin, this, x2, y1));
00394 y1 += margin2;
00395 y2 += margin2;
00396 add_subwindow(progressive = new DenoiseMJPEGModeProgressive(plugin, this, x2, y1));
00397 y1 += margin2;
00398 y2 += margin2;
00399 add_subwindow(fast = new DenoiseMJPEGModeFast(plugin, this, x2, y1));
00400 y1 += margin;
00401 y2 += margin;
00402 add_subwindow(deinterlace = new DenoiseMJPEGDeinterlace(plugin, x1, y1));
00403
00404 show_window();
00405 flush();
00406 }
00407
00408 void DenoiseMJPEGWindow::update_mode(int value)
00409 {
00410 plugin->config.mode = value;
00411 progressive->update(value == 0);
00412 interlaced->update(value == 1);
00413 fast->update(value == 2);
00414 }
00415
00416 int DenoiseMJPEGWindow::close_event()
00417 {
00418 set_done(1);
00419 return 1;
00420 }
00421
00422
00423
00424
00425
00426
00427 PLUGIN_THREAD_OBJECT(DenoiseMJPEG, DenoiseMJPEGThread, DenoiseMJPEGWindow)
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 DenoiseMJPEG::DenoiseMJPEG(PluginServer *server)
00440 : PluginVClient(server)
00441 {
00442 PLUGIN_CONSTRUCTOR_MACRO
00443 accumulation = 0;
00444 }
00445
00446
00447 DenoiseMJPEG::~DenoiseMJPEG()
00448 {
00449 PLUGIN_DESTRUCTOR_MACRO
00450
00451 if(accumulation) delete [] accumulation;
00452 }
00453
00454 int DenoiseMJPEG::process_realtime(VFrame *input, VFrame *output)
00455 {
00456 load_configuration();
00457
00458 }
00459
00460 char* DenoiseMJPEG::plugin_title() { return N_("Denoise video2"); }
00461 int DenoiseMJPEG::is_realtime() { return 1; }
00462
00463 VFrame* DenoiseMJPEG::new_picon()
00464 {
00465 return new VFrame(picon_png);
00466 }
00467
00468 SHOW_GUI_MACRO(DenoiseMJPEG, DenoiseMJPEGThread)
00469
00470 RAISE_WINDOW_MACRO(DenoiseMJPEG)
00471
00472 void DenoiseMJPEG::update_gui()
00473 {
00474 if(thread)
00475 {
00476 load_configuration();
00477 thread->window->lock_window();
00478 thread->window->delay->update(config.delay);
00479 thread->window->threshold1->update(config.threshold);
00480 thread->window->unlock_window();
00481 }
00482 }
00483
00484
00485
00486 SET_STRING_MACRO(DenoiseMJPEG);
00487
00488 LOAD_CONFIGURATION_MACRO(DenoiseMJPEG, DenoiseMJPEGConfig)
00489
00490 int DenoiseMJPEG::load_defaults()
00491 {
00492 char directory[BCTEXTLEN];
00493
00494 sprintf(directory, "%sdenoisevideo.rc", BCASTDIR);
00495
00496
00497 defaults = new BC_Hash(directory);
00498 defaults->load();
00499
00500 config.radius = defaults->get("RADIUS", config.radius);
00501 config.threshold = defaults->get("THRESHOLD", config.threshold);
00502 config.threshold2 = defaults->get("THRESHOLD2", config.threshold2);
00503 config.sharpness = defaults->get("SHARPNESS", config.sharpness);
00504 config.lcontrast = defaults->get("LCONTRAST", config.lcontrast);
00505 config.ccontrast = defaults->get("CCONTRAST", config.ccontrast);
00506 config.deinterlace = defaults->get("DEINTERLACE", config.deinterlace);
00507 config.mode = defaults->get("MODE", config.mode);
00508 config.delay = defaults->get("DELAY", config.delay);
00509 return 0;
00510 }
00511
00512 int DenoiseMJPEG::save_defaults()
00513 {
00514 defaults->update("RADIUS", config.radius);
00515 defaults->update("THRESHOLD", config.threshold);
00516 defaults->update("THRESHOLD2", config.threshold2);
00517 defaults->update("SHARPNESS", config.sharpness);
00518 defaults->update("LCONTRAST", config.lcontrast);
00519 defaults->update("CCONTRAST", config.ccontrast);
00520 defaults->update("DEINTERLACE", config.deinterlace);
00521 defaults->update("MODE", config.mode);
00522 defaults->update("DELAY", config.delay);
00523 defaults->save();
00524 return 0;
00525 }
00526
00527 void DenoiseMJPEG::save_data(KeyFrame *keyframe)
00528 {
00529 FileXML output;
00530
00531
00532 output.set_shared_string(keyframe->data, MESSAGESIZE);
00533 output.tag.set_title("DENOISE_VIDEO2");
00534 output.tag.set_property("RADIUS", config.radius);
00535 output.tag.set_property("THRESHOLD", config.threshold);
00536 output.tag.set_property("THRESHOLD2", config.threshold2);
00537 output.tag.set_property("SHARPNESS", config.sharpness);
00538 output.tag.set_property("LCONTRAST", config.lcontrast);
00539 output.tag.set_property("CCONTRAST", config.ccontrast);
00540 output.tag.set_property("DEINTERLACE", config.deinterlace);
00541 output.tag.set_property("MODE", config.mode);
00542 output.tag.set_property("DELAY", config.delay);
00543 output.append_tag();
00544 output.tag.set_title("/DENOISE_VIDEO2");
00545 output.append_tag();
00546 output.terminate_string();
00547 }
00548
00549 void DenoiseMJPEG::read_data(KeyFrame *keyframe)
00550 {
00551 FileXML input;
00552
00553 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00554
00555 int result = 0;
00556
00557 while(!input.read_tag())
00558 {
00559 if(input.tag.title_is("DENOISE_VIDEO2"))
00560 {
00561 config.radius = input.tag.get_property("RADIUS", config.radius);
00562 config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
00563 config.threshold2 = input.tag.get_property("THRESHOLD2", config.threshold2);
00564 config.sharpness = input.tag.get_property("SHARPNESS", config.sharpness);
00565 config.lcontrast = input.tag.get_property("LCONTRAST", config.lcontrast);
00566 config.ccontrast = input.tag.get_property("CCONTRAST", config.ccontrast);
00567 config.deinterlace = input.tag.get_property("DEINTERLACE", config.deinterlace);
00568 config.mode = input.tag.get_property("MODE", config.mode);
00569 config.delay = input.tag.get_property("DELAY", config.delay);
00570 }
00571 }
00572 }
00573
00574
00575
00576