sams folder icons, snap drag, sort folders, in/out ptr bug, interp bg fix, filebox...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / edl.C
index d1d904aa795647605031cf3df393e4fbf5f7a181..d6810aa763b05bd779b34a4a3c441c648aa381bf 100644 (file)
 #include "filexml.h"
 #include "guicast.h"
 #include "indexstate.h"
+#include "interlacemodes.h"
 #include "labels.h"
 #include "localsession.h"
+#include "maskautos.h"
 #include "mutex.h"
 #include "nestededls.h"
 #include "panauto.h"
@@ -74,9 +76,9 @@ EDL::EDL(EDL *parent_edl)
 
        folders.set_array_delete();
 
-       new_folder(CLIP_FOLDER);
-
-       new_folder(MEDIA_FOLDER);
+// persistent for now
+//     new_folder(CLIP_FOLDER);
+//     new_folder(MEDIA_FOLDER);
 
        id = next_id();
        path[0] = 0;
@@ -277,6 +279,8 @@ int EDL::load_xml(FileXML *file,
                                        if((load_flags & LOAD_VCONFIG) &&
                                                (load_flags & LOAD_SESSION))
                                                session->load_video_config(file, 0, load_flags);
+                                       else
+                                               result = file->skip_tag();
                                }
                                else
                                if(file->tag.title_is("AUDIO"))
@@ -284,6 +288,8 @@ int EDL::load_xml(FileXML *file,
                                        if((load_flags & LOAD_ACONFIG) &&
                                                (load_flags & LOAD_SESSION))
                                                session->load_audio_config(file, 0, load_flags);
+                                       else
+                                               result = file->skip_tag();
                                }
                                else
                                if(file->tag.title_is("FOLDER"))
