2 #include "confirmsave.h"
5 #include "edlsession.h"
8 #include "formatcheck.h"
15 #include "localsession.h"
17 #include "mainsession.h"
20 #include "mwindowgui.h"
21 #include "menueffects.h"
22 #include "playbackengine.h"
23 #include "pluginarray.h"
24 #include "pluginserver.h"
25 #include "preferences.h"
27 #include "sighandler.h"
33 MenuEffects::MenuEffects(MWindow *mwindow)
34 : BC_MenuItem(_("Render effect..."))
36 this->mwindow = mwindow;
39 MenuEffects::~MenuEffects()
44 int MenuEffects::handle_event()
46 thread->set_title("");
54 MenuEffectPacket::MenuEffectPacket(char *path, int64_t start, int64_t end)
58 strcpy(this->path, path);
61 MenuEffectPacket::~MenuEffectPacket()
70 MenuEffectThread::MenuEffectThread(MWindow *mwindow)
72 this->mwindow = mwindow;
76 MenuEffectThread::~MenuEffectThread()
84 int MenuEffectThread::set_title(char *title)
86 strcpy(this->title, title);
89 // for recent effect menu items and running new effects
90 // prompts for an effect if title is blank
91 void MenuEffectThread::run()
93 // get stuff from main window
94 ArrayList<PluginServer*> *plugindb = mwindow->plugindb;
95 Defaults *defaults = mwindow->defaults;
96 ArrayList<BC_ListBoxItem*> plugin_list;
97 ArrayList<PluginServer*> local_plugindb;
101 // Default configuration
104 ArrayList<Asset*> assets;
107 // check for recordable tracks
108 if(!get_recordable_tracks(&default_asset))
110 sprintf(string, _("No recordable tracks specified."));
111 ErrorBox error(PROGRAM_NAME ": Error");
112 error.create_objects(string);
120 sprintf(string, _("No plugins available."));
121 ErrorBox error(PROGRAM_NAME ": Error");
122 error.create_objects(string);
128 // get default attributes for output file
129 // used after completion
130 get_derived_attributes(&default_asset, defaults);
131 // to_tracks = defaults->get("RENDER_EFFECT_TO_TRACKS", 1);
132 load_mode = defaults->get("RENDER_EFFECT_LOADMODE", LOAD_PASTE);
133 strategy = defaults->get("RENDER_EFFECT_STRATEGY", SINGLE_PASS);
135 // get plugin information
142 // generate a list of plugins for the window
145 mwindow->create_plugindb(default_asset.audio_data,
146 default_asset.video_data,
152 for(int i = 0; i < local_plugindb.total; i++)
154 plugin_list.append(new BC_ListBoxItem(_(local_plugindb.values[i]->title)));
158 // find out which effect to run and get output file
159 int plugin_number, format_error = 0;
164 MenuEffectWindow window(mwindow,
166 need_plugin ? &plugin_list : 0,
168 window.create_objects();
169 result = window.run_window();
170 plugin_number = window.result;
175 FormatCheck format_check(&default_asset);
176 format_error = format_check.check_format();
178 }while(format_error && !result);
181 save_derived_attributes(&default_asset, defaults);
182 defaults->update("RENDER_EFFECT_LOADMODE", load_mode);
183 defaults->update("RENDER_EFFECT_STRATEGY", strategy);
184 mwindow->save_defaults();
186 // get plugin server to use and delete the plugin list
187 PluginServer *plugin_server = 0;
188 PluginServer *plugin = 0;
191 plugin_list.remove_all_objects();
192 if(plugin_number > -1)
194 plugin_server = local_plugindb.values[plugin_number];
195 strcpy(title, plugin_server->title);
200 for(int i = 0; i < plugindb->total && !plugin_server; i++)
202 if(!strcmp(plugindb->values[i]->title, title))
204 plugin_server = plugindb->values[i];
210 // Update the most recently used effects and copy the plugin server.
213 plugin = new PluginServer(*plugin_server);
217 if(!result && !strlen(default_asset.path))
219 result = 1; // no output path given
220 ErrorBox error(PROGRAM_NAME ": Error");
221 error.create_objects(_("No output file specified."));
225 if(!result && plugin_number < 0)
227 result = 1; // no output path given
228 ErrorBox error(PROGRAM_NAME ": Error");
229 error.create_objects(_("No effect selected."));
233 // Configuration for realtime plugins.
234 KeyFrame plugin_data;
236 // get selection to render
238 double total_start, total_end;
240 total_start = mwindow->edl->local_session->get_selectionstart();
243 if(mwindow->edl->local_session->get_selectionend() ==
244 mwindow->edl->local_session->get_selectionstart())
245 total_end = mwindow->edl->tracks->total_playable_length();
247 total_end = mwindow->edl->local_session->get_selectionend();
251 // get native units for range
252 total_start = to_units(total_start, 0);
253 total_end = to_units(total_end, 1);
257 // Trick boundaries in case of a non-realtime synthesis plugin
260 total_end == total_start) total_end = total_start + 1;
262 // Units are now in the track's units.
263 int64_t total_length = (int64_t)total_end - (int64_t)total_start;
264 // length of output file
265 int64_t output_start, output_end;
267 if(!result && total_length <= 0)
269 result = 1; // no output path given
270 ErrorBox error(PROGRAM_NAME ": Error");
271 error.create_objects(_("No selected range to process."));
275 // ========================= get keyframe from user
278 // ========================= realtime plugin
283 MenuEffectPrompt prompt(mwindow);
284 prompt.create_objects();
285 char title[BCTEXTLEN];
286 sprintf(title, PROGRAM_NAME ": %s", plugin->title);
288 // Open the plugin GUI
289 plugin->set_mwindow(mwindow);
290 plugin->set_keyframe(&plugin_data);
291 plugin->set_prompt(&prompt);
292 plugin->open_plugin(0, mwindow->preferences, mwindow->edl, 0, -1);
293 // Must set parameters since there is no plugin object to draw from.
294 plugin->get_parameters((int64_t)total_start,
299 // wait for user input
300 result = prompt.run_window();
303 plugin->save_data(&plugin_data);
305 default_asset.sample_rate = mwindow->edl->session->sample_rate;
306 default_asset.frame_rate = mwindow->edl->session->frame_rate;
310 // ============================non realtime plugin
312 plugin->set_mwindow(mwindow);
313 plugin->open_plugin(0, mwindow->preferences, mwindow->edl, 0, -1);
314 result = plugin->get_parameters((int64_t)total_start,
316 get_recordable_tracks(&default_asset));
317 // some plugins can change the sample rate and the frame rate
322 default_asset.sample_rate = plugin->get_samplerate();
323 default_asset.frame_rate = plugin->get_framerate();
329 // Should take from first recordable track
330 default_asset.width = mwindow->edl->session->output_w;
331 default_asset.height = mwindow->edl->session->output_h;
334 // Process the total length in fragments
335 ArrayList<MenuEffectPacket*> packets;
338 Label *current_label = mwindow->edl->labels->first;
339 mwindow->stop_brender();
344 Render::get_starting_number(default_asset.path,
351 // Construct all packets for single overwrite confirmation
352 for(int64_t fragment_start = (int64_t)total_start, fragment_end;
353 fragment_start < (int64_t)total_end;
354 fragment_start = fragment_end)
357 if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
359 while(current_label &&
360 to_units(current_label->position, 0) <= fragment_start)
361 current_label = current_label->next;
363 fragment_end = (int64_t)total_end;
365 fragment_end = to_units(current_label->position, 0);
369 fragment_end = (int64_t)total_end;
373 char path[BCTEXTLEN];
374 if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
375 Render::create_filename(path,
381 strcpy(path, default_asset.path);
384 MenuEffectPacket *packet = new MenuEffectPacket(path,
387 packets.append(packet);
391 // Test existence of files
392 ArrayList<char*> paths;
393 for(int i = 0; i < packets.total; i++)
395 paths.append(packets.values[i]->path);
397 result = ConfirmSave::test_files(mwindow, &paths);
403 for(int current_packet = 0;
404 current_packet < packets.total && !result;
407 Asset *asset = new Asset(default_asset);
408 MenuEffectPacket *packet = packets.values[current_packet];
409 int64_t fragment_start = packet->start;
410 int64_t fragment_end = packet->end;
411 strcpy(asset->path, packet->path);
413 assets.append(asset);
414 File *file = new File;
416 // Open the output file after getting the information because the sample rate
420 // open output file in write mode
421 file->set_processors(mwindow->preferences->processors);
422 if(file->open_file(mwindow->plugindb,
426 mwindow->edl->session->sample_rate,
427 mwindow->edl->session->frame_rate))
430 sprintf(string, _("Couldn't open %s"), asset->path);
431 ErrorBox error(PROGRAM_NAME ": Error");
432 error.create_objects(string);
438 mwindow->sighandler->push_file(file);
439 IndexFile::delete_index(mwindow->preferences, asset);
449 PluginArray *plugin_array;
450 plugin_array = create_plugin_array();
452 plugin_array->start_plugins(mwindow,
459 plugin_array->run_plugins();
461 plugin_array->stop_plugins();
462 mwindow->sighandler->pull_file(file);
464 asset->audio_length = file->asset->audio_length;
465 asset->video_length = file->asset->video_length;
472 packets.remove_all_objects();
474 // paste output to tracks
475 if(!result && load_mode != LOAD_NOTHING)
477 mwindow->gui->lock_window();
478 mwindow->undo->update_undo_before(title, LOAD_ALL);
480 if(load_mode == LOAD_PASTE)
482 mwindow->load_assets(&assets,
487 mwindow->edl->session->labels_follow_edits,
488 mwindow->edl->session->plugins_follow_edits);
491 mwindow->save_backup();
492 mwindow->undo->update_undo_after();
496 mwindow->restart_brender();
497 mwindow->update_plugin_guis();
498 mwindow->gui->update(1,
505 mwindow->sync_parameters(CHANGE_ALL);
506 mwindow->gui->unlock_window();
509 assets.remove_all_objects();
515 MenuEffectItem::MenuEffectItem(MenuEffects *menueffect, char *string)
516 : BC_MenuItem(string)
518 this->menueffect = menueffect;
520 int MenuEffectItem::handle_event()
522 menueffect->thread->set_title(get_text());
523 menueffect->thread->start();
537 MenuEffectWindow::MenuEffectWindow(MWindow *mwindow,
538 MenuEffectThread *menueffects,
539 ArrayList<BC_ListBoxItem*> *plugin_list,
541 : BC_Window(PROGRAM_NAME ": Render effect",
542 mwindow->gui->get_abs_cursor_x(1),
543 mwindow->gui->get_abs_cursor_y(1) - mwindow->session->menueffect_h / 2,
544 mwindow->session->menueffect_w,
545 mwindow->session->menueffect_h,
552 this->menueffects = menueffects;
553 this->plugin_list = plugin_list;
555 this->mwindow = mwindow;
558 MenuEffectWindow::~MenuEffectWindow()
563 // int MenuEffectWindow::calculate_w(int use_plugin_list)
565 // return use_plugin_list ? 580 : 420;
568 // int MenuEffectWindow::calculate_h(int use_plugin_list)
574 int MenuEffectWindow::create_objects()
578 mwindow->theme->get_menueffect_sizes(plugin_list ? 1 : 0);
580 // only add the list if needed
583 add_subwindow(list_title = new BC_Title(mwindow->theme->menueffect_list_x,
584 mwindow->theme->menueffect_list_y,
585 _("Select an effect")));
586 add_subwindow(list = new MenuEffectWindowList(this,
587 mwindow->theme->menueffect_list_x,
588 mwindow->theme->menueffect_list_y + 20,
589 mwindow->theme->menueffect_list_w,
590 mwindow->theme->menueffect_list_h,
594 add_subwindow(file_title = new BC_Title(mwindow->theme->menueffect_file_x,
595 mwindow->theme->menueffect_file_y,
596 (char*)((menueffects->strategy == FILE_PER_LABEL || menueffects->strategy == FILE_PER_LABEL_FARM) ?
597 _("Select the first file to render to:") :
598 _("Select a file to render to:"))));
600 x = mwindow->theme->menueffect_tools_x;
601 y = mwindow->theme->menueffect_tools_y;
602 format_tools = new FormatTools(mwindow,
605 format_tools->create_objects(x,
615 &menueffects->strategy,
618 loadmode = new LoadMode(mwindow,
622 &menueffects->load_mode,
624 loadmode->create_objects();
626 add_subwindow(new MenuEffectWindowOK(this));
627 add_subwindow(new MenuEffectWindowCancel(this));
633 int MenuEffectWindow::resize_event(int w, int h)
635 mwindow->session->menueffect_w = w;
636 mwindow->session->menueffect_h = h;
637 mwindow->theme->get_menueffect_sizes(plugin_list ? 1 : 0);
641 list_title->reposition_window(mwindow->theme->menueffect_list_x,
642 mwindow->theme->menueffect_list_y);
643 list->reposition_window(mwindow->theme->menueffect_list_x,
644 mwindow->theme->menueffect_list_y + 20,
645 mwindow->theme->menueffect_list_w,
646 mwindow->theme->menueffect_list_h);
649 file_title->reposition_window(mwindow->theme->menueffect_file_x,
650 mwindow->theme->menueffect_file_y);
651 int x = mwindow->theme->menueffect_tools_x;
652 int y = mwindow->theme->menueffect_tools_y;
653 format_tools->reposition_window(x, y);
654 loadmode->reposition_window(x, y);
659 MenuEffectWindowOK::MenuEffectWindowOK(MenuEffectWindow *window)
660 : BC_OKButton(window)
662 this->window = window;
665 int MenuEffectWindowOK::handle_event()
667 if(window->plugin_list)
668 window->result = window->list->get_selection_number(0, 0);
673 int MenuEffectWindowOK::keypress_event()
675 if(get_keypress() == 13)
683 MenuEffectWindowCancel::MenuEffectWindowCancel(MenuEffectWindow *window)
684 : BC_CancelButton(window)
686 this->window = window;
689 int MenuEffectWindowCancel::handle_event()
694 int MenuEffectWindowCancel::keypress_event()
696 if(get_keypress() == ESC)
704 MenuEffectWindowList::MenuEffectWindowList(MenuEffectWindow *window,
709 ArrayList<BC_ListBoxItem*> *plugin_list)
717 this->window = window;
720 int MenuEffectWindowList::handle_event()
722 window->result = get_selection_number(0, 0);
728 MenuEffectPrompt::MenuEffectPrompt(MWindow *mwindow)
729 : BC_Window(PROGRAM_NAME ": Effect Prompt",
730 mwindow->gui->get_abs_cursor_x(1) - 260 / 2,
731 mwindow->gui->get_abs_cursor_y(1) - 300,
742 MenuEffectPrompt::~MenuEffectPrompt()
746 int MenuEffectPrompt::create_objects()
749 add_subwindow(new BC_Title(x, y, _("Set up effect panel and hit \"OK\"")));
751 add_subwindow(new BC_OKButton(this));
753 add_subwindow(new BC_CancelButton(this));