rework set default transtion, nested proxy edl fixes, doubleclick proxy media fix...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / edl.C
index 3c3de37f9aa31b93be26a2eec2dc0dee6ea37bfb..ccc5a1b9999e6ff90692a3847bd897a7c4cf8b18 100644 (file)
 #include "autoconf.h"
 #include "automation.h"
 #include "awindowgui.inc"
+#include "bccmodels.h"
+#include "bchash.h"
 #include "bcsignals.h"
 #include "clip.h"
 #include "cstrdup.h"
-#include "bccmodels.h"
-#include "bchash.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"
@@ -735,6 +737,7 @@ double EDL::equivalent_output(EDL *edl)
 
 void EDL::set_path(const char *path)
 {
+       if( &this->path[0] == path ) return;
        strcpy(this->path, path);
 }
 
@@ -1460,3 +1463,125 @@ double EDL::prev_edit(double position)
        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,
+       ArrayList<Indexable*> *orig_assets, ArrayList<Indexable*> *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;
+
+       if( use_scaler ) {
+               for( int i=0; i<proxy_assets->size(); ++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(); i<n; ++i ) {
+               const char *orig_path = orig_assets->get(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(); j<m; ++j ) {
+                       EDL *clip = clips[j];
+                       int has_proxy = 0;
+                       for( Track *track=clip->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;
+                                       has_proxy = 1;
+                               }
+                       }
+                       if( has_proxy && !orig_use_scaler )
+                               clip->rescale_proxy(orig_scale, new_scale);
+               }
+       }
+}
+
+void EDL::add_proxy(int use_scaler,
+       ArrayList<Indexable*> *orig_assets, ArrayList<Indexable*> *proxy_assets)
+{
+       if( use_scaler ) {
+               for( int i=0,n=proxy_assets->size(); i<n; ++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();
+               }
+       }
+
+// change original assets to proxy assets
+       for( int i=0,n=proxy_assets->size(); i<n; ++i ) {
+               Asset *proxy_asset = assets->update((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;
+                               }
+                       }
+               }
+       }
+}
+