4 * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "automation.h"
27 #include "awindowgui.inc"
28 #include "bcsignals.h"
30 #include "bccmodels.h"
34 #include "edlsession.h"
37 #include "indexstate.h"
38 #include "interlacemodes.h"
40 #include "localsession.h"
42 #include "nestededls.h"
45 #include "playbackconfig.h"
46 #include "playabletracks.h"
48 #include "preferences.h"
49 #include "recordconfig.h"
50 #include "recordlabel.h"
51 #include "sharedlocation.h"
54 #include "transportque.inc"
55 #include "versioninfo.h"
62 Mutex* EDL::id_lock = 0;
66 EDL::EDL(EDL *parent_edl)
69 this->parent_edl = parent_edl;
74 // vwindow_edl_shared = 0;
76 folders.set_array_delete();
79 // new_folder(CLIP_FOLDER);
80 // new_folder(MEDIA_FOLDER);
101 delete local_session;
105 remove_vwindow_edls();
107 // if(vwindow_edl && !vwindow_edl_shared)
108 // vwindow_edl->Garbage::remove_user();
117 folders.remove_all_objects();
118 for(int i = 0; i < clips.size(); i++)
119 clips.get(i)->Garbage::remove_user();
126 void EDL::create_objects()
128 tracks = new Tracks(this);
131 assets = new Assets(this);
132 session = new EDLSession(this);
136 assets = parent_edl->assets;
137 session = parent_edl->session;
140 local_session = new LocalSession(this);
141 labels = new Labels(this, "LABELS");
142 nested_edls = new NestedEDLs;
143 // last_playback_position = 0;
146 EDL& EDL::operator=(EDL &edl)
148 printf("EDL::operator= 1\n");
153 int EDL::load_defaults(BC_Hash *defaults)
156 session->load_defaults(defaults);
158 local_session->load_defaults(defaults);
162 int EDL::save_defaults(BC_Hash *defaults)
165 session->save_defaults(defaults);
167 local_session->save_defaults(defaults);
171 void EDL::boundaries()
173 session->boundaries();
174 local_session->boundaries();
177 int EDL::create_default_tracks()
180 for(int i = 0; i < session->video_tracks; i++)
182 tracks->add_video_track(0, 0);
184 for(int i = 0; i < session->audio_tracks; i++)
186 tracks->add_audio_track(0, 0);
191 int EDL::load_xml(FileXML *file,
195 // Track numbering offset for replacing undo data.
196 int track_offset = 0;
199 folders.remove_all_objects();
201 if((load_flags & LOAD_ALL) == LOAD_ALL)
203 remove_vwindow_edls();
207 // Search for start of master EDL.
209 // The parent_edl test caused clip creation to fail since those XML files
210 // contained an EDL tag.
212 // The parent_edl test is required to make EDL loading work because
213 // when loading an EDL the EDL tag is already read by the parent.
218 result = file->read_tag();
220 !file->tag.title_is("XML") &&
221 !file->tag.title_is("EDL"));
226 // Get path for backups
228 file->tag.get_property("path", path);
231 if((load_flags & LOAD_ALL) == LOAD_ALL ||
232 (load_flags & LOAD_EDITS) == LOAD_EDITS)
234 while(tracks->last) delete tracks->last;
237 if((load_flags & LOAD_ALL) == LOAD_ALL)
239 for(int i = 0; i < clips.size(); i++)
240 clips.get(i)->Garbage::remove_user();
244 if(load_flags & LOAD_TIMEBAR)
246 while(labels->last) delete labels->last;
247 local_session->unset_inpoint();
248 local_session->unset_outpoint();
251 // This was originally in LocalSession::load_xml
252 if(load_flags & LOAD_SESSION)
254 local_session->clipboard_length = 0;
258 result = file->read_tag();
262 if(file->tag.title_is("/XML") ||
263 file->tag.title_is("/EDL") ||
264 file->tag.title_is("/CLIP_EDL") ||
265 file->tag.title_is("/VWINDOW_EDL"))
270 if(file->tag.title_is("CLIPBOARD"))
272 local_session->clipboard_length =
273 file->tag.get_property("LENGTH", (double)0);
276 if(file->tag.title_is("VIDEO"))
278 if((load_flags & LOAD_VCONFIG) &&
279 (load_flags & LOAD_SESSION))
280 session->load_video_config(file, 0, load_flags);
282 result = file->skip_tag();
285 if(file->tag.title_is("AUDIO"))
287 if((load_flags & LOAD_ACONFIG) &&
288 (load_flags & LOAD_SESSION))
289 session->load_audio_config(file, 0, load_flags);
291 result = file->skip_tag();
294 if(file->tag.title_is("FOLDER"))
296 char folder[BCTEXTLEN];
297 strcpy(folder, file->read_text());
301 if(file->tag.title_is("ASSETS"))
303 if(load_flags & LOAD_ASSETS)
304 assets->load(file, load_flags);
306 result = file->skip_tag();
309 if(file->tag.title_is(labels->xml_tag))
311 if(load_flags & LOAD_TIMEBAR)
312 labels->load(file, load_flags);
314 result = file->skip_tag();
317 if(file->tag.title_is("LOCALSESSION"))
319 if((load_flags & LOAD_SESSION) ||
320 (load_flags & LOAD_TIMEBAR))
321 local_session->load_xml(file, load_flags);
323 result = file->skip_tag();
326 if(file->tag.title_is("SESSION"))
328 if((load_flags & LOAD_SESSION) &&
330 session->load_xml(file, 0, load_flags);
332 result = file->skip_tag();
335 if(file->tag.title_is("TRACK"))
337 tracks->load(file, track_offset, load_flags);
341 // Causes clip creation to fail because that involves an opening EDL tag.
342 if(file->tag.title_is("CLIP_EDL") && !parent_edl)
344 EDL *new_edl = new EDL(this);
345 new_edl->create_objects();
346 new_edl->load_xml(file, LOAD_ALL);
348 if((load_flags & LOAD_ALL) == LOAD_ALL)
349 clips.append(new_edl);
351 new_edl->Garbage::remove_user();
354 if(file->tag.title_is("VWINDOW_EDL") && !parent_edl)
356 EDL *new_edl = new EDL(this);
357 new_edl->create_objects();
358 new_edl->load_xml(file, LOAD_ALL);
361 if((load_flags & LOAD_ALL) == LOAD_ALL)
363 // if(vwindow_edl && !vwindow_edl_shared)
364 // vwindow_edl->Garbage::remove_user();
365 // vwindow_edl_shared = 0;
366 // vwindow_edl = new_edl;
368 append_vwindow_edl(new_edl, 0);
372 // Discard if not replacing EDL
374 new_edl->Garbage::remove_user();
387 // Output path is the path of the output file if name truncation is desired.
388 // It is a "" if complete names should be used.
389 // Called recursively by copy for clips, thus the string can't be terminated.
390 // The string is not terminated in this call.
391 int EDL::save_xml(FileXML *file,
392 const char *output_path,
397 tracks->total_length(),
407 int EDL::copy_all(EDL *edl)
409 if(this == edl) return 0;
411 nested_edls->clear();
415 tracks->copy_from(edl->tracks);
416 labels->copy_from(edl->labels);
420 void EDL::copy_clips(EDL *edl)
422 if(this == edl) return;
424 remove_vwindow_edls();
426 // if(vwindow_edl && !vwindow_edl_shared)
427 // vwindow_edl->Garbage::remove_user();
429 // vwindow_edl_shared = 0;
431 for(int i = 0; i < edl->total_vwindow_edls(); i++)
433 EDL *new_edl = new EDL(this);
434 new_edl->create_objects();
435 new_edl->copy_all(edl->get_vwindow_edl(i));
436 append_vwindow_edl(new_edl, 0);
439 for(int i = 0; i < clips.size(); i++)
440 clips.get(i)->Garbage::remove_user();
442 for(int i = 0; i < edl->clips.total; i++)
444 add_clip(edl->clips.values[i]);
448 void EDL::copy_assets(EDL *edl)
450 if(this == edl) return;
454 assets->copy_from(edl->assets);
458 void EDL::copy_session(EDL *edl, int session_only)
460 if(this == edl) return;
464 strcpy(this->path, edl->path);
465 //printf("EDL::copy_session %p %s\n", this, this->path);
467 folders.remove_all_objects();
468 for(int i = 0; i < edl->folders.total; i++)
471 folders.append(new_folder = new char[strlen(edl->folders.values[i]) + 1]);
472 strcpy(new_folder, edl->folders.values[i]);
478 session->copy(edl->session);
483 local_session->copy_from(edl->local_session);
487 int EDL::copy_assets(double start,
491 const char *output_path)
493 ArrayList<Asset*> asset_list;
496 file->tag.set_title("ASSETS");
498 file->append_newline();
500 // Copy everything for a save
503 for(Asset *asset = assets->first;
507 asset_list.append(asset);
511 // Copy just the ones being used.
513 for(current = tracks->first;
519 current->copy_assets(start,
526 // Paths relativised here
527 for(int i = 0; i < asset_list.total; i++)
529 asset_list.values[i]->write(file,
534 file->tag.set_title("/ASSETS");
536 file->append_newline();
537 file->append_newline();
541 int EDL::copy(double start,
547 const char *output_path,
550 //printf("EDL::copy 1\n");
553 file->tag.set_title("CLIP_EDL");
556 file->tag.set_title("VWINDOW_EDL");
559 file->tag.set_title("EDL");
560 file->tag.set_property("VERSION", CINELERRA_VERSION);
561 // Save path for restoration of the project title from a backup.
564 file->tag.set_property("PATH", path);
569 file->append_newline();
571 // Set clipboard samples only if copying to clipboard
574 file->tag.set_title("CLIPBOARD");
575 file->tag.set_property("LENGTH", end - start);
577 file->tag.set_title("/CLIPBOARD");
579 file->append_newline();
580 file->append_newline();
582 //printf("EDL::copy 1\n");
585 local_session->save_xml(file, start);
587 //printf("EDL::copy 1\n");
592 // Need to copy all this from child EDL if pasting is desired.
594 session->save_xml(file);
595 session->save_video_config(file);
596 session->save_audio_config(file);
599 for(int i = 0; i < folders.total; i++)
601 file->tag.set_title("FOLDER");
603 file->append_text(folders.values[i]);
604 file->tag.set_title("/FOLDER");
606 file->append_newline();
610 // Don't replicate all assets for every clip.
611 // The assets for the clips are probably in the mane EDL.
620 // Don't want this if using clipboard
623 for(int i = 0; i < total_vwindow_edls(); i++)
625 get_vwindow_edl(i)->save_xml(file,
631 for(int i = 0; i < clips.total; i++)
632 clips.values[i]->save_xml(file,
638 file->append_newline();
639 file->append_newline();
643 //printf("EDL::copy 1\n");
645 labels->copy(start, end, file);
646 //printf("EDL::copy 1\n");
647 tracks->copy(start, end, all, file, output_path);
648 //printf("EDL::copy 2\n");
652 file->tag.set_title("/CLIP_EDL");
655 file->tag.set_title("/VWINDOW_EDL");
657 file->tag.set_title("/EDL");
659 file->append_newline();
662 // For editing operations we want to rewind it for immediate pasting.
663 // For clips and saving to disk leave it alone.
666 file->terminate_string();
672 void EDL::rechannel()
674 for(Track *current = tracks->first; current; current = NEXT)
676 if(current->data_type == TRACK_AUDIO)
678 PanAutos *autos = (PanAutos*)current->automation->autos[AUTOMATION_PAN];
679 ((PanAuto*)autos->default_auto)->rechannel();
680 for(PanAuto *keyframe = (PanAuto*)autos->first;
682 keyframe = (PanAuto*)keyframe->next)
684 keyframe->rechannel();
690 void EDL::resample(double old_rate, double new_rate, int data_type)
692 for(Track *current = tracks->first; current; current = NEXT)
694 if(current->data_type == data_type)
696 current->resample(old_rate, new_rate);
702 void EDL::synchronize_params(EDL *edl)
704 local_session->synchronize_params(edl->local_session);
705 for(Track *this_track = tracks->first, *that_track = edl->tracks->first;
706 this_track && that_track;
707 this_track = this_track->next,
708 that_track = that_track->next)
710 this_track->synchronize_params(that_track);
714 int EDL::trim_selection(double start,
729 tracks->total_length(),
738 int EDL::equivalent(double position1, double position2)
740 double threshold = (double).5 / session->frame_rate;
741 if(session->cursor_on_frames)
742 threshold = (double).5 / session->frame_rate;
744 threshold = (double)1 / session->sample_rate;
746 if(fabs(position2 - position1) < threshold)
752 double EDL::equivalent_output(EDL *edl)
755 session->equivalent_output(edl->session, &result);
756 tracks->equivalent_output(edl->tracks, &result);
761 void EDL::set_path(char *path)
763 strcpy(this->path, path);
766 void EDL::set_inpoint(double position)
768 if(equivalent(local_session->get_inpoint(), position) &&
769 local_session->get_inpoint() >= 0)
771 local_session->unset_inpoint();
775 local_session->set_inpoint(align_to_frame(position, 0));
776 if(local_session->get_outpoint() <= local_session->get_inpoint())
777 local_session->unset_outpoint();
781 void EDL::set_outpoint(double position)
783 if(equivalent(local_session->get_outpoint(), position) &&
784 local_session->get_outpoint() >= 0)
786 local_session->unset_outpoint();
790 local_session->set_outpoint(align_to_frame(position, 0));
791 if(local_session->get_inpoint() >= local_session->get_outpoint())
792 local_session->unset_inpoint();
797 int EDL::clear(double start,
806 tracks->clear_handle(start,
812 if(clear_labels && distance > 0)
813 labels->paste_silence(start,
828 // Need to put at beginning so a subsequent paste operation starts at the
830 double position = local_session->get_selectionstart();
831 local_session->set_selectionend(position);
832 local_session->set_selectionstart(position);
836 void EDL::modify_edithandles(double oldposition,
844 tracks->modify_edithandles(oldposition,
851 labels->modify_handles(oldposition,
858 void EDL::modify_pluginhandles(double oldposition,
866 tracks->modify_pluginhandles(oldposition,
876 void EDL::paste_silence(double start,
883 labels->paste_silence(start, end);
884 tracks->paste_silence(start,
891 void EDL::remove_from_project(ArrayList<EDL*> *clips)
893 for(int i = 0; i < clips->size(); i++)
895 for(int j = 0; j < this->clips.size(); j++)
897 if(this->clips.get(j) == clips->values[i])
899 EDL *clip = this->clips.get(j);
900 this->clips.remove(clip);
901 clip->Garbage::remove_user();
907 void EDL::remove_from_project(ArrayList<Indexable*> *assets)
911 for(int j = 0; j < clips.total; j++)
913 clips.values[j]->remove_from_project(assets);
916 // Remove from VWindow EDLs
917 for(int i = 0; i < total_vwindow_edls(); i++)
918 get_vwindow_edl(i)->remove_from_project(assets);
920 for(int i = 0; i < assets->size(); i++)
922 // Remove from tracks
923 for(Track *track = tracks->first; track; track = track->next)
925 track->remove_asset(assets->get(i));
928 // Remove from assets
929 if(!parent_edl && assets->get(i)->is_asset)
931 this->assets->remove_asset((Asset*)assets->get(i));
934 if(!parent_edl && !assets->get(i)->is_asset)
936 this->nested_edls->remove_edl((EDL*)assets->get(i));
941 void EDL::update_assets(EDL *src)
943 for(Asset *current = src->assets->first;
947 assets->update(current);
951 int EDL::get_tracks_height(Theme *theme)
953 int total_pixels = 0;
954 for(Track *current = tracks->first;
958 total_pixels += current->vertical_span(theme);
963 int64_t EDL::get_tracks_width()
965 int64_t total_pixels = 0;
966 for(Track *current = tracks->first;
970 int64_t pixels = current->horizontal_span();
971 if(pixels > total_pixels) total_pixels = pixels;
973 //printf("EDL::get_tracks_width %d\n", total_pixels);
977 // int EDL::calculate_output_w(int single_channel)
979 // if(single_channel) return session->output_w;
982 // for(int i = 0; i < session->video_channels; i++)
984 // if(session->vchannel_x[i] + session->output_w > widest) widest = session->vchannel_x[i] + session->output_w;
989 // int EDL::calculate_output_h(int single_channel)
991 // if(single_channel) return session->output_h;
994 // for(int i = 0; i < session->video_channels; i++)
996 // if(session->vchannel_y[i] + session->output_h > tallest) tallest = session->vchannel_y[i] + session->output_h;
1001 // Get the total output size scaled to aspect ratio
1002 void EDL::calculate_conformed_dimensions(int single_channel, float &w, float &h)
1004 w = session->output_w;
1005 h = session->output_h;
1007 if((float)session->output_w / session->output_h > get_aspect_ratio())
1010 (session->output_w / get_aspect_ratio() / session->output_h);
1015 (h * get_aspect_ratio() / session->output_w);
1019 float EDL::get_aspect_ratio()
1021 return session->aspect_w / session->aspect_h;
1024 int EDL::dump(FILE *fp)
1027 fprintf(fp,"CLIP\n");
1029 fprintf(fp,"EDL\n");
1030 fprintf(fp," clip_title: %s\n"
1031 " parent_edl: %p\n", local_session->clip_title, parent_edl);
1032 fprintf(fp," selectionstart %f\n selectionend %f\n loop_start %f\n loop_end %f\n",
1033 local_session->get_selectionstart(1),
1034 local_session->get_selectionend(1),
1035 local_session->loop_start,
1036 local_session->loop_end);
1037 for(int i = 0; i < TOTAL_PANES; i++)
1039 fprintf(fp," pane %d view_start=%jd track_start=%d\n", i,
1040 local_session->view_start[i],
1041 local_session->track_start[i]);
1046 fprintf(fp,"audio_channels: %d audio_tracks: %d sample_rate: %jd\n",
1047 session->audio_channels,
1048 session->audio_tracks,
1049 session->sample_rate);
1050 fprintf(fp," video_channels: %d\n"
1051 " video_tracks: %d\n"
1052 " frame_rate: %.2f\n"
1053 " frames_per_foot: %.2f\n"
1058 " color_model: %d\n",
1059 session->video_channels,
1060 session->video_tracks,
1061 session->frame_rate,
1062 session->frames_per_foot,
1067 session->color_model);
1069 fprintf(fp," CLIPS\n");
1070 fprintf(fp," total: %d\n", clips.total);
1072 for(int i = 0; i < clips.total; i++)
1075 clips.values[i]->dump(fp);
1079 fprintf(fp," VWINDOW EDLS\n");
1080 fprintf(fp," total: %d\n", total_vwindow_edls());
1082 for(int i = 0; i < total_vwindow_edls(); i++)
1084 fprintf(fp," %s\n", get_vwindow_edl(i)->local_session->clip_title);
1087 fprintf(fp," ASSETS\n");
1090 fprintf(fp," LABELS\n");
1092 fprintf(fp," TRACKS\n");
1094 //printf("EDL::dump 2\n");
1098 EDL* EDL::add_clip(EDL *edl)
1100 // Copy argument. New edls are deleted from MWindow::load_filenames.
1101 EDL *new_edl = new EDL(this);
1102 new_edl->create_objects();
1103 new_edl->copy_all(edl);
1104 clips.append(new_edl);
1108 void EDL::insert_asset(Asset *asset,
1112 RecordLabels *labels)
1114 // Insert asset into asset table
1115 Asset *new_asset = 0;
1116 EDL *new_nested_edl = 0;
1118 if(asset) new_asset = assets->update(asset);
1119 if(nested_edl) new_nested_edl = nested_edls->get_copy(nested_edl);
1123 Track *current = first_track ? first_track : tracks->first;
1126 // Fix length of single frame
1133 length = new_nested_edl->tracks->total_playable_length();
1135 channels = new_nested_edl->session->audio_channels;
1140 // Insert 1 frame for undefined length
1141 if(new_asset->video_length < 0)
1143 length = session->si_useduration ?
1144 session->si_duration :
1145 1.0 / session->frame_rate;
1148 length = new_asset->frame_rate > 0 ?
1149 (double)new_asset->video_length / new_asset->frame_rate :
1150 1.0 / session->frame_rate;
1152 layers = new_asset->layers;
1153 channels = new_asset->channels;
1157 current && vtrack < layers;
1160 if(!current->record ||
1161 current->data_type != TRACK_VIDEO)
1164 current->insert_asset(new_asset,
1176 if(new_asset->audio_length < 0)
1178 // Insert 1 frame for undefined length & video
1179 if(new_asset->video_data)
1180 length = (double)1.0 / new_asset->frame_rate;
1182 // Insert 1 second for undefined length & no video
1186 length = (double)new_asset->audio_length /
1187 new_asset->sample_rate;
1190 for(current = tracks->first;
1191 current && atrack < channels;
1194 if(!current->record ||
1195 current->data_type != TRACK_AUDIO)
1198 current->insert_asset(new_asset,
1208 // Insert labels from a recording window.
1211 for(RecordLabel *label = labels->first; label; label = label->next)
1213 this->labels->toggle_label(label->position, label->position);
1220 void EDL::set_index_file(Indexable *indexable)
1222 if(indexable->is_asset)
1223 assets->update_index((Asset*)indexable);
1225 nested_edls->update_index((EDL*)indexable);
1228 void EDL::optimize()
1230 //printf("EDL::optimize 1\n");
1231 if(local_session->preview_start < 0) local_session->preview_start = 0;
1232 double length = tracks->total_length();
1233 if(local_session->preview_end > length) local_session->preview_end = length;
1234 if(local_session->preview_start >= local_session->preview_end ) {
1235 local_session->preview_start = 0;
1236 local_session->preview_end = length;
1238 for(Track *current = tracks->first; current; current = NEXT)
1239 current->optimize();
1244 id_lock->lock("EDL::next_id");
1245 int result = EDLSession::current_id++;
1250 void EDL::get_shared_plugins(Track *source,
1251 ArrayList<SharedLocation*> *plugin_locations,
1252 int omit_recordable,
1255 for(Track *track = tracks->first; track; track = track->next)
1257 if(!track->record || !omit_recordable)
1259 if(track != source &&
1260 track->data_type == data_type)
1262 for(int i = 0; i < track->plugin_set.total; i++)
1264 Plugin *plugin = track->get_current_plugin(
1265 local_session->get_selectionstart(1),
1270 if(plugin && plugin->plugin_type == PLUGIN_STANDALONE)
1272 plugin_locations->append(new SharedLocation(tracks->number_of(track), i));
1280 void EDL::get_shared_tracks(Track *track,
1281 ArrayList<SharedLocation*> *module_locations,
1282 int omit_recordable,
1285 for(Track *current = tracks->first; current; current = NEXT)
1287 if(!omit_recordable || !current->record)
1289 if(current != track &&
1290 current->data_type == data_type)
1292 module_locations->append(new SharedLocation(tracks->number_of(current), 0));
1298 // Convert position to frames if cursor alignment is enabled
1299 double EDL::align_to_frame(double position, int round)
1301 if( session->cursor_on_frames && session->frame_rate > 0 ) {
1302 double frame_no = position * session->frame_rate;
1303 int64_t frame_pos = frame_no + (round ? 0.5 : 1e-6);
1304 double pos = frame_pos / session->frame_rate;
1305 if( !EQUIV(pos, position) ) position = pos;
1311 void EDL::new_folder(const char *folder)
1313 for(int i = 0; i < folders.total; i++)
1315 if(!strcasecmp(folders.values[i], folder)) return;
1319 folders.append(new_folder = new char[strlen(folder) + 1]);
1320 strcpy(new_folder, folder);
1323 void EDL::delete_folder(const char *folder)
1326 for(i = 0; i < folders.total; i++)
1328 if(!strcasecmp(folders.values[i], folder))
1334 if(i < folders.total) delete folders.values[i];
1336 for( ; i < folders.total - 1; i++)
1338 folders.values[i] = folders.values[i + 1];
1342 int EDL::get_use_vconsole(VEdit* *playable_edit,
1345 PlayableTracks *playable_tracks)
1347 int share_playable_tracks = 1;
1349 VTrack *playable_track = 0;
1350 const int debug = 0;
1353 // Calculate playable tracks when being called as a nested EDL
1354 if(!playable_tracks)
1356 share_playable_tracks = 0;
1357 playable_tracks = new PlayableTracks(this,
1365 // Total number of playable tracks is 1
1366 if(playable_tracks->size() != 1)
1372 playable_track = (VTrack*)playable_tracks->get(0);
1375 // Don't need playable tracks anymore
1376 if(!share_playable_tracks)
1378 delete playable_tracks;
1381 if(debug) printf("EDL::get_use_vconsole %d playable_tracks->size()=%d\n",
1383 playable_tracks->size());
1384 if(result) return 1;
1387 // Test mutual conditions between direct copy rendering and this.
1388 if(!playable_track->direct_copy_possible(position,
1392 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
1394 *playable_edit = (VEdit*)playable_track->edits->editof(position,
1397 // No edit at current location
1398 if(!*playable_edit) return 1;
1399 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
1402 // Edit is nested EDL
1403 if((*playable_edit)->nested_edl)
1406 EDL *nested_edl = (*playable_edit)->nested_edl;
1407 int64_t nested_position = (int64_t)((position -
1408 (*playable_edit)->startproject +
1409 (*playable_edit)->startsource) *
1410 nested_edl->session->frame_rate /
1411 session->frame_rate);
1414 VEdit *playable_edit_temp = 0;
1415 if(session->output_w != nested_edl->session->output_w ||
1416 session->output_h != nested_edl->session->output_h ||
1417 nested_edl->get_use_vconsole(&playable_edit_temp,
1426 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
1427 // Edit is not a nested EDL
1428 Asset *asset = (*playable_edit)->asset;
1430 if(!asset) return 1;
1431 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
1433 // Asset and output device must have the same dimensions
1434 if( asset->width != session->output_w ||
1435 asset->height != session->output_h )
1439 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
1440 // Asset and output device must have same resulting de-interlacing method
1441 if( ilaceautofixmethod2(session->interlace_mode,
1442 asset->interlace_autofixoption, asset->interlace_mode,
1443 asset->interlace_fixmethod) != ILACE_FIXMETHOD_NONE )
1446 // If we get here the frame is going to be directly copied. Whether it is
1447 // decompressed in hardware depends on the colormodel.
1453 int EDL::get_audio_channels()
1455 return session->audio_channels;
1458 int EDL::get_sample_rate()
1460 return session->sample_rate;
1463 int64_t EDL::get_audio_samples()
1465 return (int64_t)(tracks->total_playable_length() *
1466 session->sample_rate);
1469 int EDL::have_audio()
1474 int EDL::have_video()
1482 return session->output_w;
1487 return session->output_h;
1490 double EDL::get_frame_rate()
1492 return session->frame_rate;
1495 int EDL::get_video_layers()
1500 int64_t EDL::get_video_frames()
1502 return (int64_t)(tracks->total_playable_length() *
1503 session->frame_rate);
1507 void EDL::remove_vwindow_edls()
1509 for(int i = 0; i < total_vwindow_edls(); i++)
1511 get_vwindow_edl(i)->Garbage::remove_user();
1513 vwindow_edls.remove_all();
1516 void EDL::remove_vwindow_edl(EDL *edl)
1518 if(vwindow_edls.number_of(edl) >= 0)
1520 edl->Garbage::remove_user();
1522 vwindow_edls.remove(edl);
1527 EDL* EDL::get_vwindow_edl(int number)
1529 return vwindow_edls.get(number);
1532 int EDL::total_vwindow_edls()
1534 return vwindow_edls.size();
1537 void EDL::append_vwindow_edl(EDL *edl, int increase_counter)
1539 if(vwindow_edls.number_of(edl) >= 0) return;
1541 if(increase_counter) edl->Garbage::add_user();
1542 vwindow_edls.append(edl);