@@ -297,12 +303,16 @@ int EDL::load_xml(FileXML *file,
                                {
                                        if(load_flags & LOAD_ASSETS)
                                                assets->load(file, load_flags);
+                                       else
+                                               result = file->skip_tag();
                                }
                                else
                                if(file->tag.title_is(labels->xml_tag))
                                {
                                        if(load_flags & LOAD_TIMEBAR)
                                                labels->load(file, load_flags);
+                                       else
+                                               result = file->skip_tag();
                                }
                                else
                                if(file->tag.title_is("LOCALSESSION"))
@@ -310,6 +320,8 @@ int EDL::load_xml(FileXML *file,
                                        if((load_flags & LOAD_SESSION) ||
                                                (load_flags & LOAD_TIMEBAR))
                                                local_session->load_xml(file, load_flags);
+                                       else
+                                               result = file->skip_tag();
                                }
                                else
                                if(file->tag.title_is("SESSION"))
@@ -317,6 +329,8 @@ int EDL::load_xml(FileXML *file,
                                        if((load_flags & LOAD_SESSION) &&
                                                !parent_edl)
                                                session->load_xml(file, 0, load_flags);
+                                       else
+                                               result = file->skip_tag();
                                }
                                else
                                if(file->tag.title_is("TRACK"))
@@ -595,14 +609,9 @@ int EDL::copy(double start,
 
 // Media
 // Don't replicate all assets for every clip.
-// The assets for the clips are probably in the mane EDL.
-               if(!is_clip)
-                       copy_assets(start,
-                               end,
-                               file,
-                               all,
-                               output_path);
-
+// The assets for the clips are probably in the main EDL.
+               if( !is_clip )
+                       copy_assets(start, end, file, all, output_path);
 // Clips
 // Don't want this if using clipboard
                if(all)
@@ -635,10 +644,9 @@ int EDL::copy(double start,
 //printf("EDL::copy 2\n");
 
 // terminate file
-       if(is_clip)
+       if( is_clip )
                file->tag.set_title("/CLIP_EDL");
-       else
-       if(is_vwindow)
+       else if( is_vwindow )
                file->tag.set_title("/VWINDOW_EDL");
        else
                file->tag.set_title("/EDL");
@@ -656,6 +664,26 @@ int EDL::copy(double start,
        return 0;
 }
 
+void EDL::retrack()
+{
+       int min_w = session->output_w, min_h = session->output_h;
+       for( Track *track=tracks->first; track!=0; track=track->next ) {
+               if( track->data_type != TRACK_VIDEO ) continue;
+               int w = min_w, h = min_h;
+               for( Edit *current=track->edits->first; current!=0; current=NEXT ) {
+                       Indexable* indexable = current->get_source();
+                       if( !indexable ) continue;
+                       int edit_w = indexable->get_w(), edit_h = indexable->get_h();
+                       if( w < edit_w ) w = edit_w;
+                       if( h < edit_h ) h = edit_h;
+               }
+               if( track->track_w == w && track->track_h == h ) continue;
+               ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->
+                       translate_masks( (w - track->track_w) / 2, (h - track->track_h) / 2);
+               track->track_w = w;  track->track_h = h;
+       }
+}
+
 void EDL::rechannel()
 {
        for(Track *current = tracks->first; current; current = NEXT)
@@ -745,7 +773,7 @@ double EDL::equivalent_output(EDL *edl)
 }
 
 
-void EDL::set_path(char *path)
+void EDL::set_path(const char *path)
 {
        strcpy(this->path, path);
 }
@@ -988,19 +1016,10 @@ int64_t EDL::get_tracks_width()
 // Get the total output size scaled to aspect ratio
 void EDL::calculate_conformed_dimensions(int single_channel, float &w, float &h)
 {
-       w = session->output_w;
-       h = session->output_h;
-
        if((float)session->output_w / session->output_h > get_aspect_ratio())
-       {
-               h = (float)h *
-                       (session->output_w / get_aspect_ratio() / session->output_h);
-       }
+               h = (w = session->output_w) / get_aspect_ratio();
        else
-       {
-               w = (float)w *
-                       (h * get_aspect_ratio() / session->output_w);
-       }
+               w = (h = session->output_h) * get_aspect_ratio();
 }
 
 float EDL::get_aspect_ratio()
@@ -1023,7 +1042,7 @@ int EDL::dump(FILE *fp)
                local_session->loop_end);
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               fprintf(fp,"  pane %d view_start=%jd track_start=%jd\n", i,
+               fprintf(fp,"  pane %d view_start=%jd track_start=%d\n", i,
                        local_session->view_start[i],
                        local_session->track_start[i]);
        }
@@ -1285,48 +1304,12 @@ void EDL::get_shared_tracks(Track *track,
 // Convert position to frames if cursor alignment is enabled
 double EDL::align_to_frame(double position, int round)
 {
-//printf("EDL::align_to_frame 1 %f\n", position);
-       if(session->cursor_on_frames)
-       {
-// Seconds -> Frames
-               double temp = (double)position * session->frame_rate;
-//printf("EDL::align_to_frame 2 %f\n", temp);
-
-// Assert some things
-               if(session->sample_rate == 0)
-                       printf("EDL::align_to_frame: sample_rate == 0\n");
-
-               if(session->frame_rate == 0)
-                       printf("EDL::align_to_frame: frame_rate == 0\n");
-
-// Round frames
-// Always round down negative numbers
-// but round up only if requested
-               if(round)
-               {
-                       temp = Units::round(temp);
-               }
-               else
-               {
-//                     if(temp < 0)
-//                     {
-//                             temp -= 0.5;
-//                     }
-//                     else
-                               temp = Units::to_int64(temp);
-               }
-//printf("EDL::align_to_frame 3 %f\n", temp);
-
-// Frames -> Seconds
-               temp /= session->frame_rate;
-
-//printf("EDL::align_to_frame 5 %f\n", temp);
-
-               return temp;
+       if( session->cursor_on_frames && session->frame_rate > 0 ) {
+               double frame_no = position * session->frame_rate;
+               int64_t frame_pos = frame_no + (round ? 0.5 : 1e-6);
+               double pos = frame_pos / session->frame_rate;
+               if( !EQUIV(pos, position) ) position = pos;
        }
-//printf("EDL::align_to_frame 3 %d\n", position);
-
-
        return position;
 }
 
@@ -1448,20 +1431,23 @@ if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
 
 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
 // Edit is not a nested EDL
+       Asset *asset = (*playable_edit)->asset;
 // Edit is silence
-       if(!(*playable_edit)->asset) return 1;
+       if(!asset) return 1;
 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
 
-
 // Asset and output device must have the same dimensions
-       if((*playable_edit)->asset->width != session->output_w ||
-               (*playable_edit)->asset->height != session->output_h)
+       if( asset->width != session->output_w ||
+           asset->height != session->output_h )
                return 1;
 
 
 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
-
-
+// Asset and output device must have same resulting de-interlacing method
+       if( ilaceautofixmethod2(session->interlace_mode,
+           asset->interlace_autofixoption, asset->interlace_mode,
+           asset->interlace_fixmethod) != ILACE_FIXMETHOD_NONE )
+               return 1;
 
 // If we get here the frame is going to be directly copied.  Whether it is
 // decompressed in hardware depends on the colormodel.
@@ -1563,3 +1549,51 @@ void EDL::append_vwindow_edl(EDL *edl, int increase_counter)
 }
 
 
+double EDL::next_edit(double position)
+{
+       Units::fix_double(&position);
+       double new_position = tracks->total_length();
+
+       double max_rate = get_frame_rate();
+       int sample_rate = get_sample_rate();
+       if( sample_rate > max_rate ) max_rate = sample_rate;
+       double min_movement = max_rate > 0 ? 1. / max_rate : 1e-6;
+
+// Test for edit handles after position
+       for( Track *track=tracks->first; track; track=track->next ) {
+               if( !track->record ) 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);
+                       if( fabs(edit_end-position) < min_movement ) continue;
+                       if( edit_end > position && edit_end < new_position )
+                               new_position = edit_end;
+               }
+       }
+       return new_position;
+}
+
+double EDL::prev_edit(double position)
+{
+       Units::fix_double(&position);
+       double new_position = -1;
+
+       double max_rate = get_frame_rate();
+       int sample_rate = get_sample_rate();
+       if( sample_rate > max_rate ) max_rate = sample_rate;
+       double min_movement = max_rate > 0 ? 1. / max_rate : 1e-6;
+
+// Test for edit handles before cursor position
+       for( Track *track=tracks->first; track; track=track->next ) {
+               if( !track->record ) continue;
+               for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                       double edit_end = track->from_units(edit->startproject);
+                       Units::fix_double(&edit_end);
+                       if( fabs(edit_end-position) < min_movement ) continue;
+                       if( edit_end < position && edit_end > new_position )
+                               new_position = edit_end;
+               }
+       }
+       return new_position;
+}
+