#include "edits.h"
#include "edl.h"
#include "edlsession.h"
+#include "ffmpeg.h"
#include "file.h"
#include "filexml.h"
#include "filesystem.h"
// 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;
//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;
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) {
}
}
+// 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)
{
// 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;
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 &&
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;
//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
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;
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;
+ }
+}
+