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

edit.C

Go to the documentation of this file.
00001 #include "asset.h"
00002 #include "assets.h"
00003 #include "clip.h"
00004 #include "edit.h"
00005 #include "edits.h"
00006 #include "edl.h"
00007 #include "edlsession.h"
00008 #include "filexml.h"
00009 #include "filesystem.h"
00010 #include "localsession.h"
00011 #include "plugin.h"
00012 #include "mainsession.h"
00013 #include "trackcanvas.h"
00014 #include "tracks.h"
00015 #include "transition.h"
00016 #include <string.h>
00017 
00018 
00019 Edit::Edit()
00020 {
00021         reset();
00022 }
00023 
00024 Edit::Edit(EDL *edl, Track *track)
00025 {
00026         reset();
00027         this->edl = edl;
00028         this->track = track;
00029         if(track) this->edits = track->edits;
00030         id = EDL::next_id();
00031 }
00032 
00033 Edit::Edit(EDL *edl, Edits *edits)
00034 {
00035         reset();
00036         this->edl = edl;
00037         this->edits = edits;
00038         if(edits) this->track = edits->track;
00039         id = EDL::next_id();
00040 }
00041 
00042 Edit::~Edit()
00043 {
00044 //printf("Edit::~Edit 1\n");
00045         if(transition) delete transition;
00046 //printf("Edit::~Edit 2\n");
00047 }
00048 
00049 void Edit::reset()
00050 {
00051         edl = 0;
00052         track = 0;
00053         edits = 0;
00054         startsource = 0;  
00055         startproject = 0;        
00056         length = 0;  
00057         asset = 0;
00058         transition = 0;
00059         channel = 0;
00060         user_title[0] = 0;
00061 }
00062 
00063 int Edit::copy(int64_t start, int64_t end, FileXML *file, char *output_path)
00064 {
00065 // variables
00066 //printf("Edit::copy 1\n");
00067 
00068         int64_t endproject = startproject + length;
00069         int result;
00070 
00071         if((startproject >= start && startproject <= end) ||  // startproject in range
00072                  (endproject <= end && endproject >= start) ||     // endproject in range
00073                  (startproject <= start && endproject >= end))    // range in project
00074         {   
00075 // edit is in range
00076                 int64_t startproject_in_selection = startproject; // start of edit in selection in project
00077                 int64_t startsource_in_selection = startsource; // start of source in selection in source
00078                 int64_t endsource_in_selection = startsource + length; // end of source in selection
00079                 int64_t length_in_selection = length;             // length of edit in selection
00080 //printf("Edit::copy 2\n");
00081 
00082                 if(startproject < start)
00083                 {         // start is after start of edit in project
00084                         int64_t length_difference = start - startproject;
00085 
00086                         startsource_in_selection += length_difference;
00087                         startproject_in_selection += length_difference;
00088                         length_in_selection -= length_difference;
00089                 }
00090 //printf("Edit::copy 3\n");
00091 
00092                 if(endproject > end)
00093                 {         // end is before end of edit in project
00094                         length_in_selection = end - startproject_in_selection;
00095                 }
00096                 
00097 //printf("Edit::copy 4\n");
00098                 if(file)    // only if not counting
00099                 {
00100                         file->tag.set_title("EDIT");
00101                         file->tag.set_property("STARTSOURCE", startsource_in_selection);
00102                         file->tag.set_property("CHANNEL", (int64_t)channel);
00103                         file->tag.set_property("LENGTH", length_in_selection);
00104                         if(user_title[0]) file->tag.set_property("USER_TITLE", user_title);
00105 //printf("Edit::copy 5\n");
00106 
00107                         copy_properties_derived(file, length_in_selection);
00108 
00109                         file->append_tag();
00110 //                      file->append_newline();
00111 //printf("Edit::copy 6\n");
00112 
00113                         if(asset)
00114                         {
00115 //printf("Edit::copy 6 %s\n", asset->path);
00116                                 char stored_path[1024];
00117                                 char asset_directory[1024], output_directory[1024];
00118                                 FileSystem fs;
00119 
00120 //printf("Edit::copy 6 %s\n", asset->path);
00121                                 fs.extract_dir(asset_directory, asset->path);
00122 //printf("Edit::copy 6 %s\n", asset->path);
00123 
00124                                 if(output_path)
00125                                         fs.extract_dir(output_directory, output_path);
00126                                 else
00127                                         output_directory[0] = 0;
00128 //printf("Edit::copy %s, %s %s, %s\n", asset->path, asset_directory, output_path, output_directory);
00129 
00130                                 if(output_path && !strcmp(asset_directory, output_directory))
00131                                         fs.extract_name(stored_path, asset->path);
00132                                 else
00133                                         strcpy(stored_path, asset->path);
00134 
00135                                 file->tag.set_title("FILE");
00136                                 file->tag.set_property("SRC", stored_path);
00137                                 file->append_tag();
00138                                 file->tag.set_title("/FILE");
00139                                 file->append_tag();
00140                         }
00141 
00142                         if(transition)
00143                         {
00144                                 transition->save_xml(file);
00145                         }
00146 
00147 //printf("Edit::copy 7\n");
00148                         file->tag.set_title("/EDIT");
00149                         file->append_tag();
00150                         file->append_newline(); 
00151 //printf("Edit::copy 8\n");
00152                 }
00153 //printf("Edit::copy 9\n");
00154                 result = 1;
00155         }
00156         else
00157         {
00158                 result = 0;
00159         }
00160 //printf("Edit::copy 10\n");
00161         return result;
00162 }
00163 
00164 
00165 int64_t Edit::get_source_end(int64_t default_)
00166 {
00167         return default_;
00168 }
00169 
00170 void Edit::insert_transition(char *title)
00171 {
00172 //printf("Edit::insert_transition this=%p title=%p title=%s\n", this, title, title);
00173         transition = new Transition(edl, 
00174                 this, 
00175                 title, 
00176                 track->to_units(edl->session->default_transition_length, 1));
00177 }
00178 
00179 void Edit::detach_transition()
00180 {
00181         if(transition) delete transition;
00182         transition = 0;
00183 }
00184 
00185 int Edit::silence()
00186 {
00187         if(asset) 
00188                 return 0;
00189         else
00190                 return 1;
00191 }
00192 
00193 
00194 void Edit::copy_from(Edit *edit)
00195 {
00196         this->asset = edl->assets->update(edit->asset);
00197         this->startsource = edit->startsource;
00198         this->startproject = edit->startproject;
00199         this->length = edit->length;
00200         strcpy (this->user_title, edit->user_title);
00201 
00202         if(edit->transition)
00203         {
00204                 if(!transition) transition = new Transition(edl, 
00205                         this, 
00206                         edit->transition->title,
00207                         edit->transition->length);
00208                 *this->transition = *edit->transition;
00209         }
00210         this->channel = edit->channel;
00211 }
00212 
00213 void Edit::equivalent_output(Edit *edit, int64_t *result)
00214 {
00215 // End of edit changed
00216         if(startproject + length != edit->startproject + edit->length)
00217         {
00218                 int64_t new_length = MIN(startproject + length, edit->startproject + edit->length);
00219                 if(*result < 0 || new_length < *result) 
00220                         *result = new_length;
00221         }
00222 
00223 // Start of edit changed
00224         if(
00225 // One is silence and one isn't
00226                 edit->asset == 0 && asset != 0 ||
00227                 edit->asset != 0 && asset == 0 ||
00228 // One has transition and one doesn't
00229                 edit->transition == 0 && transition != 0 ||
00230                 edit->transition != 0 && transition == 0 ||
00231 // Position changed
00232                 startproject != edit->startproject ||
00233                 startsource != edit->startsource ||
00234 // Transition changed
00235                 (transition && 
00236                         edit->transition && 
00237                         !transition->identical(edit->transition)) ||
00238 // Asset changed
00239                 (asset && 
00240                         edit->asset &&
00241                         !asset->equivalent(*edit->asset, 1, 1))
00242                 )
00243         {
00244                 if(*result < 0 || startproject < *result) *result = startproject;
00245         }
00246 }
00247 
00248 
00249 Edit& Edit::operator=(Edit& edit)
00250 {
00251 //printf("Edit::operator= called\n");
00252         copy_from(&edit);
00253         return *this;
00254 }
00255 
00256 void Edit::synchronize_params(Edit *edit)
00257 {
00258         copy_from(edit);
00259 }
00260 
00261 
00262 // Comparison for ResourcePixmap drawing
00263 int Edit::identical(Edit &edit)
00264 {
00265         int result = (this->asset == edit.asset &&
00266         this->startsource == edit.startsource &&
00267         this->startproject == edit.startproject &&
00268         this->length == edit.length &&
00269         this->transition == edit.transition &&
00270         this->channel == edit.channel);
00271         return result;
00272 }
00273 
00274 int Edit::operator==(Edit &edit)
00275 {
00276         return identical(edit);
00277 }
00278 
00279 double Edit::frames_per_picon()
00280 {
00281         return picon_w() / frame_w();
00282 }
00283 
00284 double Edit::frame_w()
00285 {
00286         return track->from_units(1) * edl->session->sample_rate / edl->local_session->zoom_sample;
00287 }
00288 
00289 double Edit::picon_w()
00290 {
00291         return (double)edl->local_session->zoom_track * asset->width / asset->height;
00292 }
00293 
00294 int Edit::picon_h()
00295 {
00296         return edl->local_session->zoom_track;
00297 }
00298 
00299 
00300 int Edit::dump()
00301 {
00302         printf("     EDIT %p\n", this); fflush(stdout);
00303         printf("      asset %p\n", asset); fflush(stdout);
00304         printf("      channel %d\n", channel);
00305         if(transition) 
00306         {
00307                 printf("      TRANSITION %p\n", transition);
00308                 transition->dump();
00309         }
00310         printf("      startsource %lld startproject %lld length %lld\n", startsource, startproject, length); fflush(stdout);
00311         return 0;
00312 }
00313 
00314 int Edit::load_properties(FileXML *file, int64_t &startproject)
00315 {
00316         startsource = file->tag.get_property("STARTSOURCE", (int64_t)0);
00317         length = file->tag.get_property("LENGTH", (int64_t)0);
00318         user_title[0] = 0;
00319         file->tag.get_property("USER_TITLE", user_title);
00320         this->startproject = startproject;
00321         load_properties_derived(file);
00322         return 0;
00323 }
00324 
00325 void Edit::shift(int64_t difference)
00326 {
00327 //printf("Edit::shift 1 %p %lld %lld\n", this, startproject, difference);
00328         startproject += difference;
00329 //printf("Edit::shift 2 %lld %lld\n", startproject, difference);
00330 }
00331 
00332 int Edit::shift_start_in(int edit_mode, 
00333         int64_t newposition, 
00334         int64_t oldposition,
00335         int edit_edits,
00336         int edit_labels,
00337         int edit_plugins,
00338         Edits *trim_edits)
00339 {
00340         int64_t cut_length = newposition - oldposition;
00341         int64_t end_previous_source, end_source;
00342 
00343         if(edit_mode == MOVE_ALL_EDITS)
00344         {
00345                 if(cut_length < length)
00346                 {        // clear partial 
00347                         edits->clear_recursive(oldposition, 
00348                                 newposition,
00349                                 edit_edits,
00350                                 edit_labels,
00351                                 edit_plugins,
00352                                 trim_edits);
00353                 }
00354                 else
00355                 {        // clear entire
00356                         edits->clear_recursive(oldposition, 
00357                                 startproject + length,
00358                                 edit_edits,
00359                                 edit_labels,
00360                                 edit_plugins,
00361                                 trim_edits);
00362                 }
00363         }
00364         else
00365         if(edit_mode == MOVE_ONE_EDIT)
00366         {
00367 // Paste silence and cut
00368 //printf("Edit::shift_start_in 1\n");
00369                 if(!previous)
00370                 {
00371                         Edit *new_edit = edits->create_edit();
00372                         new_edit->startproject = this->startproject;
00373                         new_edit->length = 0;
00374                         edits->insert_before(this, 
00375                                 new_edit);
00376                 }
00377 //printf("Edit::shift_start_in 2 %p\n", previous);
00378 
00379                 end_previous_source = previous->get_source_end(previous->startsource + previous->length + cut_length);
00380                 if(end_previous_source > 0 && 
00381                         previous->startsource + previous->length + cut_length > end_previous_source)
00382                         cut_length = end_previous_source - previous->startsource - previous->length;
00383 
00384                 if(cut_length < length)
00385                 {               // Move in partial
00386                         startproject += cut_length;
00387                         startsource += cut_length;
00388                         length -= cut_length;
00389                         previous->length += cut_length;
00390 //printf("Edit::shift_start_in 2\n");
00391                 }
00392                 else
00393                 {               // Clear entire edit
00394                         cut_length = length;
00395                         previous->length += cut_length;
00396                         for(Edit* current_edit = this; current_edit; current_edit = current_edit->next)
00397                         {
00398                                 current_edit->startproject += cut_length;
00399                         }
00400                         edits->clear_recursive(oldposition + cut_length, 
00401                                 startproject + cut_length,
00402                                 edit_edits,
00403                                 edit_labels,
00404                                 edit_plugins,
00405                                 trim_edits);
00406                 }
00407 //printf("Edit::shift_start_in 3\n");
00408         }
00409         else
00410         if(edit_mode == MOVE_NO_EDITS)
00411         {
00412                 end_source = get_source_end(startsource + length + cut_length);
00413                 if(end_source > 0 && startsource + length + cut_length > end_source)
00414                         cut_length = end_source - startsource - length;
00415                 
00416                 startsource += cut_length;
00417         }
00418         return 0;
00419 }
00420 
00421 int Edit::shift_start_out(int edit_mode, 
00422         int64_t newposition, 
00423         int64_t oldposition,
00424         int edit_edits,
00425         int edit_labels,
00426         int edit_plugins,
00427         Edits *trim_edits)
00428 {
00429         int64_t cut_length = oldposition - newposition;
00430 
00431         if(asset)
00432         {
00433                 int64_t end_source = get_source_end(1);
00434 
00435 //printf("Edit::shift_start_out 1 %lld %lld\n", startsource, cut_length);
00436                 if(end_source > 0 && startsource < cut_length)
00437                 {
00438                         cut_length = startsource;
00439                 }
00440         }
00441 
00442         if(edit_mode == MOVE_ALL_EDITS)
00443         {
00444 //printf("Edit::shift_start_out 10 %lld\n", cut_length);
00445                 startsource -= cut_length;
00446                 length += cut_length;
00447 
00448                 edits->shift_keyframes_recursive(startproject, 
00449                         cut_length);
00450                 if(edit_plugins)
00451                         edits->shift_effects_recursive(startproject, 
00452                                 cut_length);
00453 
00454                 for(Edit* current_edit = next; current_edit; current_edit = current_edit->next)
00455                 {
00456                         current_edit->startproject += cut_length;
00457                 }
00458         }
00459         else
00460         if(edit_mode == MOVE_ONE_EDIT)
00461         {
00462                 if(previous)
00463                 {
00464                         if(cut_length < previous->length)
00465                         {   // Cut into previous edit
00466                                 previous->length -= cut_length;
00467                                 startproject -= cut_length;
00468                                 startsource -= cut_length;
00469                                 length += cut_length;
00470 printf("Edit::shift_start_out 2\n");
00471                         }
00472                         else
00473                         {   // Clear entire previous edit
00474                                 cut_length = previous->length;
00475                                 previous->length = 0;
00476                                 length += cut_length;
00477                                 startsource -= cut_length;
00478                                 startproject -= cut_length;
00479                         }
00480                 }
00481         }
00482         else
00483         if(edit_mode == MOVE_NO_EDITS)
00484         {
00485                 startsource -= cut_length;
00486         }
00487 
00488 // Fix infinite length files
00489         if(startsource < 0) startsource = 0;
00490         return 0;
00491 }
00492 
00493 int Edit::shift_end_in(int edit_mode, 
00494         int64_t newposition, 
00495         int64_t oldposition,
00496         int edit_edits,
00497         int edit_labels,
00498         int edit_plugins,
00499         Edits *trim_edits)
00500 {
00501         int64_t cut_length = oldposition - newposition;
00502 
00503         if(edit_mode == MOVE_ALL_EDITS)
00504         {
00505 //printf("Edit::shift_end_in 1\n");
00506                 if(newposition > startproject)
00507                 {        // clear partial edit
00508 //printf("Edit::shift_end_in %p %p\n", track->edits, edits);
00509                         edits->clear_recursive(newposition, 
00510                                 oldposition,
00511                                 edit_edits,
00512                                 edit_labels,
00513                                 edit_plugins,
00514                                 trim_edits);
00515                 }
00516                 else
00517                 {        // clear entire edit
00518                         edits->clear_recursive(startproject, 
00519                                 oldposition,
00520                                 edit_edits,
00521                                 edit_labels,
00522                                 edit_plugins,
00523                                 trim_edits);
00524                 }
00525         }
00526         else
00527         if(edit_mode == MOVE_ONE_EDIT)
00528         {
00529                 if(next)
00530                 {
00531                         if(next->asset)
00532                         {
00533                                 int64_t end_source = next->get_source_end(1);
00534 
00535                                 if(end_source > 0 && next->startsource - cut_length < 0)
00536                                 {
00537                                         cut_length = next->startsource;
00538                                 }
00539                         }
00540 
00541                         if(cut_length < length)
00542                         {
00543                                 length -= cut_length;
00544                                 next->startproject -= cut_length;
00545                                 next->startsource -= cut_length;
00546                                 next->length += cut_length;
00547 //printf("Edit::shift_end_in 2 %d\n", cut_length);
00548                         }
00549                         else
00550                         {
00551                                 cut_length = length;
00552                                 next->length += cut_length;
00553                                 next->startsource -= cut_length;
00554                                 next->startproject -= cut_length;
00555                                 length -= cut_length;
00556                         }
00557                 }
00558                 else
00559                 {
00560                         if(cut_length < length)
00561                         {
00562                                 length -= cut_length;
00563                         }
00564                         else
00565                         {
00566                                 cut_length = length;
00567                                 edits->clear_recursive(startproject, 
00568                                         oldposition,
00569                                         edit_edits,
00570                                         edit_labels,
00571                                         edit_plugins,
00572                                         trim_edits);
00573                         }
00574                 }
00575         }
00576         else
00577 // Does nothing for plugins
00578         if(edit_mode == MOVE_NO_EDITS)
00579         {
00580 //printf("Edit::shift_end_in 3\n");
00581                 int64_t end_source = get_source_end(1);
00582                 if(end_source > 0 && startsource < cut_length)
00583                 {
00584                         cut_length = startsource;
00585                 }
00586                 startsource -= cut_length;
00587         }
00588         return 0;
00589 }
00590 
00591 int Edit::shift_end_out(int edit_mode, 
00592         int64_t newposition, 
00593         int64_t oldposition,
00594         int edit_edits,
00595         int edit_labels,
00596         int edit_plugins,
00597         Edits *trim_edits)
00598 {
00599         int64_t cut_length = newposition - oldposition;
00600         int64_t endsource = get_source_end(startsource + length + cut_length);
00601 
00602 // check end of edit against end of source file
00603         if(endsource > 0 && startsource + length + cut_length > endsource)
00604                 cut_length = endsource - startsource - length;
00605 
00606 //printf("Edit::shift_end_out 1 %lld %d %d %d\n", oldposition, newposition, this->length, cut_length);
00607         if(edit_mode == MOVE_ALL_EDITS)
00608         {
00609 // Extend length
00610                 this->length += cut_length;
00611 
00612 // Effects are shifted in length extension
00613                 if(edit_plugins)
00614                         edits->shift_effects_recursive(oldposition /* startproject */, 
00615                                 cut_length);
00616                 edits->shift_keyframes_recursive(oldposition /* startproject */, 
00617                         cut_length);
00618 
00619                 for(Edit* current_edit = next; current_edit; current_edit = current_edit->next)
00620                 {
00621                         current_edit->startproject += cut_length;
00622                 }
00623         }
00624         else
00625         if(edit_mode == MOVE_ONE_EDIT)
00626         {
00627                 if(next)
00628                 {
00629                         if(cut_length < next->length)
00630                         {
00631                                 length += cut_length;
00632                                 next->startproject += cut_length;
00633                                 next->startsource += cut_length;
00634                                 next->length -= cut_length;
00635 //printf("Edit::shift_end_out 2 %d\n", cut_length);
00636                         }
00637                         else
00638                         {
00639                                 cut_length = next->length;
00640                                 next->length = 0;
00641                                 length += cut_length;
00642                         }
00643                 }
00644                 else
00645                 {
00646                         length += cut_length;
00647                 }
00648         }
00649         else
00650         if(edit_mode == MOVE_NO_EDITS)
00651         {
00652                 startsource += cut_length;
00653         }
00654         return 0;
00655 }
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
00685 int Edit::popup_transition(float view_start, float zoom_units, int cursor_x, int cursor_y)
00686 {
00687         int64_t left, right, left_unit, right_unit;
00688         if(!transition) return 0;
00689         get_handle_parameters(left, right, left_unit, right_unit, view_start, zoom_units);
00690 
00691         if(cursor_x > left && cursor_x < right)
00692         {
00693 //              transition->popup_transition(cursor_x, cursor_y);
00694                 return 1;
00695         }
00696         return 0;
00697 }
00698 
00699 int Edit::select_handle(float view_start, float zoom_units, int cursor_x, int cursor_y, int64_t &selection)
00700 {
00701         int64_t left, right, left_unit, right_unit;
00702         get_handle_parameters(left, right, left_unit, right_unit, view_start, zoom_units);
00703 
00704         int64_t pixel1, pixel2;
00705         pixel1 = left;
00706         pixel2 = pixel1 + 10;
00707 
00708 // test left edit
00709 // cursor_x is faked in acanvas
00710         if(cursor_x >= pixel1 && cursor_x <= pixel2)
00711         {
00712                 selection = left_unit;
00713                 return 1;     // left handle
00714         }
00715 
00716         int64_t endproject = startproject + length;
00717         pixel2 = right;
00718         pixel1 = pixel2 - 10;
00719 
00720 // test right edit      
00721         if(cursor_x >= pixel1 && cursor_x <= pixel2)
00722         {
00723                 selection = right_unit;
00724                 return 2;     // right handle
00725         }
00726         return 0;
00727 }
00728 

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