00001 #include "clip.h"
00002 #include "colormodels.h"
00003 #include "effecttv.h"
00004 #include "filexml.h"
00005 #include "holo.h"
00006 #include "holowindow.h"
00007 #include "language.h"
00008 #include "picon_png.h"
00009 #include "plugincolors.h"
00010
00011 #include <stdint.h>
00012 #include <stdio.h>
00013 #include <string.h>
00014
00015
00016 REGISTER_PLUGIN(HoloMain)
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 HoloConfig::HoloConfig()
00028 {
00029 threshold = 40;
00030 recycle = 1.0;
00031 }
00032
00033
00034
00035
00036
00037 HoloMain::HoloMain(PluginServer *server)
00038 : PluginVClient(server)
00039 {
00040 effecttv = 0;
00041 bgimage = 0;
00042 do_reconfigure = 1;
00043 yuv = new YUV;
00044 PLUGIN_CONSTRUCTOR_MACRO
00045 }
00046
00047 HoloMain::~HoloMain()
00048 {
00049 PLUGIN_DESTRUCTOR_MACRO
00050
00051
00052 if(effecttv)
00053 {
00054 delete holo_server;
00055 delete effecttv;
00056 }
00057
00058 if(bgimage)
00059 delete bgimage;
00060 delete yuv;
00061 }
00062
00063 char* HoloMain::plugin_title() { return N_("HolographicTV"); }
00064 int HoloMain::is_realtime() { return 1; }
00065
00066 VFrame* HoloMain::new_picon()
00067 {
00068 return new VFrame(picon_png);
00069 }
00070
00071 int HoloMain::load_defaults()
00072 {
00073 return 0;
00074 }
00075
00076 int HoloMain::save_defaults()
00077 {
00078 return 0;
00079 }
00080
00081 void HoloMain::load_configuration()
00082 {
00083 }
00084
00085
00086 void HoloMain::save_data(KeyFrame *keyframe)
00087 {
00088 }
00089
00090 void HoloMain::read_data(KeyFrame *keyframe)
00091 {
00092 }
00093
00094 void HoloMain::reconfigure()
00095 {
00096 do_reconfigure = 0;
00097
00098 effecttv->image_set_threshold_y(config.threshold);
00099 }
00100
00101
00102 #define ADD_FRAMES(type, components) \
00103 { \
00104 type **input_rows = (type**)input->get_rows(); \
00105 type **output_rows = (type**)output->get_rows(); \
00106 int w = input->get_w(); \
00107 int h = input->get_h(); \
00108 \
00109 for(int i = 0; i < h; i++) \
00110 { \
00111 type *output_row = (type*)output_rows[i]; \
00112 type *input_row = (type*)input_rows[i]; \
00113 \
00114 for(int j = 0; j < w; j++) \
00115 { \
00116 for(int k = 0; k < 3; k++) \
00117 { \
00118 if(sizeof(type) == 4) \
00119 { \
00120 int in_temp = (int)(*input_row * 0xffff); \
00121 int out_temp = (int)(*output_row * 0xffff); \
00122 int temp = (in_temp & out_temp) + \
00123 ((in_temp ^ out_temp) >> 1); \
00124 *output_row = (type)temp / 0xffff; \
00125 } \
00126 else \
00127 { \
00128 *output_row = ((uint16_t)*input_row & (uint16_t)*output_row) + \
00129 (((uint16_t)*input_row ^ (uint16_t)*output_row) >> 1); \
00130 } \
00131 output_row++; \
00132 input_row++; \
00133 } \
00134 \
00135 if(components == 4) \
00136 { \
00137 output_row++; \
00138 input_row++; \
00139 } \
00140 } \
00141 } \
00142 }
00143
00144
00145
00146 void HoloMain::add_frames(VFrame *output, VFrame *input)
00147 {
00148 switch(output->get_color_model())
00149 {
00150 case BC_RGB888:
00151 case BC_YUV888:
00152 ADD_FRAMES(uint8_t, 3);
00153 break;
00154 case BC_RGB_FLOAT:
00155 ADD_FRAMES(float, 3);
00156 break;
00157 case BC_RGBA_FLOAT:
00158 ADD_FRAMES(float, 4);
00159 break;
00160 case BC_RGBA8888:
00161 case BC_YUVA8888:
00162 ADD_FRAMES(uint8_t, 4);
00163 break;
00164 case BC_RGB161616:
00165 case BC_YUV161616:
00166 ADD_FRAMES(uint16_t, 3);
00167 break;
00168 case BC_RGBA16161616:
00169 case BC_YUVA16161616:
00170 ADD_FRAMES(uint16_t, 4);
00171 break;
00172 }
00173 }
00174
00175 void HoloMain::set_background()
00176 {
00177
00178
00179
00184 total = 0;
00185
00186 switch(total)
00187 {
00188 case 0:
00189
00190
00191
00192
00193
00194 bgimage->copy_from(input_ptr);
00195 break;
00196
00197 case 1:
00198
00199 add_frames(bgimage, input_ptr);
00200 break;
00201
00202 case 2:
00203
00204 tmp->copy_from(input_ptr);
00205 break;
00206
00207 case 3:
00208
00209 add_frames(tmp, input_ptr);
00210
00211
00212
00213
00214 add_frames(bgimage, tmp);
00215
00216 effecttv->image_bgset_y(bgimage);
00217
00218
00219 delete tmp;
00220 break;
00221 }
00222 }
00223
00224
00225 int HoloMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
00226 {
00227 this->input_ptr = input_ptr;
00228 this->output_ptr = output_ptr;
00229
00230
00231
00232
00233 load_configuration();
00234
00235
00236
00237 if(do_reconfigure)
00238 {
00239 if(!effecttv)
00240 {
00241 effecttv = new EffectTV(input_ptr->get_w(), input_ptr->get_h());
00242 bgimage = new VFrame(0,
00243 input_ptr->get_w(),
00244 input_ptr->get_h(),
00245 input_ptr->get_color_model());
00246
00247 for(int i = 0; i < 256; i++)
00248 {
00249 noisepattern[i] = (i * i * i / 40000)* i / 256;
00250 }
00251
00252 holo_server = new HoloServer(this, 1, 1);
00253 }
00254
00255 reconfigure();
00256 }
00257
00258 set_background();
00259
00260 holo_server->process_packages();
00261
00262 total++;
00263 if(total >= config.recycle * project_frame_rate)
00264 total = 0;
00265
00266 return 0;
00267 }
00268
00269 int HoloMain::show_gui()
00270 {
00271 load_configuration();
00272 thread = new HoloThread(this);
00273 thread->start();
00274 return 0;
00275 }
00276
00277 int HoloMain::set_string()
00278 {
00279 if(thread) thread->window->set_title(gui_string);
00280 return 0;
00281 }
00282
00283 void HoloMain::raise_window()
00284 {
00285 if(thread)
00286 {
00287 thread->window->raise_window();
00288 thread->window->flush();
00289 }
00290 }
00291
00292
00293
00294
00295 HoloServer::HoloServer(HoloMain *plugin, int total_clients, int total_packages)
00296 : LoadServer(total_clients, total_packages)
00297 {
00298 this->plugin = plugin;
00299 }
00300
00301
00302 LoadClient* HoloServer::new_client()
00303 {
00304 return new HoloClient(this);
00305 }
00306
00307
00308
00309
00310 LoadPackage* HoloServer::new_package()
00311 {
00312 return new HoloPackage;
00313 }
00314
00315
00316
00317 void HoloServer::init_packages()
00318 {
00319 for(int i = 0; i < get_total_packages(); i++)
00320 {
00321 HoloPackage *package = (HoloPackage*)get_package(i);
00322 package->row1 = plugin->input_ptr->get_h() * i / get_total_packages();
00323 package->row2 = plugin->input_ptr->get_h() * (i + 1) / get_total_packages();
00324 }
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334 HoloClient::HoloClient(HoloServer *server)
00335 : LoadClient(server)
00336 {
00337 this->plugin = server->plugin;
00338 phase = 0;
00339 }
00340
00341
00342 void HoloClient::process_package(LoadPackage *package)
00343 {
00344 int x, y;
00345 int sx, sy;
00346 HoloPackage *local_package = (HoloPackage*)package;
00347 unsigned char **input_rows = plugin->input_ptr->get_rows() + local_package->row1;
00348 unsigned char **output_rows = plugin->output_ptr->get_rows() + local_package->row1;
00349 int width = plugin->input_ptr->get_w();
00350 int height = local_package->row2 - local_package->row1;
00351 unsigned char *diff;
00352 uint32_t s, t;
00353 int r, g, b;
00354
00355 diff = plugin->effecttv->image_diff_filter(plugin->effecttv->image_bgsubtract_y(input_rows,
00356 plugin->input_ptr->get_color_model()));
00357
00358 diff += width;
00359 output_rows++;
00360 input_rows++;
00361
00362
00363
00364 #define STORE_PIXEL(type, components, dest, src, is_yuv) \
00365 if(sizeof(type) == 4) \
00366 { \
00367 int r = (int)(src[0] * 0xff); \
00368 int g = (int)(src[1] * 0xff); \
00369 int b = (int)(src[2] * 0xff); \
00370 CLAMP(r, 0, 0xff); \
00371 CLAMP(g, 0, 0xff); \
00372 CLAMP(b, 0, 0xff); \
00373 dest = (r << 16) | (g << 8) | b; \
00374 } \
00375 else \
00376 if(sizeof(type) == 2) \
00377 { \
00378 if(is_yuv) \
00379 { \
00380 int r = (int)src[0] >> 8; \
00381 int g = (int)src[1] >> 8; \
00382 int b = (int)src[2] >> 8; \
00383 plugin->yuv->yuv_to_rgb_8(r, g, b); \
00384 dest = (r << 16) | (g << 8) | b; \
00385 } \
00386 else \
00387 { \
00388 dest = (((uint32_t)src[0] << 8) & 0xff0000) | \
00389 ((uint32_t)src[1] & 0xff00) | \
00390 ((uint32_t)src[2]) >> 8; \
00391 } \
00392 } \
00393 else \
00394 { \
00395 if(is_yuv) \
00396 { \
00397 int r = (int)src[0]; \
00398 int g = (int)src[1]; \
00399 int b = (int)src[2]; \
00400 plugin->yuv->yuv_to_rgb_8(r, g, b); \
00401 dest = (r << 16) | (g << 8) | b; \
00402 } \
00403 else \
00404 { \
00405 dest = ((uint32_t)src[0] << 16) | \
00406 ((uint32_t)src[1] << 8) | \
00407 (uint32_t)src[2]; \
00408 } \
00409 }
00410
00411
00412
00413
00414 #define HOLO_CORE(type, components, is_yuv) \
00415 for(y = 1; y < height - 1; y++) \
00416 { \
00417 type *src = (type*)input_rows[y]; \
00418 type *bg = (type*)plugin->bgimage->get_rows()[y]; \
00419 type *dest = (type*)output_rows[y]; \
00420 \
00421 \
00422 \
00423 if(((y + phase) & 0x7f) < 0x58) \
00424 { \
00425 for(x = 0 ; x < width; x++) \
00426 { \
00427 if(*diff) \
00428 { \
00429 STORE_PIXEL(type, components, s, src, is_yuv); \
00430 \
00431 t = (s & 0xff) + \
00432 ((s & 0xff00) >> 7) + \
00433 ((s & 0xff0000) >> 16); \
00434 t += plugin->noisepattern[EffectTV::fastrand() >> 24]; \
00435 \
00436 r = ((s & 0xff0000) >> 17) + t; \
00437 g = ((s & 0xff00) >> 8) + t; \
00438 b = (s & 0xff) + t; \
00439 \
00440 r = (r >> 1) - 100; \
00441 g = (g >> 1) - 100; \
00442 b = b >> 2; \
00443 \
00444 if(r < 20) r = 20; \
00445 if(g < 20) g = 20; \
00446 \
00447 STORE_PIXEL(type, components, s, bg, is_yuv); \
00448 \
00449 r += (s & 0xff0000) >> 17; \
00450 g += (s & 0xff00) >> 9; \
00451 b += ((s & 0xff) >> 1) + 40; \
00452 \
00453 if(r > 255) r = 255; \
00454 if(g > 255) g = 255; \
00455 if(b > 255) b = 255; \
00456 \
00457 if(is_yuv) plugin->yuv->rgb_to_yuv_8(r, g, b); \
00458 if(sizeof(type) == 4) \
00459 { \
00460 dest[0] = (type)r / 0xff; \
00461 dest[1] = (type)g / 0xff; \
00462 dest[2] = (type)b / 0xff; \
00463 } \
00464 else \
00465 if(sizeof(type) == 2) \
00466 { \
00467 dest[0] = (r << 8) | r; \
00468 dest[1] = (g << 8) | g; \
00469 dest[2] = (b << 8) | b; \
00470 } \
00471 else \
00472 { \
00473 dest[0] = r; \
00474 dest[1] = g; \
00475 dest[2] = b; \
00476 } \
00477 } \
00478 else \
00479 { \
00480 dest[0] = bg[0]; \
00481 dest[1] = bg[1]; \
00482 dest[2] = bg[2]; \
00483 } \
00484 \
00485 diff++; \
00486 src += components; \
00487 dest += components; \
00488 bg += components; \
00489 } \
00490 } \
00491 else \
00492 { \
00493 for(x = 0; x < width; x++) \
00494 { \
00495 if(*diff) \
00496 { \
00497 STORE_PIXEL(type, components, s, src, is_yuv); \
00498 \
00499 \
00500 t = (s & 0xff) + ((s & 0xff00) >> 6) + ((s & 0xff0000) >> 16); \
00501 t += plugin->noisepattern[EffectTV::fastrand() >> 24]; \
00502 \
00503 r = ((s & 0xff0000) >> 16) + t; \
00504 g = ((s & 0xff00) >> 8) + t; \
00505 b = (s & 0xff) + t; \
00506 \
00507 r = (r >> 1) - 100; \
00508 g = (g >> 1) - 100; \
00509 b = b >> 2; \
00510 \
00511 if(r < 0) r = 0; \
00512 if(g < 0) g = 0; \
00513 \
00514 STORE_PIXEL(type, components, s, bg, is_yuv); \
00515 \
00516 r += ((s & 0xff0000) >> 17) + 10; \
00517 g += ((s & 0xff00) >> 9) + 10; \
00518 b += ((s & 0xff) >> 1) + 40; \
00519 \
00520 if(r > 255) r = 255; \
00521 if(g > 255) g = 255; \
00522 if(b > 255) b = 255; \
00523 \
00524 if(is_yuv) plugin->yuv->rgb_to_yuv_8(r, g, b); \
00525 if(sizeof(type) == 4) \
00526 { \
00527 dest[0] = (type)r / 0xff; \
00528 dest[1] = (type)g / 0xff; \
00529 dest[2] = (type)b / 0xff; \
00530 } \
00531 else \
00532 if(sizeof(type) == 2) \
00533 { \
00534 dest[0] = (r << 8) | r; \
00535 dest[1] = (g << 8) | g; \
00536 dest[2] = (b << 8) | b; \
00537 } \
00538 else \
00539 { \
00540 dest[0] = r; \
00541 dest[1] = g; \
00542 dest[2] = b; \
00543 } \
00544 } \
00545 else \
00546 { \
00547 dest[0] = bg[0]; \
00548 dest[1] = bg[1]; \
00549 dest[2] = bg[2]; \
00550 } \
00551 \
00552 diff++; \
00553 src += components; \
00554 dest += components; \
00555 bg += components; \
00556 } \
00557 } \
00558 }
00559
00560
00561
00562
00563 switch(plugin->input_ptr->get_color_model())
00564 {
00565 case BC_RGB888:
00566 HOLO_CORE(uint8_t, 3, 0);
00567 break;
00568 case BC_RGB_FLOAT:
00569 HOLO_CORE(float, 3, 0);
00570 break;
00571 case BC_YUV888:
00572 HOLO_CORE(uint8_t, 3, 1);
00573 break;
00574 case BC_RGBA_FLOAT:
00575 HOLO_CORE(float, 4, 0);
00576 break;
00577 case BC_RGBA8888:
00578 HOLO_CORE(uint8_t, 4, 0);
00579 break;
00580 case BC_YUVA8888:
00581 HOLO_CORE(uint8_t, 4, 1);
00582 break;
00583 case BC_RGB161616:
00584 HOLO_CORE(uint16_t, 3, 0);
00585 break;
00586 case BC_YUV161616:
00587 HOLO_CORE(uint16_t, 3, 1);
00588 break;
00589 case BC_RGBA16161616:
00590 HOLO_CORE(uint16_t, 4, 0);
00591 break;
00592 case BC_YUVA16161616:
00593 HOLO_CORE(uint16_t, 4, 1);
00594 break;
00595 }
00596
00597
00598
00599 phase -= 37;
00600 }
00601
00602
00603
00604 HoloPackage::HoloPackage()
00605 {
00606 }
00607
00608
00609