00001 #include "arender.h"
00002 #include "asset.h"
00003 #include "auto.h"
00004 #include "batchrender.h"
00005 #include "bcprogressbox.h"
00006 #include "cache.h"
00007 #include "clip.h"
00008 #include "compresspopup.h"
00009 #include "condition.h"
00010 #include "confirmsave.h"
00011 #include "cwindowgui.h"
00012 #include "cwindow.h"
00013 #include "bchash.h"
00014 #include "edits.h"
00015 #include "edl.h"
00016 #include "edlsession.h"
00017 #include "errorbox.h"
00018 #include "file.h"
00019 #include "filesystem.h"
00020 #include "filexml.h"
00021 #include "formatcheck.h"
00022 #include "formatpopup.h"
00023 #include "formattools.h"
00024 #include "labels.h"
00025 #include "language.h"
00026 #include "loadmode.h"
00027 #include "localsession.h"
00028 #include "mainprogress.h"
00029 #include "mainsession.h"
00030 #include "mainundo.h"
00031 #include "module.h"
00032 #include "mutex.h"
00033 #include "mwindowgui.h"
00034 #include "mwindow.h"
00035 #include "packagedispatcher.h"
00036 #include "packagerenderer.h"
00037 #include "patchbay.h"
00038 #include "playabletracks.h"
00039 #include "preferences.h"
00040 #include "quicktime.h"
00041 #include "renderfarm.h"
00042 #include "render.h"
00043 #include "statusbar.h"
00044 #include "theme.h"
00045 #include "timebar.h"
00046 #include "tracks.h"
00047 #include "transportque.h"
00048 #include "vedit.h"
00049 #include "vframe.h"
00050 #include "videoconfig.h"
00051 #include "vrender.h"
00052 #include "renderprofiles.h"
00053
00054 #include <ctype.h>
00055 #include <string.h>
00056
00057
00058
00059 RenderItem::RenderItem(MWindow *mwindow)
00060 : BC_MenuItem(_("Render..."), "Shift+R", 'R')
00061 {
00062 this->mwindow = mwindow;
00063 set_shift(1);
00064 }
00065
00066 int RenderItem::handle_event()
00067 {
00068 mwindow->render->start_interactive();
00069 return 1;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 RenderProgress::RenderProgress(MWindow *mwindow, Render *render)
00082 : Thread()
00083 {
00084 this->mwindow = mwindow;
00085 this->render = render;
00086 last_value = 0;
00087 Thread::set_synchronous(1);
00088 }
00089
00090 RenderProgress::~RenderProgress()
00091 {
00092 Thread::cancel();
00093 Thread::join();
00094 }
00095
00096
00097 void RenderProgress::run()
00098 {
00099 Thread::disable_cancel();
00100 while(1)
00101 {
00102 if(render->total_rendered != last_value)
00103 {
00104 render->progress->update(render->total_rendered);
00105 last_value = render->total_rendered;
00106 }
00107
00108 Thread::enable_cancel();
00109 sleep(1);
00110 Thread::disable_cancel();
00111 }
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 MainPackageRenderer::MainPackageRenderer(Render *render)
00124 : PackageRenderer()
00125 {
00126 this->render = render;
00127 }
00128
00129
00130
00131 MainPackageRenderer::~MainPackageRenderer()
00132 {
00133 }
00134
00135
00136 int MainPackageRenderer::get_master()
00137 {
00138 return 1;
00139 }
00140
00141 int MainPackageRenderer::get_result()
00142 {
00143 return render->result;
00144 }
00145
00146 void MainPackageRenderer::set_result(int value)
00147 {
00148 if(value)
00149 render->result = value;
00150 }
00151
00152 void MainPackageRenderer::set_progress(int64_t value)
00153 {
00154 render->counter_lock->lock("MainPackageRenderer::set_progress");
00155 render->total_rendered += value;
00156
00157
00158 if(!render->progress)
00159 {
00160 int64_t current_eta = render->progress_timer->get_scaled_difference(1000);
00161 if(current_eta - render->last_eta > 1000)
00162 {
00163 double eta = 0;
00164
00165
00166 if(render->total_rendered)
00167 {
00168 eta = current_eta /
00169 1000 *
00170 render->progress_max /
00171 render->total_rendered -
00172 current_eta /
00173 1000;
00174 }
00175
00176 char string[BCTEXTLEN];
00177 Units::totext(string,
00178 eta,
00179 TIME_HMS2);
00180
00181 printf("\r%d%% ETA: %s ", (int)(100 *
00182 (float)render->total_rendered /
00183 render->progress_max),
00184 string);
00185 fflush(stdout);
00186 render->last_eta = current_eta;
00187 }
00188 }
00189
00190 render->counter_lock->unlock();
00191 }
00192
00193 int MainPackageRenderer::progress_cancelled()
00194 {
00195 return (render->progress && render->progress->is_cancelled()) ||
00196 render->batch_cancelled;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 Render::Render(MWindow *mwindow)
00211 : Thread(0, 0, 0)
00212 {
00213 this->mwindow = mwindow;
00214 if(mwindow) plugindb = mwindow->plugindb;
00215 in_progress = 0;
00216 progress = 0;
00217 preferences = 0;
00218 elapsed_time = 0.0;
00219 package_lock = new Mutex("Render::package_lock");
00220 counter_lock = new Mutex("Render::counter_lock");
00221 completion = new Condition(0, "Render::completion");
00222 progress_timer = new Timer;
00223 range_type = RANGE_BACKCOMPAT;
00224 }
00225
00226 Render::~Render()
00227 {
00228 delete package_lock;
00229 delete counter_lock;
00230 delete completion;
00231 if(preferences) delete preferences;
00232 delete progress_timer;
00233 }
00234
00235 void Render::start_interactive()
00236 {
00237 if(!Thread::running())
00238 {
00239 mode = Render::INTERACTIVE;
00240 this->jobs = 0;
00241 batch_cancelled = 0;
00242 completion->reset();
00243 Thread::start();
00244 }
00245 else
00246 {
00247
00248 if (render_window && ! in_progress) {
00249 render_window->raise_window();
00250 }
00251 else {
00252 ErrorBox error_box(PROGRAM_NAME ": Error",
00253 mwindow->gui->get_abs_cursor_x(1),
00254 mwindow->gui->get_abs_cursor_y(1));
00255 error_box.create_objects("Already rendering");
00256 error_box.raise_window();
00257 error_box.run_window();
00258 }
00259 }
00260 }
00261
00262 void Render::start_batches(ArrayList<BatchRenderJob*> *jobs)
00263 {
00264 batch_cancelled = 0;
00265 if(!Thread::running())
00266 {
00267 mode = Render::BATCH;
00268 this->jobs = jobs;
00269 completion->reset();
00270 Thread::start();
00271 }
00272 else
00273 {
00274 ErrorBox error_box(PROGRAM_NAME ": Error",
00275 mwindow->gui->get_abs_cursor_x(1),
00276 mwindow->gui->get_abs_cursor_y(1));
00277 error_box.create_objects("Already rendering");
00278 error_box.raise_window();
00279 error_box.run_window();
00280 }
00281 }
00282
00283 void Render::start_batches(ArrayList<BatchRenderJob*> *jobs,
00284 BC_Hash *boot_defaults,
00285 Preferences *preferences,
00286 ArrayList<PluginServer*> *plugindb)
00287 {
00288 mode = Render::BATCH;
00289 batch_cancelled = 0;
00290 this->jobs = jobs;
00291 this->preferences = preferences;
00292 this->plugindb = plugindb;
00293
00294 completion->reset();
00295 run();
00296 this->preferences = 0;
00297 }
00298
00299 void Render::stop_operation()
00300 {
00301 if(Thread::running())
00302 {
00303 batch_cancelled = 1;
00304
00305 completion->lock("Render::stop_operation");
00306 completion->reset();
00307 }
00308 }
00309
00310
00311 void Render::run()
00312 {
00313 int format_error;
00314
00315
00316 result = 0;
00317
00318 if(mode == Render::INTERACTIVE)
00319 {
00320
00321 printf("Render::run 1\n");
00322 Asset *asset = new Asset;
00323 load_defaults(asset);
00324 printf("Render::run 2\n");
00325 check_asset(mwindow->edl, *asset);
00326 printf("Render::run 3\n");
00327
00328
00329 if(!result)
00330 {
00331 printf("Render::run 4\n");
00332 do
00333 {
00334 format_error = 0;
00335 result = 0;
00336
00337 {
00338 printf("Render::run 5\n");
00339 RenderWindow window(mwindow, this, asset);
00340 printf("Render::run 6\n");
00341 window.create_objects();
00342 printf("Render::run 7\n");
00343 result = window.run_window();
00344 printf("Render::run 8\n");
00345 if (! result) {
00346
00347 window.format_tools->path_recent->add_item(FILE_FORMAT_PREFIX(asset->format), asset->path);
00348 }
00349 }
00350
00351 if(!result)
00352 {
00353 printf("Render::run 8.1\n");
00354
00355 FormatCheck format_check(asset);
00356 printf("Render::run 8.2\n");
00357 format_error = format_check.check_format();
00358 printf("Render::run 8.3\n");
00359 }
00360 }while(format_error && !result);
00361 }
00362 printf("Render::run 9\n");
00363
00364 save_defaults(asset);
00365 mwindow->save_defaults();
00366 printf("Render::run 10\n");
00367
00368 if(!result) render(1, asset, mwindow->edl, strategy, range_type);
00369 printf("Render::run 11\n");
00370
00371 Garbage::delete_object(asset);
00372 printf("Render::run 12\n");
00373 }
00374 else
00375 if(mode == Render::BATCH)
00376 {
00377 for(int i = 0; i < jobs->total && !result; i++)
00378 {
00379 BatchRenderJob *job = jobs->values[i];
00380 if(job->enabled)
00381 {
00382 if(mwindow)
00383 {
00384 mwindow->batch_render->update_active(i);
00385 }
00386 else
00387 {
00388 printf("Render::run: %s\n", job->edl_path);
00389 }
00390
00391
00392 FileXML *file = new FileXML;
00393 EDL *edl = new EDL;
00394 edl->create_objects();
00395 file->read_from_file(job->edl_path);
00396 if(!plugindb && mwindow)
00397 plugindb = mwindow->plugindb;
00398 edl->load_xml(plugindb, file, LOAD_ALL);
00399
00400 check_asset(edl, *job->asset);
00401 render(0, job->asset, edl, job->strategy, RANGE_BACKCOMPAT);
00402
00403 delete edl;
00404 delete file;
00405 if(!result)
00406 {
00407 if(mwindow)
00408 mwindow->batch_render->update_done(i, 1, elapsed_time);
00409 else
00410 {
00411 char string[BCTEXTLEN];
00412 elapsed_time =
00413 (double)progress_timer->get_scaled_difference(1);
00414 Units::totext(string,
00415 elapsed_time,
00416 TIME_HMS2);
00417 printf("Render::run: done in %s\n", string);
00418 }
00419 }
00420 else
00421 {
00422 if(mwindow)
00423 mwindow->batch_render->update_active(-1);
00424 else
00425 printf("Render::run: failed\n");
00426 }
00427 }
00428 }
00429
00430 if(mwindow)
00431 {
00432 mwindow->batch_render->update_active(-1);
00433 mwindow->batch_render->update_done(-1, 0, 0);
00434 }
00435 }
00436 printf("Render::run 100\n");
00437 }
00438
00439
00440
00441 int Render::check_asset(EDL *edl, Asset &asset)
00442 {
00443 if(asset.video_data &&
00444 edl->tracks->playable_video_tracks() &&
00445 File::supports_video(asset.format))
00446 {
00447 asset.video_data = 1;
00448 asset.layers = 1;
00449 asset.width = edl->session->output_w;
00450 asset.height = edl->session->output_h;
00451 asset.interlace_mode = edl->session->interlace_mode;
00452 asset.tcstart = (int64_t) (edl->session->get_frame_offset() +
00453 edl->local_session->get_selectionstart() *
00454 edl->session->frame_rate);
00455 asset.tcend = (int64_t) (edl->session->get_frame_offset() +
00456 edl->local_session->get_selectionend() *
00457 edl->session->frame_rate);
00458 }
00459 else
00460 {
00461 asset.video_data = 0;
00462 asset.layers = 0;
00463 asset.tcstart = 0;
00464 asset.tcend = 0;
00465 }
00466
00467 if(asset.audio_data &&
00468 edl->tracks->playable_audio_tracks() &&
00469 File::supports_audio(asset.format))
00470 {
00471 asset.audio_data = 1;
00472 asset.channels = edl->session->audio_channels;
00473 if(asset.format == FILE_MOV) asset.byte_order = 0;
00474 asset.tcstart = (int64_t) (edl->session->get_frame_offset() +
00475 edl->local_session->get_selectionstart() *
00476 edl->session->sample_rate);
00477 asset.tcend = (int64_t) (edl->session->get_frame_offset() +
00478 edl->local_session->get_selectionend() *
00479 edl->session->sample_rate);
00480 }
00481 else
00482 {
00483 asset.audio_data = 0;
00484 asset.channels = 0;
00485 asset.tcstart = 0;
00486 asset.tcend = 0;
00487 }
00488
00489 if(!asset.audio_data &&
00490 !asset.video_data)
00491 {
00492 return 1;
00493 }
00494 return 0;
00495 }
00496
00497 int Render::fix_strategy(int strategy, int use_renderfarm)
00498 {
00499 if(use_renderfarm)
00500 {
00501 if(strategy == FILE_PER_LABEL)
00502 strategy = FILE_PER_LABEL_FARM;
00503 else
00504 if(strategy == SINGLE_PASS)
00505 strategy = SINGLE_PASS_FARM;
00506 }
00507 else
00508 {
00509 if(strategy == FILE_PER_LABEL_FARM)
00510 strategy = FILE_PER_LABEL;
00511 else
00512 if(strategy == SINGLE_PASS_FARM)
00513 strategy = SINGLE_PASS;
00514 }
00515 return strategy;
00516 }
00517
00518 void Render::start_progress()
00519 {
00520 char filename[BCTEXTLEN];
00521 char string[BCTEXTLEN];
00522 FileSystem fs;
00523
00524 progress_max = packages->get_progress_max();
00525
00526 progress_timer->update();
00527 last_eta = 0;
00528 if(mwindow)
00529 {
00530
00531 fs.extract_name(filename, default_asset->path);
00532 sprintf(string, _("Rendering %s..."), filename);
00533
00534
00535 progress = mwindow->mainprogress->start_progress(_("Rendering..."),
00536 progress_max);
00537 render_progress = new RenderProgress(mwindow, this);
00538 render_progress->start();
00539 }
00540 }
00541
00542 void Render::stop_progress()
00543 {
00544 if(progress)
00545 {
00546 char string[BCTEXTLEN], string2[BCTEXTLEN];
00547 delete render_progress;
00548 progress->get_time(string);
00549 elapsed_time = progress->get_time();
00550 progress->stop_progress();
00551 delete progress;
00552
00553 sprintf(string2, _("Rendering took %s"), string);
00554 mwindow->gui->lock_window("");
00555 mwindow->gui->show_message(string2);
00556 mwindow->gui->stop_hourglass();
00557 mwindow->gui->unlock_window();
00558 }
00559 progress = 0;
00560 }
00561
00562
00563
00564 int Render::render(int test_overwrite,
00565 Asset *asset,
00566 EDL *edl,
00567 int strategy,
00568 int range_type)
00569 {
00570 char string[BCTEXTLEN];
00571
00572 double total_length;
00573 int last_audio_buffer;
00574 RenderFarmServer *farm_server = 0;
00575 FileSystem fs;
00576 int total_digits;
00577 int number_start;
00578 int current_number;
00579
00580
00581 VFrame ***video_output;
00582
00583 VFrame *video_output_ptr[MAX_CHANNELS];
00584 double *audio_output_ptr[MAX_CHANNELS];
00585 int done = 0;
00586 in_progress = 1;
00587
00588
00589 this->default_asset = asset;
00590 progress = 0;
00591 result = 0;
00592
00593 if(mwindow)
00594 {
00595 if(!preferences)
00596 preferences = new Preferences;
00597
00598 preferences->copy_from(mwindow->preferences);
00599 }
00600
00601
00602
00603 command = new TransportCommand;
00604 command->command = NORMAL_FWD;
00605 command->get_edl()->copy_all(edl);
00606 command->change_type = CHANGE_ALL;
00607 if (range_type == RANGE_BACKCOMPAT)
00608 {
00609
00610 command->set_playback_range();
00611
00612 command->playback_range_adjust_inout();
00613 } else
00614 if (range_type == RANGE_PROJECT)
00615 {
00616 command->playback_range_project();
00617 } else
00618 if (range_type == RANGE_SELECTION)
00619 {
00620 command->set_playback_range();
00621 } else
00622 if (range_type == RANGE_INOUT)
00623 {
00624 command->playback_range_inout();
00625 }
00626 packages = new PackageDispatcher;
00627
00628
00629
00630 VideoOutConfig vconfig;
00631 PlaybackConfig *playback_config = new PlaybackConfig;
00632
00633
00634 audio_cache = new CICache(preferences, plugindb);
00635 video_cache = new CICache(preferences, plugindb);
00636
00637 default_asset->frame_rate = command->get_edl()->session->frame_rate;
00638 default_asset->sample_rate = command->get_edl()->session->sample_rate;
00639
00640
00641 result = check_asset(command->get_edl(), *default_asset);
00642
00643 if(!result)
00644 {
00645
00646 total_start = command->start_position;
00647 total_end = command->end_position;
00648 total_length = total_end - total_start;
00649
00650
00651 if(EQUIV(total_length, 0))
00652 {
00653 result = 1;
00654 }
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664 if(!result)
00665 {
00666
00667 if(mwindow) mwindow->stop_brender();
00668
00669 fs.complete_path(default_asset->path);
00670 strategy = Render::fix_strategy(strategy, preferences->use_renderfarm);
00671
00672 result = packages->create_packages(mwindow,
00673 command->get_edl(),
00674 preferences,
00675 strategy,
00676 default_asset,
00677 total_start,
00678 total_end,
00679 test_overwrite);
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 done = 0;
00692 total_rendered = 0;
00693 frames_per_second = 0;
00694
00695 if(!result)
00696 {
00697
00698 if(mwindow)
00699 {
00700 mwindow->gui->lock_window("Render::render 1");
00701 mwindow->gui->show_message(_("Starting render farm"));
00702 mwindow->gui->start_hourglass();
00703 mwindow->gui->unlock_window();
00704 }
00705 else
00706 {
00707 printf("Render::render: starting render farm\n");
00708 }
00709
00710 if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM)
00711 {
00712 farm_server = new RenderFarmServer(plugindb,
00713 packages,
00714 preferences,
00715 1,
00716 &result,
00717 &total_rendered,
00718 counter_lock,
00719 default_asset,
00720 command->get_edl(),
00721 0);
00722 result = farm_server->start_clients();
00723
00724 if(result)
00725 {
00726 if(mwindow)
00727 {
00728 mwindow->gui->lock_window("Render::render 2");
00729 mwindow->gui->show_message(_("Failed to start render farm"),
00730 mwindow->theme->message_error);
00731 mwindow->gui->stop_hourglass();
00732 mwindow->gui->unlock_window();
00733 }
00734 else
00735 {
00736 printf("Render::render: Failed to start render farm\n");
00737 }
00738 }
00739 }
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 if(!result)
00749 {
00750 start_progress();
00751
00752
00753
00754
00755 MainPackageRenderer package_renderer(this);
00756 result = package_renderer.initialize(mwindow,
00757 command->get_edl(),
00758 preferences,
00759 default_asset,
00760 plugindb);
00761
00762
00763
00764
00765
00766
00767
00768 while(!result)
00769 {
00770
00771 RenderPackage *package;
00772
00773 if(strategy == SINGLE_PASS_FARM)
00774 {
00775 package = packages->get_package(frames_per_second, -1, 1);
00776 }
00777 else
00778 {
00779 package = packages->get_package(0, -1, 1);
00780 }
00781
00782
00783 if(!package)
00784 {
00785 done = 1;
00786 break;
00787 }
00788
00789
00790
00791 Timer timer;
00792 timer.update();
00793
00794 if(package_renderer.render_package(package))
00795 result = 1;
00796
00797
00798
00799 frames_per_second = (double)(package->video_end - package->video_start) /
00800 (double)(timer.get_difference() / 1000);
00801
00802
00803 }
00804
00805
00806
00807 printf("Render::run: Session finished.\n");
00808
00809
00810
00811
00812
00813 if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM)
00814 {
00815 farm_server->wait_clients();
00816 result |= packages->packages_are_done();
00817 }
00818
00819 printf("Render::render 90\n");
00820
00821
00822 if(result &&
00823 (!progress || !progress->is_cancelled()) &&
00824 !batch_cancelled)
00825 {
00826 if(mwindow)
00827 {
00828 ErrorBox error_box(PROGRAM_NAME ": Error",
00829 mwindow->gui->get_abs_cursor_x(1),
00830 mwindow->gui->get_abs_cursor_y(1));
00831 error_box.create_objects(_("Error rendering data."));
00832 error_box.raise_window();
00833 error_box.run_window();
00834 }
00835 else
00836 {
00837 printf("Render::render: Error rendering data\n");
00838 }
00839 }
00840
00841
00842 stop_progress();
00843
00844
00845
00846
00847
00848
00849 }
00850
00851
00852
00853
00854 if(!result &&
00855 load_mode != LOAD_NOTHING &&
00856 mwindow &&
00857 mode != Render::BATCH)
00858 {
00859 mwindow->gui->lock_window("Render::render 3");
00860
00861
00862
00863
00864 ArrayList<Asset*> *assets = packages->get_asset_list();
00865 if(load_mode == LOAD_PASTE)
00866 mwindow->clear(0);
00867 mwindow->load_assets(assets,
00868 -1,
00869 load_mode,
00870 0,
00871 0,
00872 mwindow->edl->session->labels_follow_edits,
00873 mwindow->edl->session->plugins_follow_edits,
00874 0);
00875 delete assets;
00876
00877
00878 mwindow->save_backup();
00879 mwindow->undo->update_undo(_("render"), LOAD_ALL);
00880 mwindow->update_plugin_guis();
00881 mwindow->gui->update(1,
00882 2,
00883 1,
00884 1,
00885 1,
00886 1,
00887 0);
00888 mwindow->sync_parameters(CHANGE_ALL);
00889 mwindow->gui->unlock_window();
00890 }
00891
00892
00893
00894 if(mwindow)
00895 {
00896 mwindow->gui->lock_window("Render::render 3");
00897 mwindow->gui->stop_hourglass();
00898 mwindow->gui->unlock_window();
00899 }
00900
00901
00902
00903 if(mwindow)
00904 mwindow->restart_brender();
00905 if(farm_server) delete farm_server;
00906 delete command;
00907 delete playback_config;
00908 delete audio_cache;
00909 delete video_cache;
00910
00911 delete packages;
00912 in_progress = 0;
00913 completion->unlock();
00914
00915
00916 return result;
00917 }
00918
00919
00920 void Render::create_filename(char *path,
00921 char *default_path,
00922 int current_number,
00923 int total_digits,
00924 int number_start)
00925 {
00926 int i, j, k;
00927 int len = strlen(default_path);
00928 char printf_string[BCTEXTLEN];
00929 int found_number = 0;
00930
00931 for(i = 0, j = 0; i < number_start; i++, j++)
00932 {
00933 printf_string[j] = default_path[i];
00934 }
00935
00936
00937 sprintf(&printf_string[j], "%%0%dd", total_digits);
00938 j = strlen(printf_string);
00939 i += total_digits;
00940
00941
00942 for( ; i < len; i++, j++)
00943 {
00944 printf_string[j] = default_path[i];
00945 }
00946 printf_string[j] = 0;
00947
00948 sprintf(path, printf_string, current_number);
00949 }
00950
00951 void Render::get_starting_number(char *path,
00952 int ¤t_number,
00953 int &number_start,
00954 int &total_digits,
00955 int min_digits)
00956 {
00957 int i, j;
00958 int len = strlen(path);
00959 char number_text[BCTEXTLEN];
00960 char *ptr = 0;
00961 char *ptr2 = 0;
00962
00963 total_digits = 0;
00964 number_start = 0;
00965
00966
00967 ptr2 = strrchr(path, '/');
00968
00969
00970 if(ptr2)
00971 ptr = strchr(ptr2, '0');
00972
00973 if(ptr && isdigit(*ptr))
00974 {
00975 number_start = ptr - path;
00976
00977
00978 char *ptr2 = number_text;
00979 while(isdigit(*ptr))
00980 *ptr2++ = *ptr++;
00981 *ptr2++ = 0;
00982 current_number = atol(number_text);
00983 total_digits = strlen(number_text);
00984 }
00985
00986
00987
00988 if(total_digits < min_digits)
00989 {
00990 current_number = 1;
00991 number_start = len;
00992 total_digits = min_digits;
00993 }
00994 }
00995
00996
00997
00998
00999
01000
01001
01002 int Render::load_defaults(Asset *asset)
01003 {
01004 strategy = mwindow->defaults->get("RENDER_STRATEGY", SINGLE_PASS);
01005 load_mode = mwindow->defaults->get("RENDER_LOADMODE", LOAD_NEW_TRACKS);
01006 range_type = mwindow->defaults->get("RENDER_RANGE_TYPE", RANGE_PROJECT);
01007
01008
01009 asset->load_defaults(mwindow->defaults,
01010 "RENDER_",
01011 1,
01012 1,
01013 1,
01014 1,
01015 1);
01016
01017
01018 return 0;
01019 }
01020
01021 int Render::load_profile(int profile_slot, Asset *asset)
01022 {
01023 char string_name[100];
01024 sprintf(string_name, "RENDER_%i_STRATEGY", profile_slot);
01025 strategy = mwindow->defaults->get(string_name, SINGLE_PASS);
01026
01027
01028
01029 sprintf(string_name, "RENDER_%i_RANGE_TYPE", profile_slot);
01030 range_type = mwindow->defaults->get(string_name, RANGE_PROJECT);
01031
01032
01033 sprintf(string_name, "RENDER_%i_", profile_slot);
01034 asset->load_defaults(mwindow->defaults,
01035 string_name,
01036 1,
01037 1,
01038 1,
01039 1,
01040 1);
01041
01042
01043 return 0;
01044 }
01045
01046
01047
01048 int Render::save_defaults(Asset *asset)
01049 {
01050 mwindow->defaults->update("RENDER_STRATEGY", strategy);
01051 mwindow->defaults->update("RENDER_LOADMODE", load_mode);
01052 mwindow->defaults->update("RENDER_RANGE_TYPE", range_type);
01053
01054
01055
01056
01057 asset->save_defaults(mwindow->defaults,
01058 "RENDER_",
01059 1,
01060 1,
01061 1,
01062 1,
01063 1);
01064
01065 return 0;
01066 }
01067
01068
01069
01070
01071 #define WIDTH 410
01072 #define HEIGHT 455
01073
01074
01075 RenderWindow::RenderWindow(MWindow *mwindow, Render *render, Asset *asset)
01076 : BC_Window(PROGRAM_NAME ": Render",
01077 mwindow->gui->get_root_w(0, 1) / 2 - WIDTH / 2,
01078 mwindow->gui->get_root_h(1) / 2 - HEIGHT / 2,
01079 WIDTH,
01080 HEIGHT,
01081 (int)BC_INFINITY,
01082 (int)BC_INFINITY,
01083 0,
01084 0,
01085 1)
01086 {
01087 this->mwindow = mwindow;
01088 this->render = render;
01089 this->asset = asset;
01090 }
01091
01092 RenderWindow::~RenderWindow()
01093 {
01094 delete format_tools;
01095 delete loadmode;
01096 }
01097
01098
01099 int RenderWindow::load_profile(int profile_slot)
01100 {
01101 render->load_profile(profile_slot, asset);
01102 update_range_type(render->range_type);
01103 format_tools->update(asset, &render->strategy);
01104 }
01105
01106
01107
01108 int RenderWindow::create_objects()
01109 {
01110 int x = 5, y = 5;
01111 add_subwindow(new BC_Title(x,
01112 y,
01113 (char*)((render->strategy == FILE_PER_LABEL ||
01114 render->strategy == FILE_PER_LABEL_FARM) ?
01115 _("Select the first file to render to:") :
01116 _("Select a file to render to:"))));
01117 y += 25;
01118
01119 format_tools = new FormatTools(mwindow,
01120 this,
01121 asset);
01122 format_tools->create_objects(x,
01123 y,
01124 1,
01125 1,
01126 1,
01127 1,
01128 0,
01129 1,
01130 0,
01131 0,
01132 &render->strategy,
01133 0);
01134 add_subwindow(new BC_Title(x,
01135 y,
01136 _("Render range:")));
01137
01138 x += 110;
01139 add_subwindow(rangeproject = new RenderRangeProject(this,
01140 render->range_type == RANGE_PROJECT,
01141 x,
01142 y));
01143 y += 20;
01144 add_subwindow(rangeselection = new RenderRangeSelection(this,
01145 render->range_type == RANGE_SELECTION,
01146 x,
01147 y));
01148 y += 20;
01149 add_subwindow(rangeinout = new RenderRangeInOut(this,
01150 render->range_type == RANGE_INOUT,
01151 x,
01152 y));
01153 y += 30;
01154 x = 5;
01155
01156 renderprofile = new RenderProfile(mwindow, this, x, y, 1);
01157 renderprofile->create_objects();
01158 y += 70;
01159 loadmode = new LoadMode(mwindow, this, x, y, &render->load_mode, 1);
01160 loadmode->create_objects();
01161
01162
01163
01164 add_subwindow(new BC_OKButton(this));
01165 add_subwindow(new BC_CancelButton(this));
01166 show_window();
01167 return 0;
01168 }
01169
01170 void RenderWindow::update_range_type(int range_type)
01171 {
01172 render->range_type = range_type;
01173 rangeproject->update(range_type == RANGE_PROJECT);
01174 rangeselection->update(range_type == RANGE_SELECTION);
01175 rangeinout->update(range_type == RANGE_INOUT);
01176 }
01177
01178
01179 RenderRangeProject::RenderRangeProject(RenderWindow *rwindow, int value, int x, int y)
01180 : BC_Radial(x, y, value, _("Project"))
01181 {
01182 this->rwindow = rwindow;
01183 }
01184 int RenderRangeProject::handle_event()
01185 {
01186 rwindow->update_range_type(RANGE_PROJECT);
01187 return 1;
01188 }
01189
01190 RenderRangeSelection::RenderRangeSelection(RenderWindow *rwindow, int value, int x, int y)
01191 : BC_Radial(x, y, value, _("Selection"))
01192 {
01193 this->rwindow = rwindow;
01194 }
01195 int RenderRangeSelection::handle_event()
01196 {
01197 rwindow->update_range_type(RANGE_SELECTION);
01198 return 1;
01199 }
01200
01201
01202 RenderRangeInOut::RenderRangeInOut(RenderWindow *rwindow, int value, int x, int y)
01203 : BC_Radial(x, y, value, _("In/Out Points"))
01204 {
01205 this->rwindow = rwindow;
01206 }
01207 int RenderRangeInOut::handle_event()
01208 {
01209 rwindow->update_range_type(RANGE_INOUT);
01210 return 1;
01211 }
01212
01213