X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fedits.C;h=a64024ada45ad77505b3b53905e823a04608a9ed;hp=26f49890d70cb22fbc1ea7351ab80f7a15edbba1;hb=refs%2Fheads%2Fmaster;hpb=834732af87bfd7f1d4035109f31e48db12b415fa diff --git a/cinelerra-5.1/cinelerra/edits.C b/cinelerra-5.1/cinelerra/edits.C index 26f49890..71dd3b18 100644 --- a/cinelerra-5.1/cinelerra/edits.C +++ b/cinelerra-5.1/cinelerra/edits.C @@ -31,6 +31,7 @@ #include "edits.h" #include "edl.h" #include "edlsession.h" +#include "ffmpeg.h" #include "file.h" #include "filexml.h" #include "filesystem.h" @@ -178,7 +179,7 @@ void Edits::insert_edits(Edits *source_edits, // Open destination area Edit *dest_edit = insert_new_edit(position + source_edit->startproject); - dest_edit->copy_from(source_edit); + dest_edit->clone_from(source_edit); dest_edit->asset = dest_asset; dest_edit->nested_edl = dest_nested_edl; dest_edit->startproject = position + source_edit->startproject; @@ -223,9 +224,7 @@ Edit* Edits::insert_new_edit(int64_t position) //printf("Edits::insert_new_edit 1\n"); Edit *new_edit = create_edit(); - if( current ) new_edit->hard_right = current->hard_left; if( current ) current = PREVIOUS; - if( current ) new_edit->hard_left = current->hard_right; //printf("Edits::insert_new_edit 1\n"); insert_after(current, new_edit); new_edit->startproject = position; @@ -244,11 +243,21 @@ Edit* Edits::split_edit(int64_t position) Edit *new_edit = create_edit(); insert_after(edit, new_edit); - new_edit->copy_from(edit); + new_edit->clone_from(edit); new_edit->length = new_edit->startproject + new_edit->length - position; edit->length = position - edit->startproject; + if( !new_edit->length || edit->silence() ) + new_edit->hard_left = new_edit->hard_right = 0; + else if( !edit->length ) + edit->hard_left = edit->hard_right = 0; + else { + new_edit->hard_right = edit->hard_right; + new_edit->hard_left = edit->hard_right = 0; + } new_edit->startproject = position; - new_edit->startsource += edit->length; + int64_t edit_start = edit->startproject; + int64_t edit_end = edit_start + edit->length; + new_edit->startsource += track->speed_length(edit_start, edit_end); // Decide what to do with the transition if(edit->length && edit->transition) { @@ -326,6 +335,14 @@ int Edits::optimize() } } +// trim edits before position 0 + while( first && first->startproject+first->length < 0 ) + delete first; + if( first && first->startproject < 0 ) { + first->length += first->startproject; + first->startproject = 0; + } + // Insert silence between edits which aren't consecutive for(current = last; current; current = current->previous) { @@ -359,13 +376,19 @@ int Edits::optimize() // delete 0 length edits for( current = first; !result && current; ) { - Edit* next = current->next; + Edit* prev = current->previous, *next = current->next; if( current->length == 0 ) { if( next && current->transition && !next->transition) { next->transition = current->transition; next->transition->edit = next; current->transition = 0; } + if( !current->silence() ) { + if( current->hard_left && next && !next->silence() ) + next->hard_left = 1; + if( current->hard_right && prev && !prev->silence()) + prev->hard_right = 1; + } delete current; result = 1; break; @@ -386,13 +409,14 @@ int Edits::optimize() Edit *next_edit = 0; for( ; current && (next_edit=current->next); current=NEXT ) { // both edges are not hard edges - if( current->hard_right || next_edit->hard_left ) continue; + if( current->hard_right || next_edit->hard_left ) + continue; // next edit is a glitch if( is_glitch(next_edit) ) break; // both edits are silence & not a plugin - if( !current->is_plugin && current->silence() && - !next_edit->is_plugin && next_edit->silence() ) + if( !current->is_plugin() && current->silence() && + !next_edit->is_plugin() && next_edit->silence() ) break; // source channels are identical & assets are identical if( !result && current->channel == next_edit->channel && @@ -536,6 +560,13 @@ Edit* Edits::editof(int64_t position, int direction, int use_nudge) return 0; // return 0 on failure } +Edit* Edits::get_edit(int id) +{ + Edit *current = first; + while( current && current->orig_id != id ) current = NEXT; + return current; +} + Edit* Edits::get_playable_edit(int64_t position, int use_nudge) { Edit *current; @@ -607,7 +638,7 @@ void Edits::clear(int64_t start, int64_t end) //printf("Edits::clear 3.5 %d %d %d %d\n", edit1->startproject, edit1->length, edit2->startproject, edit2->length); edit1->length = start - edit1->startproject; edit2->length -= end - edit2->startproject; - edit2->startsource += end - edit2->startproject; + edit2->startsource += track->speed_length(edit2->startproject, end); edit2->startproject += end - edit2->startproject; // delete @@ -627,7 +658,7 @@ void Edits::clear(int64_t start, int64_t end) current_edit = split_edit(start); if( current_edit ) { current_edit->length -= end - start; - current_edit->startsource += end - start; + current_edit->startsource += track->speed_length(start, end); // shift while( (current_edit=current_edit->next) != 0 ) { current_edit->startproject -= end - start; @@ -730,17 +761,10 @@ int Edits::modify_handles(double oldposition, double newposition, int currentend double delta = newposition - oldposition; oldposition = track->from_units(current_edit->startproject); if( group_id > 0 ) newposition = oldposition + delta; - result = 1; -// dont move stuff if media playback does not shift in time - if( edit_mode != MOVE_MEDIA && edit_mode != MOVE_EDGE_MEDIA ) { - edit_labels = 0; - edit_plugins = 0; - edit_autos = 0; - } current_edit->shift_start(edit_mode, track->to_units(newposition, 0), track->to_units(oldposition, 0), - 0, edit_labels, edit_plugins, edit_autos, - trim_edits); + edit_labels, edit_autos, edit_plugins, trim_edits); + result = 1; } if(!result) current_edit = current_edit->next; @@ -760,7 +784,7 @@ int Edits::modify_handles(double oldposition, double newposition, int currentend current_edit->shift_end(edit_mode, track->to_units(newposition, 0), track->to_units(oldposition, 0), - edit_edits, edit_labels, edit_plugins, edit_autos, trim_edits); + edit_labels, edit_autos, edit_plugins, trim_edits); } if(!result) current_edit = current_edit->next; @@ -824,3 +848,79 @@ void Edits::shift_effects_recursive(int64_t position, int64_t length, int edit_a track->shift_effects(position, length, edit_autos, 0); } +double Edits::early_timecode() +{ + double result = -1; + for( Edit *edit=first; edit; edit=edit->next ) { + Asset *asset = edit->asset; + if( !asset ) continue; + if( asset->timecode < -1 ) + asset->timecode = FFMPEG::get_timecode(asset->path, + track->data_type, edit->channel, + edl->session->frame_rate); + if( asset->timecode < 0 ) continue; + if( result < 0 || result > asset->timecode ) + result = asset->timecode; + } + return result; +} + +void Edits::align_timecodes(double offset) +{ + for( Edit *edit=first, *next=0; edit; edit=next ) { + next = edit->next; + if( edit->silence() ) delete edit; + } + for( Edit *edit=first, *next=0; edit; edit=next ) { + next = edit->next; + Asset *asset = edit->asset; + if( !asset && asset->timecode < 0 ) continue; + double position = asset->timecode - offset; + edit->startproject = track->to_units(position, 1) + edit->startsource; + } + int result = 1; + while( result ) { + result = 0; + for( Edit *edit=first, *next=0; edit; edit=next ) { + next = edit->next; + if( !next || next->startproject >= edit->startproject ) continue; + swap(next, edit); + next = edit; + result = 1; + } + } + int64_t startproject = 0; + for( Edit *edit=first, *next=0; edit; edit=next ) { + if( (next = edit->next) != 0 ) { + int64_t length = next->startproject - startproject; + if( length > edit->length ) edit->length = length; + } + int64_t length = edit->startproject - startproject; + if( length > 0 ) { + Edit *new_edit = create_edit(); + insert_before(edit, new_edit); + new_edit->startproject = startproject; + new_edit->length = length; + startproject = edit->startproject; + } + startproject += edit->length; + } +} + +void Edits::update_idxbl_length(int id, int64_t du) +{ + for( Edit *edit=first; edit; edit=edit->next ) { + Indexable *idxbl = edit->asset ? (Indexable *)edit->asset : + edit->nested_edl ? (Indexable *)edit->nested_edl : 0; + if( !idxbl || idxbl->id != id ) continue; + edit->length += du; + if( edit->length > 0 && edit->next ) { + int64_t next_start = edit->next->startproject; + int64_t edit_end = edit->startproject + edit->length; + if( edit_end > next_start ) + edit->length = next_start - edit->startproject; + } + if( edit->length < 0 ) edit->length = 0; + } +} +