no longer need ffmpeg patch0 which was for Termux
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / edl.C
index 6739dec89dab284da8dec9be63a6128e5e6fe0c0..30e9e894dc2fafc267c7610756035d39ca4c0a87 100644 (file)
@@ -2,6 +2,7 @@
 /*
  * CINELERRA
  * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2003-2016 Cinelerra CV contributors
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -270,8 +271,7 @@ int EDL::read_xml(FileXML *file, uint32_t load_flags)
                        }
                        else
                        if( file->tag.title_is("SESSION") ) {
-                               if( (load_flags & LOAD_SESSION) &&
-                                       !parent_edl )
+                               if( (load_flags & LOAD_SESSION) && !parent_edl )
                                        session->load_xml(file, 0, load_flags);
                                else
                                        result = file->skip_tag();
@@ -281,14 +281,13 @@ int EDL::read_xml(FileXML *file, uint32_t load_flags)
                                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 ) {
+                       if( file->tag.title_is("CLIP_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( (load_flags & LOAD_ALL) == LOAD_ALL ) {
                                        clips.add_clip(new_edl);
+                               }
                                new_edl->remove_user();
                        }
                        else
@@ -301,27 +300,22 @@ int EDL::read_xml(FileXML *file, uint32_t load_flags)
                                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( file->tag.title_is("VWINDOW_EDL") ) {
+                               if( !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->remove_user();
-//                                             vwindow_edl_shared = 0;
-//                                             vwindow_edl = new_edl;
-
-                                       append_vwindow_edl(new_edl, 0);
 
+                                       if( (load_flags & LOAD_ALL) == LOAD_ALL ) {
+                                               append_vwindow_edl(new_edl, 0);
+                                       }
+                                       else { // Discard if not replacing EDL
+                                               new_edl->remove_user();
+                                       }
                                }
                                else
-// Discard if not replacing EDL
-                               {
-                                       new_edl->remove_user();
-                                       new_edl = 0;
-                               }
+                                       result = file->skip_tag();
                        }
                }
        } while(!result);
@@ -437,7 +431,7 @@ int EDL::copy_assets(int copy_flags, double start, double end,
        if( (copy_flags & COPY_USED_ASSETS) ) {
 // Copy just the ones being used.
                for( current = tracks->first; current; current = NEXT ) {
-                       if( !current->record ) continue;
+                       if( !current->is_armed() ) continue;
                        current->copy_assets(start, end, &asset_list);
                }
        }
@@ -601,7 +595,7 @@ void EDL::copy_indexables(EDL *edl)
        }
 }
 
-EDL *EDL::new_nested_edl(EDL *edl, const char *path)
+EDL *EDL::new_nested_clip(EDL *edl, const char *path)
 {
        EDL *nested = new EDL;  // no parent for nested edl
        nested->create_objects();
@@ -614,19 +608,14 @@ EDL *EDL::new_nested_edl(EDL *edl, const char *path)
        return nested;
 }
 
-EDL *EDL::get_nested_edl()
+EDL *EDL::get_nested_edl(const char *path)
 {
-       Track *track = tracks->first;
-       Edit *edit = track ? track->edits->first : 0;
-       EDL *nested = edit && !edit->next && !edit->asset ? edit->nested_edl : 0;
-       while( nested && (track=track->next)!=0 ) {
-               Edit *edit = track->edits->first;
-               if( !edit || edit->next ||
-                   ( edit->nested_edl != nested &&
-                     strcmp(edit->nested_edl->path, nested->path) ) )
-                       nested = 0;
+       for( int i=0; i<nested_edls.size(); ++i ) {
+               EDL *nested_edl = nested_edls[i];
+               if( !strcmp(path, nested_edl->path) )
+                       return nested_edl;
        }
-       return nested;
+       return 0;
 }
 
 
@@ -642,8 +631,8 @@ void EDL::create_nested(EDL *nested)
 {
        int video_tracks = 0, audio_tracks = 0;
        for( Track *track=nested->tracks->first; track!=0; track=track->next ) {
-               if( track->data_type == TRACK_VIDEO && track->record ) ++video_tracks;
-               if( track->data_type == TRACK_AUDIO && track->record ) ++audio_tracks;
+               if( track->data_type == TRACK_VIDEO && track->play ) ++video_tracks;
+               if( track->data_type == TRACK_AUDIO && track->play ) ++audio_tracks;
        }
 // renderengine properties
        if( video_tracks > 0 )
@@ -914,8 +903,8 @@ static void get_edit_regions(ArrayList<Edit*> *edits, ArrayList<Range> &regions)
 // move edit inclusive labels by regions
        for( int i=0; i<edits->size(); ++i ) {
                Edit *edit = edits->get(i);
-               double pos = edit->track->from_units(edit->startproject);
-               double end = edit->track->from_units(edit->startproject + edit->length);
+               volatile double pos = edit->track->from_units(edit->startproject);
+               volatile double end = edit->track->from_units(edit->startproject + edit->length);
                int n = regions.size(), k = n;
                while( --k >= 0 ) {
                        Range &range = regions[k];
@@ -1049,6 +1038,7 @@ int EDL::get_tracks_height(Theme *theme)
 {
        int total_pixels = 0;
        for( Track *current=tracks->first; current; current=NEXT ) {
+               if( current->is_hidden() ) continue;
                total_pixels += current->vertical_span(theme);
        }
        return total_pixels;
@@ -1058,6 +1048,7 @@ int64_t EDL::get_tracks_width()
 {
        int64_t total_pixels = 0;
        for( Track *current=tracks->first; current; current=NEXT ) {
+               if( current->is_hidden() ) continue;
                int64_t pixels = current->horizontal_span();
                if( pixels > total_pixels ) total_pixels = pixels;
        }
@@ -1233,7 +1224,7 @@ void EDL::insert_asset(Asset *asset,
        }
 
        for( ; current && vtrack<layers; current=NEXT ) {
-               if( !current->record || current->data_type != TRACK_VIDEO ) continue;
+               if( !current->is_armed() || current->data_type != TRACK_VIDEO ) continue;
                current->insert_asset(new_asset, new_nested_edl,
                        length, position, vtrack++);
        }
@@ -1255,7 +1246,7 @@ void EDL::insert_asset(Asset *asset,
 
        current = tracks->first;
        for( ; current && atrack < channels; current=NEXT ) {
-               if( !current->record || current->data_type != TRACK_AUDIO ) continue;
+               if( !current->is_armed() || current->data_type != TRACK_AUDIO ) continue;
                current->insert_asset(new_asset, new_nested_edl,
                        length, position, atrack++);
        }
@@ -1309,7 +1300,7 @@ void EDL::get_shared_plugins(Track *source,
        int data_type)
 {
        for( Track *track=tracks->first; track; track=track->next ) {
-               if( track->record && omit_recordable ) continue;
+               if( track->is_armed() && omit_recordable ) continue;
                if( track == source || track->data_type != data_type ) continue;
                for( int i=0; i<track->plugin_set.size(); ++i ) {
                        Plugin *plugin = track->get_current_plugin(
@@ -1326,7 +1317,7 @@ void EDL::get_shared_tracks(Track *track,
        int omit_recordable, int data_type)
 {
        for( Track *current=tracks->first; current; current=NEXT ) {
-               if( omit_recordable && current->record ) continue;
+               if( omit_recordable && current->is_armed() ) continue;
                if( current == track || current->data_type != data_type ) continue;
                module_locations->append(new SharedLocation(tracks->number_of(current), 0));
        }
@@ -1599,7 +1590,7 @@ double EDL::next_edit(double position)
 
 // Test for edit handles after position
        for( Track *track=tracks->first; track; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) 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);
@@ -1623,7 +1614,7 @@ double EDL::prev_edit(double position)
 
 // Test for edit handles before cursor position
        for( Track *track=tracks->first; track; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
                        double edit_end = track->from_units(edit->startproject);
                        Units::fix_double(&edit_end);
@@ -1685,26 +1676,29 @@ void EDL::set_proxy(int new_scale, int new_use_scaler,
        ArrayList<Indexable*> *orig_assets, ArrayList<Indexable*> *proxy_assets)
 {
        int orig_scale = session->proxy_scale;
-       session->proxy_scale = new_scale;
+       int proxy_scale = new_scale;
+       if( !proxy_scale ) proxy_scale = 1;
+       session->proxy_scale = proxy_scale;
        int orig_use_scaler = session->proxy_use_scaler;
        session->proxy_use_scaler = new_use_scaler;
        if( orig_use_scaler ) orig_scale = 1;
-       int scale = new_use_scaler ? new_scale : 1;
-       int asset_scale = new_scale == 1 && !new_use_scaler ? 0 : scale;
+       int scale = new_use_scaler ? proxy_scale : 1;
+       int asset_scale = !new_scale ? 0 : !new_use_scaler ? 1 : scale;
 // change original assets to proxy assets
-       int folder_no = new_use_scaler || new_scale != 1 ? AW_PROXY_FOLDER : AW_MEDIA_FOLDER;
+       int folder_no = !new_use_scaler && !new_scale ? AW_MEDIA_FOLDER : AW_PROXY_FOLDER;
        for( int i=0,n=proxy_assets->size(); i<n; ++i ) {
                Indexable *proxy_idxbl = proxy_assets->get(i);
                proxy_idxbl->folder_no = folder_no;
                if( !proxy_idxbl->is_asset ) continue;
                Asset *proxy_asset = assets->update((Asset *)proxy_idxbl);
+               proxy_asset->proxy_scale = asset_scale;
+               if( !new_scale ) continue;  // in case geom resized
                proxy_asset->width = proxy_asset->actual_width * scale;
                proxy_asset->height = proxy_asset->actual_height * scale;
-               proxy_asset->proxy_scale = asset_scale;
        }
 // rescale to full size asset in read_frame
-       if( new_use_scaler ) new_scale = 1;
-       rescale_proxy(orig_scale, new_scale);
+       if( new_use_scaler ) proxy_scale = 1;
+       rescale_proxy(orig_scale, proxy_scale);
 
 // replace track contents
        for( Track *track=tracks->first; track; track=track->next ) {
@@ -1748,7 +1742,7 @@ void EDL::set_proxy(int new_scale, int new_use_scaler,
                        }
                }
                if( has_proxy && !orig_use_scaler )
-                       clip->rescale_proxy(orig_scale, new_scale);
+                       clip->rescale_proxy(orig_scale, proxy_scale);
        }
 }
 
@@ -1869,7 +1863,7 @@ EDL *EDL::selected_edits_to_clip(int packed,
        double start = DBL_MAX, end = DBL_MIN;
        Track *first_track=0, *last_track = 0;
        for( Track *track=tracks->first; track; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                int empty = 1;
                for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
                        if( !edit->is_selected || edit->silence() ) continue;
@@ -1895,7 +1889,7 @@ EDL *EDL::selected_edits_to_clip(int packed,
        new_edl->session->video_tracks = 0;
        new_edl->session->audio_tracks = 0;
        for( Track *track=tracks->first; track; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                if( first_track ) {
                        if( first_track != track ) continue;
                        first_track = 0;
@@ -2045,7 +2039,7 @@ void EDL::paste_edits(EDL *clip, Track *first_track, double position, int overwr
                first_track = tracks->first;
        Track *src = clip->tracks->first;
        for( Track *track=first_track; track && src; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                int64_t pos = track->to_units(position, 0);
                if( edit_edits ) {
                        for( Edit *edit=src->edits->first; edit; edit=edit->next ) {
@@ -2211,7 +2205,7 @@ int EDL::collect_effects(EDL *&group)
                Edit *edit = track->edits->first;
                while( edit && !edit->is_selected ) edit = edit->next;
                if( !edit ) continue;
-               if( !track->record ) { ret = COLLECT_EFFECTS_RECORD;  break; } 
+               if( !track->is_armed() ) { ret = COLLECT_EFFECTS_RECORD;  break; } 
                Track *new_track = 0;
                edl_shared *location = 0;
                int64_t start_pos = edit->startproject;
@@ -2278,6 +2272,8 @@ int EDL::collect_effects(EDL *&group)
        }
        if( !ret )
                group = new_edl;
+       else
+               new_edl->remove_user();
        return ret;
 }
 
@@ -2298,7 +2294,7 @@ int EDL::insert_effects(EDL *group, Track *first_track)
                Edit *edit = track->edits->first;
                while( edit && !edit->is_selected ) edit = edit->next;
                if( !edit ) continue;
-               if( !track->record ) return INSERT_EFFECTS_RECORD;
+               if( !track->is_armed() ) return INSERT_EFFECTS_RECORD;
                if( track->data_type != new_track->data_type ) return INSERT_EFFECTS_TYPE;
                int gtrk = group->tracks->number_of(new_track);
                int trk = tracks->number_of(track);
@@ -2321,7 +2317,7 @@ int EDL::insert_effects(EDL *group, Track *first_track)
        new_track = group->tracks->first;
        track = first_track;
        for( ; track && new_track; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                Edit *edit = track->edits->first;
                while( edit && !edit->is_selected ) edit = edit->next;
                if( !edit ) continue;