X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fedl.C;h=8312c71ec09aa09471e7a7f019f0d2e0575bda84;hb=4710b00debcb86b8ff626c4af3473afe338408ae;hp=1c0c77b1da1a6d060e80041d7f83d02d4749b943;hpb=9a7a880b549aed850fd3c29abb152d69a94e23f8;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index 1c0c77b1..8312c71e 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -49,6 +49,7 @@ #include "playbackconfig.h" #include "playabletracks.h" #include "plugin.h" +#include "pluginset.h" #include "preferences.h" #include "recordconfig.h" #include "recordlabel.h" @@ -335,7 +336,7 @@ int EDL::read_xml(FileXML *file, uint32_t load_flags) // The string is not terminated in this call. int EDL::save_xml(FileXML *file, const char *output_path) { - copy(1, file, output_path, 0); + copy(COPY_EDL, file, output_path, 0); return 0; } @@ -415,11 +416,8 @@ void EDL::copy_session(EDL *edl, int session_only) } } -int EDL::copy_assets(double start, - double end, - FileXML *file, - int all, - const char *output_path) +int EDL::copy_assets(int copy_flags, double start, double end, + FileXML *file, const char *output_path) { ArrayList asset_list; Track* current; @@ -429,12 +427,12 @@ int EDL::copy_assets(double start, file->append_newline(); // Copy everything for a save - if( all ) { + if( (copy_flags & COPY_ALL_ASSETS) ) { for( Asset *asset=assets->first; asset; asset=asset->next ) { asset_list.append(asset); } } - else { + if( (copy_flags & COPY_USED_ASSETS) ) { // Copy just the ones being used. for( current = tracks->first; current; current = NEXT ) { if( !current->record ) continue; @@ -455,67 +453,66 @@ int EDL::copy_assets(double start, } -int EDL::copy(double start, double end, int all, +int EDL::copy(int copy_flags, double start, double end, FileXML *file, const char *output_path, int rewind_it) { 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); - return copy(start, end, all, - "/EDL", file, output_path, rewind_it); + return copy_xml(copy_flags, start, end, file, "/EDL", output_path, rewind_it); } -int EDL::copy(int all, FileXML *file, const char *output_path, int rewind_it) +int EDL::copy(int copy_flags, FileXML *file, const char *output_path, int rewind_it) { - return copy(0, tracks->total_length(), all, file, output_path, rewind_it); + return copy(copy_flags, 0., tracks->total_length(), + file, output_path, rewind_it); } -int EDL::copy_clip(double start, double end, int all, +int EDL::copy_clip(int copy_flags, double start, double end, 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); + return copy_xml(copy_flags, start, end, file, "/CLIP_EDL", output_path, rewind_it); } -int EDL::copy_clip(int all, FileXML *file, const char *output_path, int rewind_it) +int EDL::copy_clip(int copy_flags, FileXML *file, const char *output_path, int rewind_it) { - return copy_clip(0, tracks->total_length(), all, file, output_path, rewind_it); + return copy_clip(copy_flags, 0., tracks->total_length(), + file, output_path, rewind_it); } -int EDL::copy_nested_edl(double start, double end, int all, +int EDL::copy_nested(int copy_flags, double start, double end, 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); + return copy_xml(copy_flags, start, end, file, "/NESTED_EDL", output_path, rewind_it); } -int EDL::copy_nested_edl(int all, FileXML *file, const char *output_path, int rewind_it) +int EDL::copy_nested(int copy_flags, FileXML *file, const char *output_path, int rewind_it) { - return copy_nested_edl(0, tracks->total_length(), all, file, output_path, rewind_it); + return copy_nested(copy_flags, 0., tracks->total_length(), + file, output_path, rewind_it); } -int EDL::copy_vwindow_edl(double start, double end, int all, +int EDL::copy_vwindow(int copy_flags, double start, double end, 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); + return copy_xml(copy_flags, start, end, file, "/VWINDOW_EDL", output_path, rewind_it); } -int EDL::copy_vwindow_edl(int all, FileXML *file, const char *output_path, int rewind_it) +int EDL::copy_vwindow(int copy_flags, FileXML *file, const char *output_path, int rewind_it) { - return copy_vwindow_edl(0, tracks->total_length(), all, file, output_path, rewind_it); + return copy_vwindow(copy_flags, 0., tracks->total_length(), + 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) +int EDL::copy_xml(int copy_flags, double start, double end, + FileXML *file, const char *closer, const char *output_path, + int rewind_it) { file->append_tag(); file->append_newline(); // Set clipboard samples only if copying to clipboard - if( !all ) { + if( (copy_flags & COPY_LENGTH) ) { file->tag.set_title("CLIPBOARD"); file->tag.set_property("LENGTH", end - start); file->append_tag(); @@ -527,45 +524,54 @@ int EDL::copy(double start, double end, int all, //printf("EDL::copy 1\n"); // Sessions - local_session->save_xml(file, start); - -//printf("EDL::copy 1\n"); + if( (copy_flags & COPY_LOCAL_SESSION) ) + local_session->save_xml(file, start); // Top level stuff. -// if(!parent_edl) - { // Need to copy all this from child EDL if pasting is desired. -// Session + + if( (copy_flags & COPY_SESSION) ) session->save_xml(file); + + if( (copy_flags & COPY_VIDEO_CONFIG) ) session->save_video_config(file); + + if( (copy_flags & COPY_AUDIO_CONFIG) ) session->save_audio_config(file); + + if( (copy_flags & COPY_FOLDERS) ) folders.save_xml(file); - if( !parent_edl ) - copy_assets(start, end, file, all, output_path); + if( (copy_flags & (COPY_ALL_ASSETS | COPY_USED_ASSETS)) ) + copy_assets(copy_flags, start, end, file, output_path); + if( (copy_flags & COPY_NESTED_EDL) ) { for( int i=0; icopy_nested_edl(0, tracks->total_length(), 1, + nested_edls[i]->copy_nested(copy_flags, file, output_path, 0); - + } // Clips -// Don't want this if using clipboard - if( all ) { - for( int i=0; icopy_vwindow_edl(1, file, output_path, 0); + if( (copy_flags & COPY_CLIPS) ) { + for( int i=0; icopy_clip(copy_flags, file, output_path, 0); + } - for( int i=0; icopy_clip(1, file, output_path, 0); + if( (copy_flags & COPY_VWINDOWS) ) { + for( int i=0; icopy_vwindow(copy_flags, + file, output_path, 0); + } - mixers.save(file); - } + if( (copy_flags & COPY_MIXERS) ) + mixers.save(file); - file->append_newline(); - file->append_newline(); - } + file->append_newline(); + file->append_newline(); - labels->copy(start, end, file); - tracks->copy(start, end, all, file, output_path); + if( (copy_flags & COPY_LABELS) ) + labels->copy(start, end, file); + + tracks->copy(copy_flags, start, end, file, output_path); // terminate file file->tag.set_title(closer); @@ -794,58 +800,145 @@ int EDL::clear(double start, double end, return 0; } -void EDL::modify_edithandles(double oldposition, - double newposition, - int currentend, - int handle_mode, - int edit_labels, - int edit_plugins, - int edit_autos) +static int dead_edit_cmp(Edit**ap, Edit**bp) { - tracks->modify_edithandles(oldposition, - newposition, - currentend, - handle_mode, - edit_labels, - edit_plugins, - edit_autos); - labels->modify_handles(oldposition, - newposition, - currentend, - handle_mode, - edit_labels); -} - -void EDL::modify_pluginhandles(double oldposition, - double newposition, - int currentend, - int handle_mode, - int edit_labels, - int edit_autos, - Edits *trim_edits) -{ - tracks->modify_pluginhandles(oldposition, - newposition, - currentend, - handle_mode, - edit_labels, - edit_autos, - trim_edits); + Edit *a = *ap, *b = *bp; + if( a->track != b->track ) return 0; + return a->startproject > b->startproject ? -1 : 1; +} + +void EDL::delete_edits(ArrayList *edits, int collapse) +{ + edits->sort(dead_edit_cmp); + for( int i=0; isize(); ++i ) { + Edit *edit = edits->get(i); + Track *track = edit->track; + int64_t start = edit->startproject; + int64_t length = edit->length; + int64_t end = start + length; + if( session->autos_follow_edits ) { + track->automation->clear(start, end, 0, collapse); + } + if( session->plugins_follow_edits ) { + for( int k=0; kplugin_set.size(); ++k ) { + PluginSet *plugin_set = track->plugin_set[k]; + plugin_set->clear(start, end, 1); + if( !collapse ) + plugin_set->paste_silence(start, end, 1); + plugin_set->optimize(); + } + } + Edit *dead_edit = edit; + if( collapse ) { + while( (edit=edit->next) ) + edit->startproject -= length; + } + delete dead_edit; + } optimize(); } -void EDL::paste_silence(double start, - double end, - int edit_labels, - int edit_plugins, - int edit_autos) +class Range { +public: + static int cmp(Range *ap, Range *bp); + double start, end; + bool operator ==(Range &that) { return this->start == that.start; } + bool operator >(Range &that) { return this->start > that.start; } +}; +int Range::cmp(Range *ap, Range *bp) { + return ap->start < bp->start ? -1 : ap->start == bp->start ? 0 : 1; +} + +static void get_edit_regions(ArrayList *edits, ArrayList ®ions) +{ +// move edit inclusive labels by regions + for( int i=0; isize(); ++i ) { + Edit *edit = edits->get(i); + double pos = edit->track->from_units(edit->startproject); + double end = edit->track->from_units(edit->startproject + edit->length); + int n = regions.size(), k = n; + while( --k >= 0 ) { + Range &range = regions[k]; + if( pos >= range.end ) continue; + if( range.start >= end ) continue; + int expand = 0; + if( range.start > pos ) { range.start = pos; expand = 1; } + if( range.end < end ) { range.end = end; expand = 1; } + if( !expand ) break; + k = n; + } + if( k < 0 ) { + Range &range = regions.append(); + range.start = pos; range.end = end; + } + } + regions.sort(Range::cmp); +} + +void EDL::delete_edit_labels(ArrayList *edits, int collapse) +{ + ArrayList regions; + get_edit_regions(edits, regions); + int n = regions.size(), k = n; + while( --k >= 0 ) { + Range &range = regions[k]; + labels->clear(range.start, range.end, collapse); + } +} + +void EDL::move_edit_labels(ArrayList *edits, double dist) +{ + ArrayList regions; + get_edit_regions(edits, regions); + int n = regions.size(), k = n; + Labels moved(this, 0); + while( --k >= 0 ) { + Range &range = regions[k]; + Label *label = labels->label_of(range.start); + for( Label *next=0; label && label->position <= range.end; label=next ) { + next = label->next; + labels->remove_pointer(label); + label->position += dist; + moved.append(label); + } + Label *current = labels->first; + while( (label=moved.first) ) { + moved.remove_pointer(label); + while( current && current->position < label->position ) + current = current->next; + if( current && current->position == label->position ) { + delete label; continue; + } + labels->insert_before(current, label); + } + } +} + +void EDL::modify_edithandles(double oldposition, double newposition, + int currentend, int handle_mode, int edit_labels, + int edit_plugins, int edit_autos, int group_id) +{ + tracks->modify_edithandles(oldposition, newposition, + currentend, handle_mode, edit_labels, + edit_plugins, edit_autos, group_id); +} + +void EDL::modify_pluginhandles(double oldposition, double newposition, + int currentend, int handle_mode, int edit_labels, + int edit_autos, Edits *trim_edits) +{ + tracks->modify_pluginhandles(oldposition, newposition, + currentend, handle_mode, edit_labels, + edit_autos, trim_edits); + optimize(); +} + +void EDL::paste_silence(double start, double end, + int edit_labels, int edit_plugins, int edit_autos) { if( edit_labels ) labels->paste_silence(start, end); - tracks->paste_silence(start, - end, - edit_plugins, - edit_autos); + tracks->paste_silence(start, end, edit_plugins, edit_autos); } @@ -1179,13 +1272,15 @@ void EDL::get_shared_tracks(Track *track, } } -// aligned frame time +// aligned frame time, account for sample truncation double EDL::frame_align(double position, int round) { - 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; + if( !round && session->sample_rate > 0 ) { + int64_t sample_pos = position * session->sample_rate; + position = (sample_pos+2.) / session->sample_rate; + } + int64_t frame_pos = (position * session->frame_rate + (round ? 0.5 : 1e-6)); + return frame_pos / session->frame_rate; } // Convert position to frames if alignment is enabled.