00001 #include "asset.h"
00002 #include "clip.h"
00003 #include "confirmsave.h"
00004 #include "defaults.h"
00005 #include "edl.h"
00006 #include "edlsession.h"
00007 #include "errorbox.h"
00008 #include "file.h"
00009 #include "formatcheck.h"
00010 #include "indexfile.h"
00011 #include "keyframe.h"
00012 #include "keys.h"
00013 #include "labels.h"
00014 #include "language.h"
00015 #include "loadmode.h"
00016 #include "localsession.h"
00017 #include "mainmenu.h"
00018 #include "mainsession.h"
00019 #include "mainundo.h"
00020 #include "mwindow.h"
00021 #include "mwindowgui.h"
00022 #include "menueffects.h"
00023 #include "playbackengine.h"
00024 #include "pluginarray.h"
00025 #include "pluginserver.h"
00026 #include "preferences.h"
00027 #include "render.h"
00028 #include "sighandler.h"
00029 #include "theme.h"
00030 #include "tracks.h"
00031
00032
00033
00034 MenuEffects::MenuEffects(MWindow *mwindow)
00035 : BC_MenuItem(_("Render effect..."))
00036 {
00037 this->mwindow = mwindow;
00038 }
00039
00040 MenuEffects::~MenuEffects()
00041 {
00042 }
00043
00044
00045 int MenuEffects::handle_event()
00046 {
00047 thread->set_title("");
00048 thread->start();
00049 }
00050
00051
00052
00053
00054
00055 MenuEffectPacket::MenuEffectPacket(char *path, int64_t start, int64_t end)
00056 {
00057 this->start = start;
00058 this->end = end;
00059 strcpy(this->path, path);
00060 }
00061
00062 MenuEffectPacket::~MenuEffectPacket()
00063 {
00064 }
00065
00066
00067
00068
00069
00070
00071 MenuEffectThread::MenuEffectThread(MWindow *mwindow)
00072 {
00073 this->mwindow = mwindow;
00074 sprintf(title, "");
00075 }
00076
00077 MenuEffectThread::~MenuEffectThread()
00078 {
00079 }
00080
00081
00082
00083
00084
00085 int MenuEffectThread::set_title(char *title)
00086 {
00087 strcpy(this->title, title);
00088 }
00089
00090
00091
00092 void MenuEffectThread::run()
00093 {
00094
00095 ArrayList<PluginServer*> *plugindb = mwindow->plugindb;
00096 Defaults *defaults = mwindow->defaults;
00097 ArrayList<BC_ListBoxItem*> plugin_list;
00098 ArrayList<PluginServer*> local_plugindb;
00099 char string[1024];
00100 int i;
00101 int result = 0;
00102
00103 Asset default_asset;
00104
00105 ArrayList<Asset*> assets;
00106
00107
00108
00109 if(!get_recordable_tracks(&default_asset))
00110 {
00111 sprintf(string, _("No recordable tracks specified."));
00112 ErrorBox error(PROGRAM_NAME ": Error");
00113 error.create_objects(string);
00114 error.run_window();
00115 return;
00116 }
00117
00118
00119 if(!plugindb->total)
00120 {
00121 sprintf(string, _("No plugins available."));
00122 ErrorBox error(PROGRAM_NAME ": Error");
00123 error.create_objects(string);
00124 error.run_window();
00125 return;
00126 }
00127
00128
00129
00130
00131 get_derived_attributes(&default_asset, defaults);
00132
00133 load_mode = defaults->get("RENDER_EFFECT_LOADMODE", LOAD_PASTE);
00134 strategy = defaults->get("RENDER_EFFECT_STRATEGY", SINGLE_PASS);
00135
00136
00137 int need_plugin;
00138 if(!strlen(title))
00139 need_plugin = 1;
00140 else
00141 need_plugin = 0;
00142
00143
00144 if(need_plugin)
00145 {
00146 mwindow->create_plugindb(default_asset.audio_data,
00147 default_asset.video_data,
00148 -1,
00149 0,
00150 0,
00151 local_plugindb);
00152
00153 for(int i = 0; i < local_plugindb.total; i++)
00154 {
00155 plugin_list.append(new BC_ListBoxItem(_(local_plugindb.values[i]->title)));
00156 }
00157 }
00158
00159
00160 int plugin_number, format_error = 0;
00161
00162 do
00163 {
00164 {
00165 MenuEffectWindow window(mwindow,
00166 this,
00167 need_plugin ? &plugin_list : 0,
00168 &default_asset);
00169 window.create_objects();
00170 result = window.run_window();
00171 plugin_number = window.result;
00172 }
00173
00174 if(!result)
00175 {
00176 FormatCheck format_check(&default_asset);
00177 format_error = format_check.check_format();
00178 }
00179 }while(format_error && !result);
00180
00181
00182 save_derived_attributes(&default_asset, defaults);
00183 defaults->update("RENDER_EFFECT_LOADMODE", load_mode);
00184 defaults->update("RENDER_EFFECT_STRATEGY", strategy);
00185 mwindow->save_defaults();
00186
00187
00188 PluginServer *plugin_server = 0;
00189 PluginServer *plugin = 0;
00190 if(need_plugin)
00191 {
00192 plugin_list.remove_all_objects();
00193 if(plugin_number > -1)
00194 {
00195 plugin_server = local_plugindb.values[plugin_number];
00196 strcpy(title, plugin_server->title);
00197 }
00198 }
00199 else
00200 {
00201 for(int i = 0; i < plugindb->total && !plugin_server; i++)
00202 {
00203 if(!strcmp(plugindb->values[i]->title, title))
00204 {
00205 plugin_server = plugindb->values[i];
00206 plugin_number = i;
00207 }
00208 }
00209 }
00210
00211
00212 if(plugin_server)
00213 {
00214 plugin = new PluginServer(*plugin_server);
00215 fix_menu(title);
00216 }
00217
00218 if(!result && !strlen(default_asset.path))
00219 {
00220 result = 1;
00221 ErrorBox error(PROGRAM_NAME ": Error");
00222 error.create_objects(_("No output file specified."));
00223 error.run_window();
00224 }
00225
00226 if(!result && plugin_number < 0)
00227 {
00228 result = 1;
00229 ErrorBox error(PROGRAM_NAME ": Error");
00230 error.create_objects(_("No effect selected."));
00231 error.run_window();
00232 }
00233
00234
00235 KeyFrame plugin_data;
00236
00237
00238
00239 double total_start, total_end;
00240
00241 total_start = mwindow->edl->local_session->get_selectionstart();
00242
00243
00244 if(mwindow->edl->local_session->get_selectionend() ==
00245 mwindow->edl->local_session->get_selectionstart())
00246 total_end = mwindow->edl->tracks->total_playable_length();
00247 else
00248 total_end = mwindow->edl->local_session->get_selectionend();
00249
00250
00251
00252
00253 total_start = to_units(total_start, 0);
00254 total_end = to_units(total_end, 1);
00255
00256
00257
00258
00259 if(plugin &&
00260 !plugin->realtime &&
00261 total_end == total_start) total_end = total_start + 1;
00262
00263
00264 int64_t total_length = (int64_t)total_end - (int64_t)total_start;
00265
00266 int64_t output_start, output_end;
00267
00268 if(!result && total_length <= 0)
00269 {
00270 result = 1;
00271 ErrorBox error(PROGRAM_NAME ": Error");
00272 error.create_objects(_("No selected range to process."));
00273 error.run_window();
00274 }
00275
00276
00277 if(!result)
00278 {
00279
00280
00281 if(plugin->realtime)
00282 {
00283
00284 MenuEffectPrompt prompt(mwindow);
00285 prompt.create_objects();
00286 char title[BCTEXTLEN];
00287 sprintf(title, PROGRAM_NAME ": %s", plugin->title);
00288
00289
00290 plugin->set_mwindow(mwindow);
00291 plugin->set_keyframe(&plugin_data);
00292 plugin->set_prompt(&prompt);
00293 plugin->open_plugin(0, mwindow->preferences, mwindow->edl, 0, -1);
00294
00295 plugin->get_parameters((int64_t)total_start,
00296 (int64_t)total_end,
00297 1);
00298 plugin->show_gui();
00299
00300
00301 result = prompt.run_window();
00302
00303
00304 plugin->save_data(&plugin_data);
00305 delete plugin;
00306 default_asset.sample_rate = mwindow->edl->session->sample_rate;
00307 default_asset.frame_rate = mwindow->edl->session->frame_rate;
00308 realtime = 1;
00309 }
00310 else
00311
00312 {
00313 plugin->set_mwindow(mwindow);
00314 plugin->open_plugin(0, mwindow->preferences, mwindow->edl, 0, -1);
00315 result = plugin->get_parameters((int64_t)total_start,
00316 (int64_t)total_end,
00317 get_recordable_tracks(&default_asset));
00318
00319
00320
00321 if(!result)
00322 {
00323 default_asset.sample_rate = plugin->get_samplerate();
00324 default_asset.frame_rate = plugin->get_framerate();
00325 }
00326 delete plugin;
00327 realtime = 0;
00328 }
00329
00330
00331 default_asset.width = mwindow->edl->session->output_w;
00332 default_asset.height = mwindow->edl->session->output_h;
00333 }
00334
00335
00336 ArrayList<MenuEffectPacket*> packets;
00337 if(!result)
00338 {
00339 Label *current_label = mwindow->edl->labels->first;
00340 mwindow->stop_brender();
00341
00342 int current_number;
00343 int number_start;
00344 int total_digits;
00345 Render::get_starting_number(default_asset.path,
00346 current_number,
00347 number_start,
00348 total_digits);
00349
00350
00351
00352
00353 for(int64_t fragment_start = (int64_t)total_start, fragment_end;
00354 fragment_start < (int64_t)total_end;
00355 fragment_start = fragment_end)
00356 {
00357
00358 if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
00359 {
00360 while(current_label &&
00361 to_units(current_label->position, 0) <= fragment_start)
00362 current_label = current_label->next;
00363 if(!current_label)
00364 fragment_end = (int64_t)total_end;
00365 else
00366 fragment_end = to_units(current_label->position, 0);
00367 }
00368 else
00369 {
00370 fragment_end = (int64_t)total_end;
00371 }
00372
00373
00374 char path[BCTEXTLEN];
00375 if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
00376 Render::create_filename(path,
00377 default_asset.path,
00378 current_number,
00379 total_digits,
00380 number_start);
00381 else
00382 strcpy(path, default_asset.path);
00383 current_number++;
00384
00385 MenuEffectPacket *packet = new MenuEffectPacket(path,
00386 fragment_start,
00387 fragment_end);
00388 packets.append(packet);
00389 }
00390
00391
00392
00393 ArrayList<char*> paths;
00394 for(int i = 0; i < packets.total; i++)
00395 {
00396 paths.append(packets.values[i]->path);
00397 }
00398 result = ConfirmSave::test_files(mwindow, &paths);
00399 paths.remove_all();
00400 }
00401
00402
00403
00404 for(int current_packet = 0;
00405 current_packet < packets.total && !result;
00406 current_packet++)
00407 {
00408 Asset *asset = new Asset(default_asset);
00409 MenuEffectPacket *packet = packets.values[current_packet];
00410 int64_t fragment_start = packet->start;
00411 int64_t fragment_end = packet->end;
00412 strcpy(asset->path, packet->path);
00413
00414 assets.append(asset);
00415 File *file = new File;
00416
00417
00418
00419 if(!result)
00420 {
00421
00422 file->set_processors(mwindow->preferences->processors);
00423 if(file->open_file(mwindow->preferences,
00424 asset,
00425 0,
00426 1,
00427 mwindow->edl->session->sample_rate,
00428 mwindow->edl->session->frame_rate))
00429 {
00430
00431 sprintf(string, _("Couldn't open %s"), asset->path);
00432 ErrorBox error(PROGRAM_NAME ": Error");
00433 error.create_objects(string);
00434 error.run_window();
00435 result = 1;
00436 }
00437 else
00438 {
00439 mwindow->sighandler->push_file(file);
00440 IndexFile::delete_index(mwindow->preferences, asset);
00441 }
00442 }
00443
00444
00445 if(!result)
00446 {
00447
00448 output_start = 0;
00449
00450 PluginArray *plugin_array;
00451 plugin_array = create_plugin_array();
00452
00453 plugin_array->start_plugins(mwindow,
00454 mwindow->edl,
00455 plugin_server,
00456 &plugin_data,
00457 fragment_start,
00458 fragment_end,
00459 file);
00460 plugin_array->run_plugins();
00461
00462 plugin_array->stop_plugins();
00463 mwindow->sighandler->pull_file(file);
00464 file->close_file();
00465 asset->audio_length = file->asset->audio_length;
00466 asset->video_length = file->asset->video_length;
00467 delete plugin_array;
00468 }
00469
00470 delete file;
00471 }
00472
00473 packets.remove_all_objects();
00474
00475
00476 if(!result && load_mode != LOAD_NOTHING)
00477 {
00478 mwindow->gui->lock_window("MenuEffectThread::run");
00479
00480 if(load_mode == LOAD_PASTE)
00481 mwindow->clear(0);
00482 mwindow->load_assets(&assets,
00483 -1,
00484 load_mode,
00485 0,
00486 0,
00487 mwindow->edl->session->labels_follow_edits,
00488 mwindow->edl->session->plugins_follow_edits);
00489
00490
00491 mwindow->save_backup();
00492 mwindow->undo->update_undo(title, LOAD_ALL);
00493
00494
00495
00496 mwindow->restart_brender();
00497 mwindow->update_plugin_guis();
00498 mwindow->gui->update(1,
00499 2,
00500 1,
00501 1,
00502 1,
00503 1,
00504 0);
00505 mwindow->sync_parameters(CHANGE_ALL);
00506 mwindow->gui->unlock_window();
00507 }
00508
00509 assets.remove_all_objects();
00510 }
00511
00512
00513
00514
00515 MenuEffectItem::MenuEffectItem(MenuEffects *menueffect, char *string)
00516 : BC_MenuItem(string)
00517 {
00518 this->menueffect = menueffect;
00519 }
00520 int MenuEffectItem::handle_event()
00521 {
00522 menueffect->thread->set_title(get_text());
00523 menueffect->thread->start();
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 MenuEffectWindow::MenuEffectWindow(MWindow *mwindow,
00538 MenuEffectThread *menueffects,
00539 ArrayList<BC_ListBoxItem*> *plugin_list,
00540 Asset *asset)
00541 : BC_Window(PROGRAM_NAME ": Render effect",
00542 mwindow->gui->get_abs_cursor_x(1),
00543 mwindow->gui->get_abs_cursor_y(1) - mwindow->session->menueffect_h / 2,
00544 mwindow->session->menueffect_w,
00545 mwindow->session->menueffect_h,
00546 580,
00547 350,
00548 1,
00549 0,
00550 1)
00551 {
00552 this->menueffects = menueffects;
00553 this->plugin_list = plugin_list;
00554 this->asset = asset;
00555 this->mwindow = mwindow;
00556 }
00557
00558 MenuEffectWindow::~MenuEffectWindow()
00559 {
00560 delete format_tools;
00561 }
00562
00563
00564
00565 int MenuEffectWindow::create_objects()
00566 {
00567 int x, y;
00568 result = -1;
00569 mwindow->theme->get_menueffect_sizes(plugin_list ? 1 : 0);
00570
00571
00572 if(plugin_list)
00573 {
00574 add_subwindow(list_title = new BC_Title(mwindow->theme->menueffect_list_x,
00575 mwindow->theme->menueffect_list_y,
00576 _("Select an effect")));
00577 add_subwindow(list = new MenuEffectWindowList(this,
00578 mwindow->theme->menueffect_list_x,
00579 mwindow->theme->menueffect_list_y + list_title->get_h() + 5,
00580 mwindow->theme->menueffect_list_w,
00581 mwindow->theme->menueffect_list_h - list_title->get_h() - 5,
00582 plugin_list));
00583 }
00584
00585 add_subwindow(file_title = new BC_Title(mwindow->theme->menueffect_file_x,
00586 mwindow->theme->menueffect_file_y,
00587 (char*)((menueffects->strategy == FILE_PER_LABEL || menueffects->strategy == FILE_PER_LABEL_FARM) ?
00588 _("Select the first file to render to:") :
00589 _("Select a file to render to:"))));
00590
00591 x = mwindow->theme->menueffect_tools_x;
00592 y = mwindow->theme->menueffect_tools_y;
00593 format_tools = new FormatTools(mwindow,
00594 this,
00595 asset);
00596 format_tools->create_objects(x,
00597 y,
00598 asset->audio_data,
00599 asset->video_data,
00600 0,
00601 0,
00602 0,
00603 1,
00604 0,
00605 0,
00606 &menueffects->strategy,
00607 0);
00608
00609 loadmode = new LoadMode(mwindow,
00610 this,
00611 x,
00612 y,
00613 &menueffects->load_mode,
00614 1);
00615 loadmode->create_objects();
00616
00617 add_subwindow(new MenuEffectWindowOK(this));
00618 add_subwindow(new MenuEffectWindowCancel(this));
00619 show_window();
00620 flush();
00621 return 0;
00622 }
00623
00624 int MenuEffectWindow::resize_event(int w, int h)
00625 {
00626 mwindow->session->menueffect_w = w;
00627 mwindow->session->menueffect_h = h;
00628 mwindow->theme->get_menueffect_sizes(plugin_list ? 1 : 0);
00629
00630 if(plugin_list)
00631 {
00632 list_title->reposition_window(mwindow->theme->menueffect_list_x,
00633 mwindow->theme->menueffect_list_y);
00634 list->reposition_window(mwindow->theme->menueffect_list_x,
00635 mwindow->theme->menueffect_list_y + list_title->get_h() + 5,
00636 mwindow->theme->menueffect_list_w,
00637 mwindow->theme->menueffect_list_h - list_title->get_h() - 5);
00638 }
00639
00640 file_title->reposition_window(mwindow->theme->menueffect_file_x,
00641 mwindow->theme->menueffect_file_y);
00642 int x = mwindow->theme->menueffect_tools_x;
00643 int y = mwindow->theme->menueffect_tools_y;
00644 format_tools->reposition_window(x, y);
00645 loadmode->reposition_window(x, y);
00646 }
00647
00648
00649
00650 MenuEffectWindowOK::MenuEffectWindowOK(MenuEffectWindow *window)
00651 : BC_OKButton(window)
00652 {
00653 this->window = window;
00654 }
00655
00656 int MenuEffectWindowOK::handle_event()
00657 {
00658 if(window->plugin_list)
00659 window->result = window->list->get_selection_number(0, 0);
00660
00661 window->set_done(0);
00662 }
00663
00664 int MenuEffectWindowOK::keypress_event()
00665 {
00666 if(get_keypress() == RETURN)
00667 {
00668 handle_event();
00669 return 1;
00670 }
00671 return 0;
00672 }
00673
00674 MenuEffectWindowCancel::MenuEffectWindowCancel(MenuEffectWindow *window)
00675 : BC_CancelButton(window)
00676 {
00677 this->window = window;
00678 }
00679
00680 int MenuEffectWindowCancel::handle_event()
00681 {
00682 window->set_done(1);
00683 }
00684
00685 int MenuEffectWindowCancel::keypress_event()
00686 {
00687 if(get_keypress() == ESC)
00688 {
00689 handle_event();
00690 return 1;
00691 }
00692 return 0;
00693 }
00694
00695 MenuEffectWindowList::MenuEffectWindowList(MenuEffectWindow *window,
00696 int x,
00697 int y,
00698 int w,
00699 int h,
00700 ArrayList<BC_ListBoxItem*> *plugin_list)
00701 : BC_ListBox(x,
00702 y,
00703 w,
00704 h,
00705 LISTBOX_TEXT,
00706 plugin_list)
00707 {
00708 this->window = window;
00709 }
00710
00711 int MenuEffectWindowList::handle_event()
00712 {
00713 window->result = get_selection_number(0, 0);
00714 window->set_done(0);
00715 }
00716
00717 #define PROMPT_TEXT _("Set up effect panel and hit \"OK\"")
00718
00719 MenuEffectPrompt::MenuEffectPrompt(MWindow *mwindow)
00720 : BC_Window(PROGRAM_NAME ": Effect Prompt",
00721 mwindow->gui->get_abs_cursor_x(1) - 260 / 2,
00722 mwindow->gui->get_abs_cursor_y(1) - 300,
00723 MenuEffectPrompt::calculate_w(mwindow->gui),
00724 MenuEffectPrompt::calculate_h(mwindow->gui),
00725 MenuEffectPrompt::calculate_w(mwindow->gui),
00726 MenuEffectPrompt::calculate_h(mwindow->gui),
00727 0,
00728 0,
00729 1)
00730 {
00731 }
00732
00733 int MenuEffectPrompt::calculate_w(BC_WindowBase *gui)
00734 {
00735 int w = BC_Title::calculate_w(gui, PROMPT_TEXT) + 10;
00736 w = MAX(w, BC_OKButton::calculate_w() + BC_CancelButton::calculate_w() + 30);
00737 return w;
00738 }
00739
00740 int MenuEffectPrompt::calculate_h(BC_WindowBase *gui)
00741 {
00742 int h = BC_Title::calculate_h(gui, PROMPT_TEXT);
00743 h += BC_OKButton::calculate_h() + 30;
00744 return h;
00745 }
00746
00747
00748 int MenuEffectPrompt::create_objects()
00749 {
00750 int x = 10, y = 10;
00751 BC_Title *title;
00752 add_subwindow(title = new BC_Title(x, y, PROMPT_TEXT));
00753 add_subwindow(new BC_OKButton(this));
00754 add_subwindow(new BC_CancelButton(this));
00755 show_window();
00756 raise_window();
00757 flush();
00758 return 0;
00759 }
00760