Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

plugin.C

Go to the documentation of this file.
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 // Should reconfigure this based on where the first track is now.
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 // End of plugin changed
00156         if(startproject + length != plugin->startproject + plugin->length)
00157         {
00158                 if(*result < 0 || startproject + length < *result)
00159                         *result = startproject + length;
00160         }
00161 
00162 // Start of plugin changed
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 // Test keyframes
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 // Dereference real plugin and descend another level
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 // Get shared plugin from master track
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 // Dereference the real track and descend
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 // Test type
00235         if(plugin_type != that->plugin_type) return 0;
00236 
00237 // Test title or location
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 // Test remaining fields
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 // This doesn't work because edl->selectionstart doesn't change during
00287 // playback at the same rate as PluginClient::source_position.
00288         if(position < 0)
00289         {
00290                 position = track->to_units(edl->local_session->get_selectionstart(1), 0);
00291         }
00292 
00293 // Get keyframe on or before current position
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 // Nothing before current position
00304         if(!current && keyframes->first)
00305         {
00306                 current = (KeyFrame*)keyframes->first;
00307         }
00308         else
00309 // No keyframes
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 // This doesn't work for playback because edl->selectionstart doesn't 
00324 // change during playback at the same rate as PluginClient::source_position.
00325         if(position < 0)
00326         {
00327 //printf("Plugin::get_next_keyframe position < 0\n");
00328                 position = track->to_units(edl->local_session->get_selectionstart(1), 0);
00329         }
00330 
00331 // Get keyframe after current position
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 // Nothing after current position
00342         if(!current && keyframes->last)
00343         {
00344                 current =  (KeyFrame*)keyframes->last;
00345         }
00346         else
00347 // No keyframes
00348         if(!current)
00349         {
00350                 current = (KeyFrame*)keyframes->default_auto;
00351         }
00352 
00353         return current;
00354 }
00355 
00356 KeyFrame* Plugin::get_keyframe()
00357 {
00358 // Search for keyframe on or before selection
00359         KeyFrame *result = 
00360                 get_prev_keyframe(track->to_units(edl->local_session->get_selectionstart(1), 0), 
00361                         PLAY_FORWARD);
00362 
00363 // Return nearest keyframe if not in automatic keyframe generation
00364         if(!edl->session->auto_keyframes)
00365         {
00366                 return result;
00367         }
00368         else
00369 // Return new keyframe
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 // Return existing keyframe
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) ||  // startproject in range
00389                  (endproject <= end && endproject >= start) ||     // endproject in range
00390                  (startproject <= start && endproject >= end))    // range in project
00391         {
00392 // edit is in range
00393                 int64_t startproject_in_selection = startproject; // start of edit in selection in project
00394                 int64_t startsource_in_selection = startsource; // start of source in selection in source
00395                 int64_t endsource_in_selection = startsource + length; // end of source in selection
00396                 int64_t length_in_selection = length;             // length of edit in selection
00397 
00398                 if(startproject < start)
00399                 {         // start is after start of edit in project
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 // end is before end of edit in project
00408                 if(endproject > end)
00409                 {         
00410                         length_in_selection = end - startproject_in_selection;
00411                 }
00412 
00413 // Plugins don't store silence
00414                 file->tag.set_title("PLUGIN");  
00415 //              file->tag.set_property("STARTPROJECT", startproject_in_selection - start);
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 // Keyframes
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 // Currently show is ignored when loading
00477         show = 0;
00478         on = 0;
00479         while(keyframes->last) delete keyframes->last;
00480 
00481         do{
00482                 result = file->read_tag();
00483 
00484 //printf("Plugin::load 1 %s\n", file->tag.get_title());
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 //                              show = 1;
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 // Default keyframe
00520                                 if(first_keyframe)
00521                                 {
00522                                         keyframes->default_auto->load(file);
00523                                         first_keyframe = 0;
00524                                 }
00525                                 else
00526 // Override default keyframe
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 // Resample keyframes in here
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 

Generated on Sun Jan 8 13:38:58 2006 for Cinelerra-svn by  doxygen 1.4.4