00001 #include "bcsignals.h"
00002 #include "edl.h"
00003 #include "edlsession.h"
00004 #include "filexml.h"
00005 #include "keyframe.h"
00006 #include "keyframes.h"
00007 #include "localsession.h"
00008 #include "mwindow.h"
00009 #include "messages.h"
00010 #include "plugin.h"
00011 #include "pluginpopup.h"
00012 #include "pluginset.h"
00013 #include "pluginserver.h"
00014 #include "renderengine.h"
00015 #include "track.h"
00016 #include "tracks.h"
00017 #include "virtualnode.h"
00018
00019
00020 Plugin::Plugin(EDL *edl,
00021 Track *track,
00022 char *title)
00023 : Edit(edl, track)
00024 {
00025 this->track = track;
00026 this->plugin_set = 0;
00027 strcpy(this->title, title);
00028 plugin_type = PLUGIN_NONE;
00029 in = 1;
00030 out = 1;
00031 show = 0;
00032 on = 1;
00033 keyframes = new KeyFrames(edl, track);
00034 keyframes->create_objects();
00035 }
00036
00037
00038 Plugin::Plugin(EDL *edl, PluginSet *plugin_set, char *title)
00039 : Edit(edl, plugin_set)
00040 {
00041 this->track = plugin_set->track;
00042 this->plugin_set = plugin_set;
00043 strcpy(this->title, title);
00044 plugin_type = PLUGIN_NONE;
00045 in = 1;
00046 out = 1;
00047 show = 0;
00048 on = 1;
00049 keyframes = new KeyFrames(edl, track);
00050 keyframes->create_objects();
00051 }
00052
00053 Plugin::~Plugin()
00054 {
00055 while(keyframes->last) delete keyframes->last;
00056 delete keyframes;
00057 }
00058
00059 Edit& Plugin::operator=(Edit& edit)
00060 {
00061 copy_from(&edit);
00062 return *this;
00063 }
00064
00065 Plugin& Plugin::operator=(Plugin& edit)
00066 {
00067 copy_from(&edit);
00068 return *this;
00069 }
00070
00071 int Plugin::operator==(Plugin& that)
00072 {
00073 return identical(&that);
00074 }
00075
00076 int Plugin::operator==(Edit& that)
00077 {
00078 return identical((Plugin*)&that);
00079 }
00080
00081 int Plugin::silence()
00082 {
00083 if(plugin_type != PLUGIN_NONE)
00084 return 0;
00085 else
00086 return 1;
00087 }
00088
00089 void Plugin::clear_keyframes(int64_t start, int64_t end)
00090 {
00091 keyframes->clear(start, end, 0);
00092 }
00093
00094
00095 void Plugin::copy_from(Edit *edit)
00096 {
00097 Plugin *plugin = (Plugin*)edit;
00098
00099 this->startsource = edit->startsource;
00100 this->startproject = edit->startproject;
00101 this->length = edit->length;
00102
00103
00104 this->plugin_type = plugin->plugin_type;
00105 this->in = plugin->in;
00106 this->out = plugin->out;
00107 this->show = plugin->show;
00108 this->on = plugin->on;
00109
00110 this->shared_location = plugin->shared_location;
00111 strcpy(this->title, plugin->title);
00112
00113 copy_keyframes(plugin);
00114 }
00115
00116 void Plugin::copy_keyframes(Plugin *plugin)
00117 {
00118 keyframes->copy_from(plugin->keyframes);
00119 }
00120
00121 void Plugin::copy_keyframes(int64_t start,
00122 int64_t end,
00123 FileXML *file,
00124 int default_only,
00125 int autos_only)
00126 {
00127 keyframes->copy(start, end, file, default_only, autos_only);
00128 }
00129
00130 void Plugin::synchronize_params(Edit *edit)
00131 {
00132 Plugin *plugin = (Plugin*)edit;
00133 this->in = plugin->in;
00134 this->out = plugin->out;
00135 this->show = plugin->show;
00136 this->on = plugin->on;
00137 strcpy(this->title, plugin->title);
00138 copy_keyframes(plugin);
00139 }
00140
00141 void Plugin::shift_keyframes(int64_t position)
00142 {
00143 for(KeyFrame *keyframe = (KeyFrame*)keyframes->first;
00144 keyframe;
00145 keyframe = (KeyFrame*)keyframe->next)
00146 {
00147 keyframe->position += position;
00148 }
00149 }
00150
00151
00152 void Plugin::equivalent_output(Edit *edit, int64_t *result)
00153 {
00154 Plugin *plugin = (Plugin*)edit;
00155
00156 if(startproject + length != plugin->startproject + plugin->length)
00157 {
00158 if(*result < 0 || startproject + length < *result)
00159 *result = startproject + length;
00160 }
00161
00162
00163 if(
00164 startproject != plugin->startproject ||
00165 plugin_type != plugin->plugin_type ||
00166 on != plugin->on ||
00167 !(shared_location == plugin->shared_location) ||
00168 strcmp(title, plugin->title)
00169 )
00170 {
00171 if(*result < 0 || startproject < *result)
00172 *result = startproject;
00173 }
00174
00175
00176 keyframes->equivalent_output(plugin->keyframes, startproject, result);
00177 }
00178
00179
00180
00181 int Plugin::is_synthesis(RenderEngine *renderengine,
00182 int64_t position,
00183 int direction)
00184 {
00185 switch(plugin_type)
00186 {
00187 case PLUGIN_STANDALONE:
00188 {
00189 if(!track)
00190 {
00191 printf("Plugin::is_synthesis track not defined\n");
00192 return 0;
00193 }
00194 PluginServer *plugin_server = renderengine->scan_plugindb(title,
00195 track->data_type);
00196 return plugin_server->synthesis;
00197 break;
00198 }
00199
00200
00201 case PLUGIN_SHAREDPLUGIN:
00202 {
00203 int real_module_number = shared_location.module;
00204 int real_plugin_number = shared_location.plugin;
00205 Track *track = edl->tracks->number(real_module_number);
00206
00207 Plugin *plugin = track->get_current_plugin(position,
00208 real_plugin_number,
00209 direction,
00210 0,
00211 0);
00212
00213 if(plugin)
00214 return plugin->is_synthesis(renderengine, position, direction);
00215 break;
00216 }
00217
00218
00219 case PLUGIN_SHAREDMODULE:
00220 {
00221 int real_module_number = shared_location.module;
00222 Track *track = edl->tracks->number(real_module_number);
00223 return track->is_synthesis(renderengine, position, direction);
00224 break;
00225 }
00226 }
00227 return 0;
00228 }
00229
00230
00231
00232 int Plugin::identical(Plugin *that)
00233 {
00234
00235 if(plugin_type != that->plugin_type) return 0;
00236
00237
00238 switch(plugin_type)
00239 {
00240 case PLUGIN_STANDALONE:
00241 if(strcmp(title, that->title)) return 0;
00242 break;
00243 case PLUGIN_SHAREDPLUGIN:
00244 if(shared_location.module != that->shared_location.module ||
00245 shared_location.plugin != that->shared_location.plugin) return 0;
00246 break;
00247 case PLUGIN_SHAREDMODULE:
00248 if(shared_location.module != that->shared_location.module) return 0;
00249 break;
00250 }
00251
00252
00253 return (this->on == that->on &&
00254 ((KeyFrame*)keyframes->default_auto)->identical(
00255 ((KeyFrame*)that->keyframes->default_auto)));
00256 }
00257
00258 int Plugin::identical_location(Plugin *that)
00259 {
00260 if(!plugin_set || !plugin_set->track) return 0;
00261 if(!that->plugin_set || !that->plugin_set->track) return 0;
00262
00263 if(plugin_set->track->number_of() == that->plugin_set->track->number_of() &&
00264 plugin_set->get_number() == that->plugin_set->get_number() &&
00265 startproject == that->startproject) return 1;
00266
00267 return 0;
00268 }
00269
00270 void Plugin::change_plugin(char *title,
00271 SharedLocation *shared_location,
00272 int plugin_type)
00273 {
00274 strcpy(this->title, title);
00275 this->shared_location = *shared_location;
00276 this->plugin_type = plugin_type;
00277 }
00278
00279
00280
00281 KeyFrame* Plugin::get_prev_keyframe(int64_t position,
00282 int direction)
00283 {
00284 KeyFrame *current = 0;
00285
00286
00287
00288 if(position < 0)
00289 {
00290 position = track->to_units(edl->local_session->get_selectionstart(1), 0);
00291 }
00292
00293
00294 for(current = (KeyFrame*)keyframes->last;
00295 current;
00296 current = (KeyFrame*)PREVIOUS)
00297 {
00298 if(direction == PLAY_FORWARD && current->position <= position) break;
00299 else
00300 if(direction == PLAY_REVERSE && current->position < position) break;
00301 }
00302
00303
00304 if(!current && keyframes->first)
00305 {
00306 current = (KeyFrame*)keyframes->first;
00307 }
00308 else
00309
00310 if(!current)
00311 {
00312 current = (KeyFrame*)keyframes->default_auto;
00313 }
00314
00315 return current;
00316 }
00317
00318 KeyFrame* Plugin::get_next_keyframe(int64_t position,
00319 int direction)
00320 {
00321 KeyFrame *current;
00322
00323
00324
00325 if(position < 0)
00326 {
00327
00328 position = track->to_units(edl->local_session->get_selectionstart(1), 0);
00329 }
00330
00331
00332 for(current = (KeyFrame*)keyframes->first;
00333 current;
00334 current = (KeyFrame*)NEXT)
00335 {
00336 if(direction == PLAY_FORWARD && current->position > position) break;
00337 else
00338 if(direction == PLAY_REVERSE && current->position >= position) break;
00339 }
00340
00341
00342 if(!current && keyframes->last)
00343 {
00344 current = (KeyFrame*)keyframes->last;
00345 }
00346 else
00347
00348 if(!current)
00349 {
00350 current = (KeyFrame*)keyframes->default_auto;
00351 }
00352
00353 return current;
00354 }
00355
00356 KeyFrame* Plugin::get_keyframe()
00357 {
00358
00359 KeyFrame *result =
00360 get_prev_keyframe(track->to_units(edl->local_session->get_selectionstart(1), 0),
00361 PLAY_FORWARD);
00362
00363
00364 if(!edl->session->auto_keyframes)
00365 {
00366 return result;
00367 }
00368 else
00369
00370 if(result == (KeyFrame*)keyframes->default_auto ||
00371 result->position != track->to_units(edl->local_session->get_selectionstart(1), 0))
00372 {
00373 return (KeyFrame*)keyframes->insert_auto(track->to_units(edl->local_session->get_selectionstart(1), 0));
00374 }
00375 else
00376
00377 {
00378 return result;
00379 }
00380
00381 return 0;
00382 }
00383
00384 void Plugin::copy(int64_t start, int64_t end, FileXML *file)
00385 {
00386 int64_t endproject = startproject + length;
00387
00388 if((startproject >= start && startproject <= end) ||
00389 (endproject <= end && endproject >= start) ||
00390 (startproject <= start && endproject >= end))
00391 {
00392
00393 int64_t startproject_in_selection = startproject;
00394 int64_t startsource_in_selection = startsource;
00395 int64_t endsource_in_selection = startsource + length;
00396 int64_t length_in_selection = length;
00397
00398 if(startproject < start)
00399 {
00400 int64_t length_difference = start - startproject;
00401
00402 startsource_in_selection += length_difference;
00403 startproject_in_selection += length_difference;
00404 length_in_selection -= length_difference;
00405 }
00406
00407
00408 if(endproject > end)
00409 {
00410 length_in_selection = end - startproject_in_selection;
00411 }
00412
00413
00414 file->tag.set_title("PLUGIN");
00415
00416 file->tag.set_property("LENGTH", length_in_selection);
00417 file->tag.set_property("TYPE", plugin_type);
00418 file->tag.set_property("TITLE", title);
00419 file->append_tag();
00420 file->append_newline();
00421
00422
00423 if(plugin_type == PLUGIN_SHAREDPLUGIN ||
00424 plugin_type == PLUGIN_SHAREDMODULE)
00425 {
00426 shared_location.save(file);
00427 }
00428
00429
00430
00431 if(in)
00432 {
00433 file->tag.set_title("IN");
00434 file->append_tag();
00435 file->tag.set_title("/IN");
00436 file->append_tag();
00437 }
00438 if(out)
00439 {
00440 file->tag.set_title("OUT");
00441 file->append_tag();
00442 file->tag.set_title("/OUT");
00443 file->append_tag();
00444 }
00445 if(show)
00446 {
00447 file->tag.set_title("SHOW");
00448 file->append_tag();
00449 file->tag.set_title("/SHOW");
00450 file->append_tag();
00451 }
00452 if(on)
00453 {
00454 file->tag.set_title("ON");
00455 file->append_tag();
00456 file->tag.set_title("/ON");
00457 file->append_tag();
00458 }
00459 file->append_newline();
00460
00461
00462 keyframes->copy(start, end, file, 0, 0);
00463
00464 file->tag.set_title("/PLUGIN");
00465 file->append_tag();
00466 file->append_newline();
00467 }
00468 }
00469
00470 void Plugin::load(FileXML *file)
00471 {
00472 int result = 0;
00473 int first_keyframe = 1;
00474 in = 0;
00475 out = 0;
00476
00477 show = 0;
00478 on = 0;
00479 while(keyframes->last) delete keyframes->last;
00480
00481 do{
00482 result = file->read_tag();
00483
00484
00485 if(!result)
00486 {
00487 if(file->tag.title_is("/PLUGIN"))
00488 {
00489 result = 1;
00490 }
00491 else
00492 if(file->tag.title_is("SHARED_LOCATION"))
00493 {
00494 shared_location.load(file);
00495 }
00496 else
00497 if(file->tag.title_is("IN"))
00498 {
00499 in = 1;
00500 }
00501 else
00502 if(file->tag.title_is("OUT"))
00503 {
00504 out = 1;
00505 }
00506 else
00507 if(file->tag.title_is("SHOW"))
00508 {
00509
00510 }
00511 else
00512 if(file->tag.title_is("ON"))
00513 {
00514 on = 1;
00515 }
00516 else
00517 if(file->tag.title_is("KEYFRAME"))
00518 {
00519
00520 if(first_keyframe)
00521 {
00522 keyframes->default_auto->load(file);
00523 first_keyframe = 0;
00524 }
00525 else
00526
00527 {
00528 KeyFrame *keyframe = (KeyFrame*)keyframes->append(new KeyFrame(edl, keyframes));
00529 keyframe->position = file->tag.get_property("POSITION", (int64_t)0);
00530 keyframe->load(file);
00531 }
00532 }
00533 }
00534 }while(!result);
00535 }
00536
00537 void Plugin::get_shared_location(SharedLocation *result)
00538 {
00539 if(plugin_type == PLUGIN_STANDALONE && plugin_set)
00540 {
00541 result->module = edl->tracks->number_of(track);
00542 result->plugin = track->plugin_set.number_of(plugin_set);
00543 }
00544 else
00545 {
00546 *result = this->shared_location;
00547 }
00548 }
00549
00550 Track* Plugin::get_shared_track()
00551 {
00552 return edl->tracks->get_item_number(shared_location.module);
00553 }
00554
00555
00556 void Plugin::calculate_title(char *string, int use_nudge)
00557 {
00558 if(plugin_type == PLUGIN_STANDALONE || plugin_type == PLUGIN_NONE)
00559 {
00560 strcpy(string, _(title));
00561 }
00562 else
00563 if(plugin_type == PLUGIN_SHAREDPLUGIN || plugin_type == PLUGIN_SHAREDMODULE)
00564 {
00565 shared_location.calculate_title(string,
00566 edl,
00567 startproject,
00568 0,
00569 plugin_type,
00570 use_nudge);
00571 }
00572 }
00573
00574
00575 void Plugin::paste(FileXML *file)
00576 {
00577 length = file->tag.get_property("LENGTH", (int64_t)0);
00578 }
00579
00580 void Plugin::resample(double old_rate, double new_rate)
00581 {
00582
00583 keyframes->resample(old_rate, new_rate);
00584 }
00585
00586 void Plugin::shift(int64_t difference)
00587 {
00588 Edit::shift(difference);
00589 shift_keyframes(difference);
00590 }
00591
00592 void Plugin::dump()
00593 {
00594 printf(" PLUGIN: type=%d title=\"%s\" on=%d track=%d plugin=%d\n",
00595 plugin_type,
00596 title,
00597 on,
00598 shared_location.module,
00599 shared_location.plugin);
00600 printf(" startproject %lld length %lld\n", startproject, length);
00601
00602 keyframes->dump();
00603 }
00604
00605