X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fedl.C;h=d3f19b2353652f04390b1fcbc6be766afb550f0e;hp=e50474042e7fe9052740960e35511f2911a38780;hb=976d56536456148f6d14a2c12630c20e367abbe1;hpb=9e779f63289f91f132569a933ddc93f4c1487751 diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index e5047404..d3f19b23 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -25,21 +25,25 @@ #include "autoconf.h" #include "automation.h" #include "awindowgui.inc" -#include "bcsignals.h" -#include "clip.h" #include "bccmodels.h" #include "bchash.h" +#include "bcsignals.h" +#include "clip.h" +#include "cstrdup.h" +#include "clipedls.h" #include "edits.h" #include "edl.h" #include "edlsession.h" #include "filexml.h" +#include "floatauto.h" +#include "floatautos.h" #include "guicast.h" #include "indexstate.h" #include "interlacemodes.h" #include "labels.h" #include "localsession.h" +#include "maskautos.h" #include "mutex.h" -#include "nestededls.h" #include "panauto.h" #include "panautos.h" #include "playbackconfig.h" @@ -59,10 +63,6 @@ -Mutex* EDL::id_lock = 0; - - - EDL::EDL(EDL *parent_edl) : Indexable(0) { @@ -70,15 +70,7 @@ EDL::EDL(EDL *parent_edl) tracks = 0; labels = 0; local_session = 0; -// vwindow_edl = 0; -// vwindow_edl_shared = 0; - folders.set_array_delete(); - -// persistent for now -// new_folder(CLIP_FOLDER); -// new_folder(MEDIA_FOLDER); - id = next_id(); path[0] = 0; } @@ -87,60 +79,25 @@ EDL::EDL(EDL *parent_edl) EDL::~EDL() { - if(tracks) - { - delete tracks; - } - if(labels) - { - delete labels; - } - - if(local_session) - { - delete local_session; - } - - + delete tracks; + delete labels; + delete local_session; remove_vwindow_edls(); - -// if(vwindow_edl && !vwindow_edl_shared) -// vwindow_edl->Garbage::remove_user(); - - if(!parent_edl) - { + if( !parent_edl ) { delete assets; delete session; } - - folders.remove_all_objects(); - for(int i = 0; i < clips.size(); i++) - clips.get(i)->Garbage::remove_user(); - clips.remove_all(); - delete nested_edls; } - void EDL::create_objects() { tracks = new Tracks(this); - if(!parent_edl) - { - assets = new Assets(this); - session = new EDLSession(this); - } - else - { - assets = parent_edl->assets; - session = parent_edl->session; - } - + assets = !parent_edl ? new Assets(this) : parent_edl->assets; + session = !parent_edl ? new EDLSession(this) : parent_edl->session; local_session = new LocalSession(this); labels = new Labels(this, "LABELS"); - nested_edls = new NestedEDLs; -// last_playback_position = 0; } EDL& EDL::operator=(EDL &edl) @@ -152,7 +109,7 @@ printf("EDL::operator= 1\n"); int EDL::load_defaults(BC_Hash *defaults) { - if(!parent_edl) + if( !parent_edl ) session->load_defaults(defaults); local_session->load_defaults(defaults); @@ -161,7 +118,7 @@ int EDL::load_defaults(BC_Hash *defaults) int EDL::save_defaults(BC_Hash *defaults) { - if(!parent_edl) + if( !parent_edl ) session->save_defaults(defaults); local_session->save_defaults(defaults); @@ -177,29 +134,23 @@ void EDL::boundaries() int EDL::create_default_tracks() { - for(int i = 0; i < session->video_tracks; i++) - { + for( int i=0; ivideo_tracks; ++i ) { tracks->add_video_track(0, 0); } - for(int i = 0; i < session->audio_tracks; i++) - { + for( int i=0; iaudio_tracks; ++i ) { tracks->add_audio_track(0, 0); } return 0; } -int EDL::load_xml(FileXML *file, - uint32_t load_flags) +int EDL::load_xml(FileXML *file, uint32_t load_flags) { int result = 0; -// Track numbering offset for replacing undo data. - int track_offset = 0; // Clear objects folders.remove_all_objects(); - if((load_flags & LOAD_ALL) == LOAD_ALL) - { + if( (load_flags & LOAD_ALL) == LOAD_ALL ) { remove_vwindow_edls(); } @@ -212,160 +163,172 @@ int EDL::load_xml(FileXML *file, // The parent_edl test is required to make EDL loading work because // when loading an EDL the EDL tag is already read by the parent. - if(!parent_edl) - { - do{ + if( !parent_edl ) { + do { result = file->read_tag(); - }while(!result && + } while(!result && !file->tag.title_is("XML") && !file->tag.title_is("EDL")); } + return result ? result : read_xml(file, load_flags); +} + +int EDL::read_xml(FileXML *file, uint32_t load_flags) +{ + int result = 0; +// Track numbering offset for replacing undo data. + int track_offset = 0; - if(!result) - { // Get path for backups -// path[0] = 0; - file->tag.get_property("path", path); + file->tag.get_property("path", path); // Erase everything - if((load_flags & LOAD_ALL) == LOAD_ALL || - (load_flags & LOAD_EDITS) == LOAD_EDITS) - { - while(tracks->last) delete tracks->last; - } + if( (load_flags & LOAD_ALL) == LOAD_ALL || + (load_flags & LOAD_EDITS) == LOAD_EDITS ) { + while(tracks->last) delete tracks->last; + } - if((load_flags & LOAD_ALL) == LOAD_ALL) - { - for(int i = 0; i < clips.size(); i++) - clips.get(i)->Garbage::remove_user(); - clips.remove_all(); - } + if( (load_flags & LOAD_ALL) == LOAD_ALL ) { + clips.clear(); + mixers.remove_all_objects(); + } - if(load_flags & LOAD_TIMEBAR) - { - while(labels->last) delete labels->last; - local_session->unset_inpoint(); - local_session->unset_outpoint(); - } + if( load_flags & LOAD_TIMEBAR ) { + while(labels->last) delete labels->last; + local_session->unset_inpoint(); + local_session->unset_outpoint(); + } // This was originally in LocalSession::load_xml - if(load_flags & LOAD_SESSION) - { - local_session->clipboard_length = 0; - } + if( load_flags & LOAD_SESSION ) { + local_session->clipboard_length = 0; + } - do{ - result = file->read_tag(); + do { + result = file->read_tag(); - if(!result) - { - if(file->tag.title_is("/XML") || - file->tag.title_is("/EDL") || - file->tag.title_is("/CLIP_EDL") || - file->tag.title_is("/VWINDOW_EDL")) - { - result = 1; - } - else - if(file->tag.title_is("CLIPBOARD")) - { - local_session->clipboard_length = - file->tag.get_property("LENGTH", (double)0); - } - else - if(file->tag.title_is("VIDEO")) - { - if((load_flags & LOAD_VCONFIG) && - (load_flags & LOAD_SESSION)) - session->load_video_config(file, 0, load_flags); - } - else - if(file->tag.title_is("AUDIO")) - { - if((load_flags & LOAD_ACONFIG) && - (load_flags & LOAD_SESSION)) - session->load_audio_config(file, 0, load_flags); - } + if( !result ) { + if( file->tag.title_is("/XML") || + file->tag.title_is("/EDL") || + file->tag.title_is("/CLIP_EDL") || + file->tag.title_is("/NESTED_EDL") || + file->tag.title_is("/VWINDOW_EDL") ) { + result = 1; + } + else + if( file->tag.title_is("CLIPBOARD") ) { + local_session->clipboard_length = + file->tag.get_property("LENGTH", (double)0); + } + else + if( file->tag.title_is("VIDEO") ) { + if( (load_flags & LOAD_VCONFIG) && + (load_flags & LOAD_SESSION) ) + session->load_video_config(file, 0, load_flags); else - if(file->tag.title_is("FOLDER")) - { - char folder[BCTEXTLEN]; - strcpy(folder, file->read_text()); - new_folder(folder); - } + result = file->skip_tag(); + } + else + if( file->tag.title_is("AUDIO") ) { + if( (load_flags & LOAD_ACONFIG) && + (load_flags & LOAD_SESSION) ) + session->load_audio_config(file, 0, load_flags); else - if(file->tag.title_is("ASSETS")) - { - if(load_flags & LOAD_ASSETS) - assets->load(file, load_flags); - } + result = file->skip_tag(); + } + else + if( file->tag.title_is("FOLDER") ) { + char folder[BCTEXTLEN]; + strcpy(folder, file->read_text()); + new_folder(folder); + } + else + if( file->tag.title_is("MIXERS") ) { + if( (load_flags & LOAD_SESSION) ) + mixers.load(file); else - if(file->tag.title_is(labels->xml_tag)) - { - if(load_flags & LOAD_TIMEBAR) - labels->load(file, load_flags); - } + result = file->skip_tag(); + } + else + if( file->tag.title_is("ASSETS") ) { + if( load_flags & LOAD_ASSETS ) + assets->load(file, load_flags); else - if(file->tag.title_is("LOCALSESSION")) - { - if((load_flags & LOAD_SESSION) || - (load_flags & LOAD_TIMEBAR)) - local_session->load_xml(file, load_flags); - } + result = file->skip_tag(); + } + else + if( file->tag.title_is(labels->xml_tag) ) { + if( load_flags & LOAD_TIMEBAR ) + labels->load(file, load_flags); else - if(file->tag.title_is("SESSION")) - { - if((load_flags & LOAD_SESSION) && - !parent_edl) - session->load_xml(file, 0, load_flags); - } + result = file->skip_tag(); + } + else + if( file->tag.title_is("LOCALSESSION") ) { + if( (load_flags & LOAD_SESSION) || + (load_flags & LOAD_TIMEBAR) ) + local_session->load_xml(file, load_flags); else - if(file->tag.title_is("TRACK")) - { - tracks->load(file, track_offset, load_flags); - } + result = file->skip_tag(); + } + else + if( file->tag.title_is("SESSION") ) { + if( (load_flags & LOAD_SESSION) && + !parent_edl ) + session->load_xml(file, 0, load_flags); else + result = file->skip_tag(); + } + else + if( file->tag.title_is("TRACK") ) { + tracks->load(file, track_offset, load_flags); + } + else // Sub EDL. // Causes clip creation to fail because that involves an opening EDL tag. - if(file->tag.title_is("CLIP_EDL") && !parent_edl) - { - EDL *new_edl = new EDL(this); - new_edl->create_objects(); - new_edl->load_xml(file, LOAD_ALL); - - if((load_flags & LOAD_ALL) == LOAD_ALL) - clips.append(new_edl); - else - new_edl->Garbage::remove_user(); - } - else - if(file->tag.title_is("VWINDOW_EDL") && !parent_edl) - { - EDL *new_edl = new EDL(this); - new_edl->create_objects(); - new_edl->load_xml(file, LOAD_ALL); + if( file->tag.title_is("CLIP_EDL") && !parent_edl ) { + EDL *new_edl = new EDL(this); + new_edl->create_objects(); + new_edl->read_xml(file, LOAD_ALL); + if( (load_flags & LOAD_ALL) == LOAD_ALL ) + clips.add_clip(new_edl); + new_edl->remove_user(); + } + else + if( file->tag.title_is("NESTED_EDL") ) { + EDL *nested_edl = new EDL; + nested_edl->create_objects(); + nested_edl->read_xml(file, LOAD_ALL); + if( (load_flags & LOAD_ALL) == LOAD_ALL ) + nested_edls.get_nested(nested_edl); + nested_edl->remove_user(); + } + else + if( file->tag.title_is("VWINDOW_EDL") && !parent_edl ) { + EDL *new_edl = new EDL(this); + new_edl->create_objects(); + new_edl->read_xml(file, LOAD_ALL); - if((load_flags & LOAD_ALL) == LOAD_ALL) - { -// if(vwindow_edl && !vwindow_edl_shared) -// vwindow_edl->Garbage::remove_user(); + if( (load_flags & LOAD_ALL) == LOAD_ALL ) { +// if( vwindow_edl && !vwindow_edl_shared ) +// vwindow_edl->remove_user(); // vwindow_edl_shared = 0; // vwindow_edl = new_edl; - append_vwindow_edl(new_edl, 0); + append_vwindow_edl(new_edl, 0); - } - else + } + else // Discard if not replacing EDL - { - new_edl->Garbage::remove_user(); - new_edl = 0; - } + { + new_edl->remove_user(); + new_edl = 0; } } - }while(!result); - } + } + } while(!result); + boundaries(); //dump(); @@ -376,30 +339,21 @@ int EDL::load_xml(FileXML *file, // It is a "" if complete names should be used. // Called recursively by copy for clips, thus the string can't be terminated. // The string is not terminated in this call. -int EDL::save_xml(FileXML *file, - const char *output_path, - int is_clip, - int is_vwindow) -{ - copy(0, - tracks->total_length(), - 1, - is_clip, - is_vwindow, - file, - output_path, - 0); +int EDL::save_xml(FileXML *file, const char *output_path) +{ + copy(1, file, output_path, 0); return 0; } int EDL::copy_all(EDL *edl) { - if(this == edl) return 0; + if( this == edl ) return 0; update_index(edl); - nested_edls->clear(); copy_session(edl); copy_assets(edl); copy_clips(edl); + copy_nested(edl); + copy_mixers(edl); tracks->copy_from(edl->tracks); labels->copy_from(edl->labels); return 0; @@ -407,67 +361,65 @@ int EDL::copy_all(EDL *edl) void EDL::copy_clips(EDL *edl) { - if(this == edl) return; + if( this == edl ) return; remove_vwindow_edls(); -// if(vwindow_edl && !vwindow_edl_shared) -// vwindow_edl->Garbage::remove_user(); +// if( vwindow_edl && !vwindow_edl_shared ) +// vwindow_edl->remove_user(); // vwindow_edl = 0; // vwindow_edl_shared = 0; - for(int i = 0; i < edl->total_vwindow_edls(); i++) - { + for( int i=0; itotal_vwindow_edls(); ++i ) { EDL *new_edl = new EDL(this); new_edl->create_objects(); new_edl->copy_all(edl->get_vwindow_edl(i)); append_vwindow_edl(new_edl, 0); } - for(int i = 0; i < clips.size(); i++) - clips.get(i)->Garbage::remove_user(); - clips.remove_all(); - for(int i = 0; i < edl->clips.total; i++) - { - add_clip(edl->clips.values[i]); - } + clips.clear(); + for( int i=0; iclips.size(); ++i ) add_clip(edl->clips[i]); +} + +void EDL::copy_nested(EDL *edl) +{ + if( this == edl ) return; + nested_edls.copy_nested(edl->nested_edls); } void EDL::copy_assets(EDL *edl) { - if(this == edl) return; + if( this == edl ) return; - if(!parent_edl) - { + if( !parent_edl ) { assets->copy_from(edl->assets); } } +void EDL::copy_mixers(EDL *edl) +{ + if( this == edl ) return; + mixers.copy_from(edl->mixers); +} + void EDL::copy_session(EDL *edl, int session_only) { - if(this == edl) return; + if( this == edl ) return; - if(!session_only) - { + if( !session_only ) { strcpy(this->path, edl->path); //printf("EDL::copy_session %p %s\n", this, this->path); folders.remove_all_objects(); - for(int i = 0; i < edl->folders.total; i++) - { - char *new_folder; - folders.append(new_folder = new char[strlen(edl->folders.values[i]) + 1]); - strcpy(new_folder, edl->folders.values[i]); - } + for( int i=0; ifolders.size(); ++i ) + folders.append(cstrdup(edl->folders[i])); } - if(!parent_edl) - { + if( !parent_edl ) { session->copy(edl->session); } - if(!session_only) - { + if( !session_only ) { local_session->copy_from(edl->local_session); } } @@ -486,37 +438,22 @@ int EDL::copy_assets(double start, file->append_newline(); // Copy everything for a save - if(all) - { - for(Asset *asset = assets->first; - asset; - asset = asset->next) - { + if( all ) { + for( Asset *asset=assets->first; asset; asset=asset->next ) { asset_list.append(asset); } } - else + else { // Copy just the ones being used. - { - for(current = tracks->first; - current; - current = NEXT) - { - if(current->record) - { - current->copy_assets(start, - end, - &asset_list); - } + for( current = tracks->first; current; current = NEXT ) { + if( !current->record ) continue; + current->copy_assets(start, end, &asset_list); } } // Paths relativised here - for(int i = 0; i < asset_list.total; i++) - { - asset_list.values[i]->write(file, - 0, - output_path); + for( int i=0; iwrite(file, 0, output_path); } file->tag.set_title("/ASSETS"); @@ -526,39 +463,68 @@ int EDL::copy_assets(double start, return 0; } -int EDL::copy(double start, - double end, - int all, - int is_clip, - int is_vwindow, - FileXML *file, - const char *output_path, - int rewind_it) + +int EDL::copy(double start, double end, int all, + FileXML *file, const char *output_path, int rewind_it) { -//printf("EDL::copy 1\n"); -// begin file - if(is_clip) - file->tag.set_title("CLIP_EDL"); - else - if(is_vwindow) - file->tag.set_title("VWINDOW_EDL"); - else - { - file->tag.set_title("EDL"); - file->tag.set_property("VERSION", CINELERRA_VERSION); + file->tag.set_title("EDL"); + file->tag.set_property("VERSION", CINELERRA_VERSION); // Save path for restoration of the project title from a backup. - if(this->path[0]) - { - file->tag.set_property("PATH", path); - } - } + if( this->path[0] ) file->tag.set_property("PATH", path); + return copy(start, end, all, + "/EDL", file, output_path, rewind_it); +} +int EDL::copy(int all, FileXML *file, const char *output_path, int rewind_it) +{ + return copy(0, tracks->total_length(), all, file, output_path, rewind_it); +} + +int EDL::copy_clip(double start, double end, int all, + FileXML *file, const char *output_path, int rewind_it) +{ + file->tag.set_title("CLIP_EDL"); + return copy(start, end, all, + "/CLIP_EDL", file, output_path, rewind_it); +} +int EDL::copy_clip(int all, FileXML *file, const char *output_path, int rewind_it) +{ + return copy_clip(0, tracks->total_length(), all, file, output_path, rewind_it); +} + +int EDL::copy_nested_edl(double start, double end, int all, + FileXML *file, const char *output_path, int rewind_it) +{ + file->tag.set_title("NESTED_EDL"); + if( this->path[0] ) file->tag.set_property("PATH", path); + return copy(start, end, all, + "/NESTED_EDL", file, output_path, rewind_it); +} +int EDL::copy_nested_edl(int all, FileXML *file, const char *output_path, int rewind_it) +{ + return copy_nested_edl(0, tracks->total_length(), all, file, output_path, rewind_it); +} + +int EDL::copy_vwindow_edl(double start, double end, int all, + FileXML *file, const char *output_path, int rewind_it) +{ + file->tag.set_title("VWINDOW_EDL"); + return copy(start, end, all, + "/VWINDOW_EDL", file, output_path, rewind_it); +} +int EDL::copy_vwindow_edl(int all, FileXML *file, const char *output_path, int rewind_it) +{ + return copy_vwindow_edl(0, tracks->total_length(), all, file, output_path, rewind_it); +} + +int EDL::copy(double start, double end, int all, + const char *closer, FileXML *file, + const char *output_path, int rewind_it) +{ file->append_tag(); file->append_newline(); - // Set clipboard samples only if copying to clipboard - if(!all) - { + if( !all ) { file->tag.set_title("CLIPBOARD"); file->tag.set_property("LENGTH", end - start); file->append_tag(); @@ -584,91 +550,126 @@ int EDL::copy(double start, session->save_audio_config(file); // Folders - for(int i = 0; i < folders.total; i++) - { + for( int i=0; itag.set_title("FOLDER"); file->append_tag(); - file->append_text(folders.values[i]); + file->append_text(folders[i]); file->tag.set_title("/FOLDER"); file->append_tag(); file->append_newline(); } -// Media -// Don't replicate all assets for every clip. -// The assets for the clips are probably in the mane EDL. - if(!is_clip) - copy_assets(start, - end, - file, - all, - output_path); + if( !parent_edl ) + copy_assets(start, end, file, all, output_path); + + for( int i=0; icopy_nested_edl(0, tracks->total_length(), 1, + file, output_path, 0); // Clips // Don't want this if using clipboard - if(all) - { - for(int i = 0; i < total_vwindow_edls(); i++) - { - get_vwindow_edl(i)->save_xml(file, - output_path, - 0, - 1); - } + if( all ) { + for( int i=0; icopy_vwindow_edl(1, file, output_path, 0); - for(int i = 0; i < clips.total; i++) - clips.values[i]->save_xml(file, - output_path, - 1, - 0); + for( int i=0; icopy_clip(1, file, output_path, 0); + + mixers.save(file); } file->append_newline(); file->append_newline(); } - -//printf("EDL::copy 1\n"); - labels->copy(start, end, file); -//printf("EDL::copy 1\n"); tracks->copy(start, end, all, file, output_path); -//printf("EDL::copy 2\n"); // terminate file - if(is_clip) - file->tag.set_title("/CLIP_EDL"); - else - if(is_vwindow) - file->tag.set_title("/VWINDOW_EDL"); - else - file->tag.set_title("/EDL"); + file->tag.set_title(closer); file->append_tag(); file->append_newline(); - // For editing operations we want to rewind it for immediate pasting. // For clips and saving to disk leave it alone. - if(rewind_it) - { + if( rewind_it ) { file->terminate_string(); file->rewind(); } return 0; } +void EDL::copy_indexables(EDL *edl) +{ + for( Track *track=edl->tracks->first; track; track=track->next ) { + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + if( edit->asset ) + assets->update(edit->asset); + if( edit->nested_edl ) + nested_edls.get_nested(edit->nested_edl); + } + } +} + +EDL *EDL::new_nested(EDL *edl, const char *path) +{ + EDL *nested = new EDL; // no parent for nested edl + nested->create_objects(); + nested->copy_session(edl); + nested->set_path(path); + nested->update_index(edl); + nested->copy_indexables(edl); + nested->tracks->copy_from(edl->tracks); + nested_edls.append(nested); + return nested; +} + +EDL *EDL::create_nested_clip(EDL *nested) +{ + EDL *new_edl = new EDL(this); // parent for clip edl + new_edl->create_objects(); + new_edl->create_nested(nested); + return new_edl; +} + +void EDL::create_nested(EDL *nested) +{ +// Keep frame rate, sample rate, and output size unchanged. +// Nest all video & audio outputs + session->video_tracks = 1; + session->audio_tracks = nested->session->audio_channels; + create_default_tracks(); + insert_asset(0, nested, 0, 0, 0); +} + +void EDL::retrack() +{ + int min_w = session->output_w, min_h = session->output_h; + for( Track *track=tracks->first; track!=0; track=track->next ) { + if( track->data_type != TRACK_VIDEO ) continue; + int w = min_w, h = min_h; + for( Edit *current=track->edits->first; current!=0; current=NEXT ) { + Indexable* indexable = current->get_source(); + if( !indexable ) continue; + int edit_w = indexable->get_w(), edit_h = indexable->get_h(); + if( w < edit_w ) w = edit_w; + if( h < edit_h ) h = edit_h; + } + if( track->track_w == w && track->track_h == h ) continue; + ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])-> + translate_masks( (w - track->track_w) / 2, (h - track->track_h) / 2); + track->track_w = w; track->track_h = h; + } +} + void EDL::rechannel() { - for(Track *current = tracks->first; current; current = NEXT) - { - if(current->data_type == TRACK_AUDIO) - { + for( Track *current=tracks->first; current; current=NEXT ) { + if( current->data_type == TRACK_AUDIO ) { PanAutos *autos = (PanAutos*)current->automation->autos[AUTOMATION_PAN]; ((PanAuto*)autos->default_auto)->rechannel(); - for(PanAuto *keyframe = (PanAuto*)autos->first; - keyframe; - keyframe = (PanAuto*)keyframe->next) - { + for( PanAuto *keyframe = (PanAuto*)autos->first; + keyframe; keyframe = (PanAuto*)keyframe->next ) { keyframe->rechannel(); } } @@ -677,10 +678,8 @@ void EDL::rechannel() void EDL::resample(double old_rate, double new_rate, int data_type) { - for(Track *current = tracks->first; current; current = NEXT) - { - if(current->data_type == data_type) - { + for( Track *current=tracks->first; current; current=NEXT ) { + if( current->data_type == data_type ) { current->resample(old_rate, new_rate); } } @@ -690,11 +689,9 @@ void EDL::resample(double old_rate, double new_rate, int data_type) void EDL::synchronize_params(EDL *edl) { local_session->synchronize_params(edl->local_session); - for(Track *this_track = tracks->first, *that_track = edl->tracks->first; - this_track && that_track; - this_track = this_track->next, - that_track = that_track->next) - { + for( Track *this_track=tracks->first, *that_track=edl->tracks->first; + this_track && that_track; + this_track=this_track->next, that_track=that_track->next ) { this_track->synchronize_params(that_track); } } @@ -705,8 +702,7 @@ int EDL::trim_selection(double start, int edit_plugins, int edit_autos) { - if(start != end) - { + if( start != end ) { // clear the data clear(0, start, @@ -725,16 +721,9 @@ int EDL::trim_selection(double start, int EDL::equivalent(double position1, double position2) { - double threshold = (double).5 / session->frame_rate; - if(session->cursor_on_frames) - threshold = (double).5 / session->frame_rate; - else - threshold = (double)1 / session->sample_rate; - - if(fabs(position2 - position1) < threshold) - return 1; - else - return 0; + double threshold = session->cursor_on_frames ? + 0.5 / session->frame_rate : 1.0 / session->sample_rate; + return fabs(position2 - position1) < threshold ? 1 : 0; } double EDL::equivalent_output(EDL *edl) @@ -746,50 +735,53 @@ double EDL::equivalent_output(EDL *edl) } -void EDL::set_path(char *path) +void EDL::set_path(const char *path) { + if( &this->path[0] == path ) return; strcpy(this->path, path); } void EDL::set_inpoint(double position) { - if(equivalent(local_session->get_inpoint(), position) && - local_session->get_inpoint() >= 0) - { + if( equivalent(local_session->get_inpoint(), position) && + local_session->get_inpoint() >= 0 ) { local_session->unset_inpoint(); } - else - { + else { local_session->set_inpoint(align_to_frame(position, 0)); - if(local_session->get_outpoint() <= local_session->get_inpoint()) + if( local_session->get_outpoint() <= local_session->get_inpoint() ) local_session->unset_outpoint(); } } void EDL::set_outpoint(double position) { - if(equivalent(local_session->get_outpoint(), position) && - local_session->get_outpoint() >= 0) - { + if( equivalent(local_session->get_outpoint(), position) && + local_session->get_outpoint() >= 0 ) { local_session->unset_outpoint(); } - else - { + else { local_session->set_outpoint(align_to_frame(position, 0)); - if(local_session->get_inpoint() >= local_session->get_outpoint()) + if( local_session->get_inpoint() >= local_session->get_outpoint() ) local_session->unset_inpoint(); } } +void EDL::unset_inoutpoint() +{ + local_session->unset_inpoint(); + local_session->unset_outpoint(); +} -int EDL::clear(double start, - double end, - int clear_labels, - int clear_plugins, - int edit_autos) +int EDL::blade(double position) { - if(start == end) - { + return tracks->blade(position); +} + +int EDL::clear(double start, double end, + int clear_labels, int clear_plugins, int edit_autos) +{ + if( start == end ) { double distance = 0; tracks->clear_handle(start, end, @@ -797,17 +789,16 @@ int EDL::clear(double start, clear_labels, clear_plugins, edit_autos); - if(clear_labels && distance > 0) + if( clear_labels && distance > 0 ) labels->paste_silence(start, start + distance); } - else - { + else { tracks->clear(start, end, clear_plugins, edit_autos); - if(clear_labels) + if( clear_labels ) labels->clear(start, end, 1); @@ -867,7 +858,7 @@ void EDL::paste_silence(double start, int edit_plugins, int edit_autos) { - if(edit_labels) + if( edit_labels ) labels->paste_silence(start, end); tracks->paste_silence(start, end, @@ -878,60 +869,43 @@ void EDL::paste_silence(double start, void EDL::remove_from_project(ArrayList *clips) { - for(int i = 0; i < clips->size(); i++) - { - for(int j = 0; j < this->clips.size(); j++) - { - if(this->clips.get(j) == clips->values[i]) - { - EDL *clip = this->clips.get(j); - this->clips.remove(clip); - clip->Garbage::remove_user(); - } - } + for( int i=0; isize(); ++i ) { + this->clips.remove_clip(clips->get(i)); } } void EDL::remove_from_project(ArrayList *assets) { // Remove from clips - if(!parent_edl) - for(int j = 0; j < clips.total; j++) - { - clips.values[j]->remove_from_project(assets); + if( !parent_edl ) + for( int j=0; jremove_from_project(assets); } // Remove from VWindow EDLs - for(int i = 0; i < total_vwindow_edls(); i++) + for( int i=0; iremove_from_project(assets); - for(int i = 0; i < assets->size(); i++) - { + for( int i=0; isize(); ++i ) { // Remove from tracks - for(Track *track = tracks->first; track; track = track->next) - { + for( Track *track=tracks->first; track; track=track->next ) { track->remove_asset(assets->get(i)); } // Remove from assets - if(!parent_edl && assets->get(i)->is_asset) - { + if( !parent_edl && assets->get(i)->is_asset ) { this->assets->remove_asset((Asset*)assets->get(i)); } else - if(!parent_edl && !assets->get(i)->is_asset) - { - this->nested_edls->remove_edl((EDL*)assets->get(i)); + if( !parent_edl && !assets->get(i)->is_asset ) { + this->nested_edls.remove_clip((EDL*)assets->get(i)); } } } void EDL::update_assets(EDL *src) { - for(Asset *current = src->assets->first; - current; - current = NEXT) - { + for( Asset *current=src->assets->first; current; current=NEXT ) { assets->update(current); } } @@ -939,10 +913,7 @@ void EDL::update_assets(EDL *src) int EDL::get_tracks_height(Theme *theme) { int total_pixels = 0; - for(Track *current = tracks->first; - current; - current = NEXT) - { + for( Track *current=tracks->first; current; current=NEXT ) { total_pixels += current->vertical_span(theme); } return total_pixels; @@ -951,12 +922,9 @@ int EDL::get_tracks_height(Theme *theme) int64_t EDL::get_tracks_width() { int64_t total_pixels = 0; - for(Track *current = tracks->first; - current; - current = NEXT) - { + for( Track *current=tracks->first; current; current=NEXT ) { int64_t pixels = current->horizontal_span(); - if(pixels > total_pixels) total_pixels = pixels; + if( pixels > total_pixels ) total_pixels = pixels; } //printf("EDL::get_tracks_width %d\n", total_pixels); return total_pixels; @@ -964,24 +932,24 @@ int64_t EDL::get_tracks_width() // int EDL::calculate_output_w(int single_channel) // { -// if(single_channel) return session->output_w; +// if( single_channel ) return session->output_w; // // int widest = 0; -// for(int i = 0; i < session->video_channels; i++) +// for( int i=0; ivideo_channels; ++i ) // { -// if(session->vchannel_x[i] + session->output_w > widest) widest = session->vchannel_x[i] + session->output_w; +// if( session->vchannel_x[i] + session->output_w > widest ) widest = session->vchannel_x[i] + session->output_w; // } // return widest; // } // // int EDL::calculate_output_h(int single_channel) // { -// if(single_channel) return session->output_h; +// if( single_channel ) return session->output_h; // // int tallest = 0; -// for(int i = 0; i < session->video_channels; i++) +// for( int i=0; ivideo_channels; ++i ) // { -// if(session->vchannel_y[i] + session->output_h > tallest) tallest = session->vchannel_y[i] + session->output_h; +// if( session->vchannel_y[i] + session->output_h > tallest ) tallest = session->vchannel_y[i] + session->output_h; // } // return tallest; // } @@ -989,19 +957,10 @@ int64_t EDL::get_tracks_width() // Get the total output size scaled to aspect ratio void EDL::calculate_conformed_dimensions(int single_channel, float &w, float &h) { - w = session->output_w; - h = session->output_h; - - if((float)session->output_w / session->output_h > get_aspect_ratio()) - { - h = (float)h * - (session->output_w / get_aspect_ratio() / session->output_h); - } + if( (float)session->output_w / session->output_h > get_aspect_ratio() ) + h = (w = session->output_w) / get_aspect_ratio(); else - { - w = (float)w * - (h * get_aspect_ratio() / session->output_w); - } + w = (h = session->output_h) * get_aspect_ratio(); } float EDL::get_aspect_ratio() @@ -1011,7 +970,7 @@ float EDL::get_aspect_ratio() int EDL::dump(FILE *fp) { - if(parent_edl) + if( parent_edl ) fprintf(fp,"CLIP\n"); else fprintf(fp,"EDL\n"); @@ -1022,15 +981,13 @@ int EDL::dump(FILE *fp) local_session->get_selectionend(1), local_session->loop_start, local_session->loop_end); - for(int i = 0; i < TOTAL_PANES; i++) - { + for( int i=0; iview_start[i], local_session->track_start[i]); } - if(!parent_edl) - { + if( !parent_edl ) { fprintf(fp,"audio_channels: %d audio_tracks: %d sample_rate: %jd\n", session->audio_channels, session->audio_tracks, @@ -1039,9 +996,9 @@ int EDL::dump(FILE *fp) " video_tracks: %d\n" " frame_rate: %.2f\n" " frames_per_foot: %.2f\n" - " output_w: %d\n" - " output_h: %d\n" - " aspect_w: %f\n" + " output_w: %d\n" + " output_h: %d\n" + " aspect_w: %f\n" " aspect_h: %f\n" " color_model: %d\n", session->video_channels, @@ -1049,26 +1006,27 @@ int EDL::dump(FILE *fp) session->frame_rate, session->frames_per_foot, session->output_w, - session->output_h, - session->aspect_w, - session->aspect_h, + session->output_h, + session->aspect_w, + session->aspect_h, session->color_model); - fprintf(fp," CLIPS\n"); - fprintf(fp," total: %d\n", clips.total); - - for(int i = 0; i < clips.total; i++) - { + fprintf(fp," CLIPS"); + fprintf(fp," total: %d\n", clips.size()); + for( int i=0; idump(fp); + clips[i]->dump(fp); fprintf(fp,"\n\n"); } + fprintf(fp," NESTED_EDLS"); + fprintf(fp," total: %d\n", nested_edls.size()); + for( int i=0; ipath); - fprintf(fp," VWINDOW EDLS\n"); + fprintf(fp," VWINDOW EDLS"); fprintf(fp," total: %d\n", total_vwindow_edls()); - for(int i = 0; i < total_vwindow_edls(); i++) - { + for( int i=0; ilocal_session->clip_title); } @@ -1103,8 +1061,8 @@ void EDL::insert_asset(Asset *asset, Asset *new_asset = 0; EDL *new_nested_edl = 0; - if(asset) new_asset = assets->update(asset); - if(nested_edl) new_nested_edl = nested_edls->get_copy(nested_edl); + if( asset ) new_asset = assets->update(asset); + if( nested_edl ) new_nested_edl = nested_edls.get_nested(nested_edl); // Paste video int vtrack = 0; @@ -1116,18 +1074,15 @@ void EDL::insert_asset(Asset *asset, int layers = 0; int channels = 0; - if(new_nested_edl) - { - length = new_nested_edl->tracks->total_playable_length(); + if( new_nested_edl ) { + length = new_nested_edl->tracks->total_length(); layers = 1; channels = new_nested_edl->session->audio_channels; } - if(new_asset) - { + if( new_asset ) { // Insert 1 frame for undefined length - if(new_asset->video_length < 0) - { + if( new_asset->video_length < 0 ) { length = session->si_useduration ? session->si_duration : 1.0 / session->frame_rate; @@ -1141,30 +1096,17 @@ void EDL::insert_asset(Asset *asset, channels = new_asset->channels; } - for( ; - current && vtrack < layers; - current = NEXT) - { - if(!current->record || - current->data_type != TRACK_VIDEO) - continue; - - current->insert_asset(new_asset, - new_nested_edl, - length, - position, - vtrack); - - vtrack++; + for( ; current && vtrackrecord || current->data_type != TRACK_VIDEO ) continue; + current->insert_asset(new_asset, new_nested_edl, + length, position, vtrack++); } int atrack = 0; - if(new_asset) - { - if(new_asset->audio_length < 0) - { + if( new_asset ) { + if( new_asset->audio_length < 0 ) { // Insert 1 frame for undefined length & video - if(new_asset->video_data) + if( new_asset->video_data ) length = (double)1.0 / new_asset->frame_rate; else // Insert 1 second for undefined length & no video @@ -1175,29 +1117,16 @@ void EDL::insert_asset(Asset *asset, new_asset->sample_rate; } - for(current = tracks->first; - current && atrack < channels; - current = NEXT) - { - if(!current->record || - current->data_type != TRACK_AUDIO) - continue; - - current->insert_asset(new_asset, - new_nested_edl, - length, - position, - atrack); - - - atrack++; + current = tracks->first; + for( ; current && atrack < channels; current=NEXT ) { + if( !current->record || current->data_type != TRACK_AUDIO ) continue; + current->insert_asset(new_asset, new_nested_edl, + length, position, atrack++); } // Insert labels from a recording window. - if(labels) - { - for(RecordLabel *label = labels->first; label; label = label->next) - { + if( labels ) { + for( RecordLabel *label=labels->first; label; label=label->next ) { this->labels->toggle_label(label->position, label->position); } } @@ -1207,31 +1136,32 @@ void EDL::insert_asset(Asset *asset, void EDL::set_index_file(Indexable *indexable) { - if(indexable->is_asset) + if( indexable->is_asset ) assets->update_index((Asset*)indexable); else - nested_edls->update_index((EDL*)indexable); + nested_edls.update_index((EDL*)indexable); } void EDL::optimize() { //printf("EDL::optimize 1\n"); - if(local_session->preview_start < 0) local_session->preview_start = 0; + if( local_session->preview_start < 0 ) local_session->preview_start = 0; double length = tracks->total_length(); - if(local_session->preview_end > length) local_session->preview_end = length; - if(local_session->preview_start >= local_session->preview_end ) { + if( local_session->preview_end > length ) local_session->preview_end = length; + if( local_session->preview_start >= local_session->preview_end ) { local_session->preview_start = 0; local_session->preview_end = length; } - for(Track *current = tracks->first; current; current = NEXT) + for( Track *current=tracks->first; current; current=NEXT ) current->optimize(); } int EDL::next_id() { - id_lock->lock("EDL::next_id"); + static Mutex id_lock; + id_lock.lock("EDL::next_id"); int result = EDLSession::current_id++; - id_lock->unlock(); + id_lock.unlock(); return result; } @@ -1240,133 +1170,64 @@ void EDL::get_shared_plugins(Track *source, int omit_recordable, int data_type) { - for(Track *track = tracks->first; track; track = track->next) - { - if(!track->record || !omit_recordable) - { - if(track != source && - track->data_type == data_type) - { - for(int i = 0; i < track->plugin_set.total; i++) - { - Plugin *plugin = track->get_current_plugin( - local_session->get_selectionstart(1), - i, - PLAY_FORWARD, - 1, - 0); - if(plugin && plugin->plugin_type == PLUGIN_STANDALONE) - { - plugin_locations->append(new SharedLocation(tracks->number_of(track), i)); - } - } - } + for( Track *track=tracks->first; track; track=track->next ) { + if( track->record && omit_recordable ) continue; + if( track == source || track->data_type != data_type ) continue; + for( int i=0; iplugin_set.size(); ++i ) { + Plugin *plugin = track->get_current_plugin( + local_session->get_selectionstart(1), + i, PLAY_FORWARD, 1, 0); + if( plugin && plugin->plugin_type != PLUGIN_STANDALONE ) continue; + plugin_locations->append(new SharedLocation(tracks->number_of(track), i)); } } } void EDL::get_shared_tracks(Track *track, ArrayList *module_locations, - int omit_recordable, - int data_type) + int omit_recordable, int data_type) { - for(Track *current = tracks->first; current; current = NEXT) - { - if(!omit_recordable || !current->record) - { - if(current != track && - current->data_type == data_type) - { - module_locations->append(new SharedLocation(tracks->number_of(current), 0)); - } - } + for( Track *current=tracks->first; current; current=NEXT ) { + if( omit_recordable && current->record ) continue; + if( current == track || current->data_type != data_type ) continue; + module_locations->append(new SharedLocation(tracks->number_of(current), 0)); } } -// Convert position to frames if cursor alignment is enabled -double EDL::align_to_frame(double position, int round) +// aligned frame time +double EDL::frame_align(double position, int round) { -//printf("EDL::align_to_frame 1 %f\n", position); - if(session->cursor_on_frames) - { -// Seconds -> Frames - double temp = (double)position * session->frame_rate; -//printf("EDL::align_to_frame 2 %f\n", temp); - -// Assert some things - if(session->sample_rate == 0) - printf("EDL::align_to_frame: sample_rate == 0\n"); - - if(session->frame_rate == 0) - printf("EDL::align_to_frame: frame_rate == 0\n"); - -// Round frames -// Always round down negative numbers -// but round up only if requested - if(round) - { - temp = Units::round(temp); - } - else - { -// if(temp < 0) -// { -// temp -= 0.5; -// } -// else - temp = Units::to_int64(temp); - } -//printf("EDL::align_to_frame 3 %f\n", temp); - -// Frames -> Seconds - temp /= session->frame_rate; - -//printf("EDL::align_to_frame 5 %f\n", temp); - - return temp; - } -//printf("EDL::align_to_frame 3 %d\n", position); - + double frame_pos = position * session->frame_rate; + frame_pos = (int64_t)(frame_pos + (round ? 0.5 : 1e-6)); + position = frame_pos / session->frame_rate; + return position; +} +// Convert position to frames if alignment is enabled. +double EDL::align_to_frame(double position, int round) +{ + if( session->cursor_on_frames ) + position = frame_align(position, round); return position; } void EDL::new_folder(const char *folder) { - for(int i = 0; i < folders.total; i++) - { - if(!strcasecmp(folders.values[i], folder)) return; - } - - char *new_folder; - folders.append(new_folder = new char[strlen(folder) + 1]); - strcpy(new_folder, folder); + for( int i=0; i= 0 && strcasecmp(folders[i], folder) ); + if( i >= 0 ) folders.remove_number(i); } int EDL::get_use_vconsole(VEdit* *playable_edit, - int64_t position, - int direction, - PlayableTracks *playable_tracks) + int64_t position, int direction, PlayableTracks *playable_tracks) { int share_playable_tracks = 1; int result = 0; @@ -1375,57 +1236,47 @@ int EDL::get_use_vconsole(VEdit* *playable_edit, *playable_edit = 0; // Calculate playable tracks when being called as a nested EDL - if(!playable_tracks) - { + if( !playable_tracks ) { share_playable_tracks = 0; playable_tracks = new PlayableTracks(this, - position, - direction, - TRACK_VIDEO, - 1); + position, direction, TRACK_VIDEO, 1); } // Total number of playable tracks is 1 - if(playable_tracks->size() != 1) - { + if( playable_tracks->size() != 1 ) { result = 1; } - else - { + else { playable_track = (VTrack*)playable_tracks->get(0); } // Don't need playable tracks anymore - if(!share_playable_tracks) - { + if( !share_playable_tracks ) { delete playable_tracks; } -if(debug) printf("EDL::get_use_vconsole %d playable_tracks->size()=%d\n", -__LINE__, -playable_tracks->size()); - if(result) return 1; +if( debug ) printf("EDL::get_use_vconsole %d playable_tracks->size()=%d\n", + __LINE__, playable_tracks->size()); + if( result ) return 1; // Test mutual conditions between direct copy rendering and this. - if(!playable_track->direct_copy_possible(position, + if( !playable_track->direct_copy_possible(position, direction, - 1)) + 1) ) return 1; -if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); +if( debug ) printf("EDL::get_use_vconsole %d\n", __LINE__); *playable_edit = (VEdit*)playable_track->edits->editof(position, - direction, - 0); + direction, 0); // No edit at current location - if(!*playable_edit) return 1; -if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); + if( !*playable_edit ) return 1; +if( debug ) printf("EDL::get_use_vconsole %d\n", __LINE__); // Edit is nested EDL - if((*playable_edit)->nested_edl) - { + if( (*playable_edit)->nested_edl ) { // Test nested EDL EDL *nested_edl = (*playable_edit)->nested_edl; int64_t nested_position = (int64_t)((position - @@ -1436,23 +1287,23 @@ if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); VEdit *playable_edit_temp = 0; - if(session->output_w != nested_edl->session->output_w || + if( session->output_w != nested_edl->session->output_w || session->output_h != nested_edl->session->output_h || nested_edl->get_use_vconsole(&playable_edit_temp, nested_position, direction, - 0)) + 0) ) return 1; return 0; } -if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); +if( debug ) printf("EDL::get_use_vconsole %d\n", __LINE__); // Edit is not a nested EDL Asset *asset = (*playable_edit)->asset; // Edit is silence - if(!asset) return 1; -if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); + if( !asset ) return 1; +if( debug ) printf("EDL::get_use_vconsole %d\n", __LINE__); // Asset and output device must have the same dimensions if( asset->width != session->output_w || @@ -1460,11 +1311,11 @@ if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); return 1; -if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); +if( debug ) printf("EDL::get_use_vconsole %d\n", __LINE__); // Asset and output device must have same resulting de-interlacing method if( ilaceautofixmethod2(session->interlace_mode, asset->interlace_autofixoption, asset->interlace_mode, - asset->interlace_fixmethod) != BC_ILACE_FIXMETHOD_NONE ) + asset->interlace_fixmethod) != ILACE_FIXMETHOD_NONE ) return 1; // If we get here the frame is going to be directly copied. Whether it is @@ -1486,7 +1337,7 @@ int EDL::get_sample_rate() int64_t EDL::get_audio_samples() { - return (int64_t)(tracks->total_playable_length() * + return (int64_t)(tracks->total_length() * session->sample_rate); } @@ -1523,26 +1374,23 @@ int EDL::get_video_layers() int64_t EDL::get_video_frames() { - return (int64_t)(tracks->total_playable_length() * + return (int64_t)(tracks->total_length() * session->frame_rate); } void EDL::remove_vwindow_edls() { - for(int i = 0; i < total_vwindow_edls(); i++) - { - get_vwindow_edl(i)->Garbage::remove_user(); + for( int i=0; iremove_user(); } vwindow_edls.remove_all(); } void EDL::remove_vwindow_edl(EDL *edl) { - if(vwindow_edls.number_of(edl) >= 0) - { - edl->Garbage::remove_user(); - + if( vwindow_edls.number_of(edl) >= 0 ) { + edl->remove_user(); vwindow_edls.remove(edl); } } @@ -1562,8 +1410,179 @@ void EDL::append_vwindow_edl(EDL *edl, int increase_counter) { if(vwindow_edls.number_of(edl) >= 0) return; - if(increase_counter) edl->Garbage::add_user(); + if(increase_counter) edl->add_user(); vwindow_edls.append(edl); } +double EDL::next_edit(double position) +{ + Units::fix_double(&position); + double new_position = tracks->total_length(); + + double max_rate = get_frame_rate(); + int sample_rate = get_sample_rate(); + if( sample_rate > max_rate ) max_rate = sample_rate; + double min_movement = max_rate > 0 ? 1. / max_rate : 1e-6; + +// Test for edit handles after position + for( Track *track=tracks->first; track; track=track->next ) { + if( !track->record ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + double edit_end = track->from_units(edit->startproject + edit->length); + Units::fix_double(&edit_end); + if( fabs(edit_end-position) < min_movement ) continue; + if( edit_end > position && edit_end < new_position ) + new_position = edit_end; + } + } + return new_position; +} + +double EDL::prev_edit(double position) +{ + Units::fix_double(&position); + double new_position = -1; + + double max_rate = get_frame_rate(); + int sample_rate = get_sample_rate(); + if( sample_rate > max_rate ) max_rate = sample_rate; + double min_movement = max_rate > 0 ? 1. / max_rate : 1e-6; + +// Test for edit handles before cursor position + for( Track *track=tracks->first; track; track=track->next ) { + if( !track->record ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + double edit_end = track->from_units(edit->startproject); + Units::fix_double(&edit_end); + if( fabs(edit_end-position) < min_movement ) continue; + if( edit_end < position && edit_end > new_position ) + new_position = edit_end; + } + } + return new_position; +} + +void EDL::rescale_proxy(int orig_scale, int new_scale) +{ + if( orig_scale == new_scale ) return; +// project size + float orig_w = (float)session->output_w * orig_scale; + float orig_h = (float)session->output_h * orig_scale; + if( !parent_edl ) { + session->output_w = Units::round(orig_w / new_scale); + session->output_h = Units::round(orig_h / new_scale); + } + +// track sizes + for( Track *track=tracks->first; track; track=track->next ) { + if( track->data_type != TRACK_VIDEO ) continue; + orig_w = (float)track->track_w * orig_scale; + orig_h = (float)track->track_h * orig_scale; + track->track_w = Units::round(orig_w / new_scale); + track->track_h = Units::round(orig_h / new_scale); + ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])-> + set_proxy(orig_scale, new_scale); + ((FloatAutos*)track->automation->autos[AUTOMATION_CAMERA_X])-> + set_proxy(orig_scale, new_scale); + ((FloatAutos*)track->automation->autos[AUTOMATION_CAMERA_Y])-> + set_proxy(orig_scale, new_scale); + ((FloatAutos*)track->automation->autos[AUTOMATION_PROJECTOR_X])-> + set_proxy(orig_scale, new_scale); + ((FloatAutos*)track->automation->autos[AUTOMATION_PROJECTOR_Y])-> + set_proxy(orig_scale, new_scale); + } +} + +void EDL::set_proxy(int use_scaler, int new_scale, int auto_scale, int beep, + ArrayList *orig_assets, ArrayList *proxy_assets) +{ + int orig_use_scaler = session->proxy_use_scaler; + int orig_scale = session->proxy_scale; +// rescale to full size asset in read_frame + session->proxy_use_scaler = use_scaler; + session->proxy_scale = new_scale; + session->proxy_auto_scale = auto_scale; + session->proxy_beep = beep; + + if( use_scaler ) { + for( int i=0; isize(); ++i ) { + Asset *proxy_asset = (Asset *)proxy_assets->get(i); + proxy_asset->width = orig_assets->get(i)->get_w(); + proxy_asset->height = orig_assets->get(i)->get_h(); + } + new_scale = 1; + } + + if( !orig_use_scaler ) + rescale_proxy(orig_scale, new_scale); + +// change original assets to proxy assets + int awindow_folder = use_scaler || new_scale != 1 ? AW_PROXY_FOLDER : AW_MEDIA_FOLDER; + for( int i=0,n=proxy_assets->size(); iget(i)->path; + Indexable *proxy_idxbl = proxy_assets->get(i); + proxy_idxbl->awindow_folder = awindow_folder; + Asset *proxy_asset = proxy_idxbl->is_asset ? assets->update((Asset *)proxy_idxbl) : 0; + EDL *proxy_edl = !proxy_idxbl->is_asset ? (EDL *)proxy_idxbl : 0; +// replace track contents + for( Track *track=tracks->first; track; track=track->next ) { + if( track->data_type != TRACK_VIDEO ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + Indexable *idxbl = (Indexable *)edit->asset; + if( !idxbl ) idxbl = (Indexable *)edit->nested_edl; + if( !idxbl ) continue; + if( strcmp(idxbl->path, orig_path) ) continue; + edit->asset = proxy_asset; + edit->nested_edl = proxy_edl; + } + } + for( int j=0,m=clips.size(); jtracks->first; track; track=track->next ) { + if( track->data_type != TRACK_VIDEO ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + Indexable *idxbl = (Indexable *)edit->asset; + if( !idxbl ) idxbl = (Indexable *)edit->nested_edl; + if( !idxbl ) continue; + if( strcmp(idxbl->path, orig_path) ) continue; + edit->asset = proxy_asset; + edit->nested_edl = proxy_edl; + has_proxy = 1; + } + } + if( has_proxy && !orig_use_scaler ) + clip->rescale_proxy(orig_scale, new_scale); + } + } +} + +void EDL::add_proxy(int use_scaler, + ArrayList *orig_assets, ArrayList *proxy_assets) +{ + if( use_scaler ) { + for( int i=0,n=proxy_assets->size(); iget(i); + proxy_asset->width = orig_assets->get(i)->get_w(); + proxy_asset->height = orig_assets->get(i)->get_h(); + } + } + +// change original assets to proxy assets + for( int i=0,n=proxy_assets->size(); iupdate((Asset *)proxy_assets->get(i)); + proxy_asset->awindow_folder = AW_PROXY_FOLDER; +// replace track contents + for( Track *track=tracks->first; track; track=track->next ) { + if( track->data_type != TRACK_VIDEO ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + if( !edit->asset ) continue; + if( !strcmp(edit->asset->path, orig_assets->get(i)->path) ) { + edit->asset = proxy_asset; + } + } + } + } +} +