r1014: Enable horizontal scrolling with the mouse wheel by pressing Ctrl.
[cinelerra_cv/ct.git] / cinelerra / render.C
blob543484fd345d80947d01a1cb2ba03ea52ec05e51
1 #include "arender.h"
2 #include "asset.h"
3 #include "auto.h"
4 #include "batchrender.h"
5 #include "bcprogressbox.h"
6 #include "cache.h"
7 #include "clip.h"
8 #include "compresspopup.h"
9 #include "condition.h"
10 #include "confirmsave.h"
11 #include "cwindowgui.h"
12 #include "cwindow.h"
13 #include "bchash.h"
14 #include "edits.h"
15 #include "edl.h"
16 #include "edlsession.h"
17 #include "errorbox.h"
18 #include "file.h"
19 #include "filesystem.h"
20 #include "filexml.h"
21 #include "formatcheck.h"
22 #include "formatpopup.h"
23 #include "formattools.h"
24 #include "labels.h"
25 #include "language.h"
26 #include "loadmode.h"
27 #include "localsession.h"
28 #include "mainprogress.h"
29 #include "mainsession.h"
30 #include "mainundo.h"
31 #include "module.h"
32 #include "mutex.h"
33 #include "mwindowgui.h"
34 #include "mwindow.h"
35 #include "packagedispatcher.h"
36 #include "packagerenderer.h"
37 #include "patchbay.h"
38 #include "playabletracks.h"
39 #include "preferences.h"
40 #include "quicktime.h"
41 #include "renderfarm.h"
42 #include "render.h"
43 #include "statusbar.h"
44 #include "theme.h"
45 #include "timebar.h"
46 #include "tracks.h"
47 #include "transportque.h"
48 #include "vedit.h"
49 #include "vframe.h"
50 #include "videoconfig.h"
51 #include "vrender.h"
52 #include "renderprofiles.h"
54 #include <ctype.h>
55 #include <string.h>
59 RenderItem::RenderItem(MWindow *mwindow)
60  : BC_MenuItem(_("Render..."), "Shift+R", 'R')
62         this->mwindow = mwindow;
63         set_shift(1);
66 int RenderItem::handle_event() 
68         mwindow->render->start_interactive();
69         return 1;
81 RenderProgress::RenderProgress(MWindow *mwindow, Render *render)
82  : Thread()
84         this->mwindow = mwindow;
85         this->render = render;
86         last_value = 0;
87         Thread::set_synchronous(1);
90 RenderProgress::~RenderProgress()
92         Thread::cancel();
93         Thread::join();
97 void RenderProgress::run()
99         Thread::disable_cancel();
100         while(1)
101         {
102                 if(render->total_rendered != last_value)
103                 {
104                         render->progress->update(render->total_rendered);
105                         last_value = render->total_rendered;
106                 }
108                 Thread::enable_cancel();
109                 sleep(1);
110                 Thread::disable_cancel();
111         }
123 MainPackageRenderer::MainPackageRenderer(Render *render)
124  : PackageRenderer()
126         this->render = render;
131 MainPackageRenderer::~MainPackageRenderer()
136 int MainPackageRenderer::get_master()
138         return 1;
141 int MainPackageRenderer::get_result()
143         return render->result;
146 void MainPackageRenderer::set_result(int value)
148         if(value)
149                 render->result = value;
152 void MainPackageRenderer::set_progress(int64_t value)
154         render->counter_lock->lock("MainPackageRenderer::set_progress");
155         render->total_rendered += value;
157 // If non interactive, print progress out
158         if(!render->progress)
159         {
160                 int64_t current_eta = render->progress_timer->get_scaled_difference(1000);
161                 if(current_eta - render->last_eta > 1000)
162                 {
163                         double eta = 0;
166                         if(render->total_rendered)
167                         {
168                                 eta = current_eta /
169                                         1000 *
170                                         render->progress_max /
171                                         render->total_rendered -
172                                         current_eta /
173                                         1000;
174                         }
176                         char string[BCTEXTLEN];
177                         Units::totext(string, 
178                                 eta,
179                                 TIME_HMS2);
181                         printf("\r%d%% ETA: %s      ", (int)(100 * 
182                                 (float)render->total_rendered / 
183                                         render->progress_max),
184                                 string);
185                         fflush(stdout);
186                         render->last_eta = current_eta;
187                 }
188         }
190         render->counter_lock->unlock();
193 int MainPackageRenderer::progress_cancelled()
195         return (render->progress && render->progress->is_cancelled()) || 
196                 render->batch_cancelled;
210 Render::Render(MWindow *mwindow)
211  : Thread(0, 0, 0)
213         this->mwindow = mwindow;
214         if(mwindow) plugindb = mwindow->plugindb;
215         in_progress = 0;
216         progress = 0;
217         preferences = 0;
218         elapsed_time = 0.0;
219         package_lock = new Mutex("Render::package_lock");
220         counter_lock = new Mutex("Render::counter_lock");
221         completion = new Condition(0, "Render::completion");
222         progress_timer = new Timer;
223         range_type = RANGE_BACKCOMPAT;
226 Render::~Render()
228         delete package_lock;
229         delete counter_lock;
230         delete completion;
231         if(preferences) delete preferences;
232         delete progress_timer;
235 void Render::start_interactive()
237         if(!Thread::running())
238         {
239                 mode = Render::INTERACTIVE;
240                 this->jobs = 0;
241                 batch_cancelled = 0;
242                 completion->reset();
243                 Thread::start();
244         }
245         else
246         {
247                 // raise the window if rendering hasn't started yet
248                 if (render_window && ! in_progress) {
249                         render_window->raise_window();
250                 }
251                 else {
252                         ErrorBox error_box(PROGRAM_NAME ": Error",
253                                            mwindow->gui->get_abs_cursor_x(1),
254                                            mwindow->gui->get_abs_cursor_y(1));
255                         error_box.create_objects("Already rendering");
256                         error_box.raise_window();
257                         error_box.run_window();
258                 }
259         }
262 void Render::start_batches(ArrayList<BatchRenderJob*> *jobs)
264         batch_cancelled = 0;
265         if(!Thread::running())
266         {
267                 mode = Render::BATCH;
268                 this->jobs = jobs;
269                 completion->reset();
270                 Thread::start();
271         }
272         else
273         {
274                 ErrorBox error_box(PROGRAM_NAME ": Error",
275                         mwindow->gui->get_abs_cursor_x(1),
276                         mwindow->gui->get_abs_cursor_y(1));
277                 error_box.create_objects("Already rendering");
278                 error_box.raise_window();
279                 error_box.run_window();
280         }
283 void Render::start_batches(ArrayList<BatchRenderJob*> *jobs,
284         BC_Hash *boot_defaults,
285         Preferences *preferences,
286         ArrayList<PluginServer*> *plugindb)
288         mode = Render::BATCH;
289         batch_cancelled = 0;
290         this->jobs = jobs;
291         this->preferences = preferences;
292         this->plugindb = plugindb;
294         completion->reset();
295         run();
296         this->preferences = 0;
299 void Render::stop_operation()
301         if(Thread::running())
302         {
303                 batch_cancelled = 1;
304 // Wait for completion
305                 completion->lock("Render::stop_operation");
306                 completion->reset();
307         }
311 void Render::run()
313         int format_error;
316         result = 0;
318         if(mode == Render::INTERACTIVE)
319         {
320 // Fix the asset for rendering
321 printf("Render::run 1\n");
322                 Asset *asset = new Asset;
323                 load_defaults(asset);
324 printf("Render::run 2\n");
325                 check_asset(mwindow->edl, *asset);
326 printf("Render::run 3\n");
328 // Get format from user
329                 if(!result)
330                 {
331 printf("Render::run 4\n");
332                         do
333                         {
334                                 format_error = 0;
335                                 result = 0;
337                                 {
338 printf("Render::run 5\n");
339                                         RenderWindow window(mwindow, this, asset);
340 printf("Render::run 6\n");
341                                         window.create_objects();
342 printf("Render::run 7\n");
343                                         result = window.run_window();
344 printf("Render::run 8\n");
345                                         if (! result) {
346                                                 // add to recentlist only on OK
347                                                 window.format_tools->path_recent->add_item(FILE_FORMAT_PREFIX(asset->format), asset->path);
348                                         }
349                                 }
351                                 if(!result)
352                                 {
353 printf("Render::run 8.1\n");
354 // Check the asset format for errors.
355                                         FormatCheck format_check(asset);
356 printf("Render::run 8.2\n");
357                                         format_error = format_check.check_format();
358 printf("Render::run 8.3\n");
359                                 }
360                         }while(format_error && !result);
361                 }
362 printf("Render::run 9\n");
364                 save_defaults(asset);
365                 mwindow->save_defaults();
366 printf("Render::run 10\n");
368                 if(!result) render(1, asset, mwindow->edl, strategy, range_type);
369 printf("Render::run 11\n");
371                 Garbage::delete_object(asset);
372 printf("Render::run 12\n");
373         }
374         else
375         if(mode == Render::BATCH)
376         {
377                 for(int i = 0; i < jobs->total && !result; i++)
378                 {
379                         BatchRenderJob *job = jobs->values[i];
380                         if(job->enabled)
381                         {
382                                 if(mwindow)
383                                 {
384                                         mwindow->batch_render->update_active(i);
385                                 }
386                                 else
387                                 {
388                                         printf("Render::run: %s\n", job->edl_path);
389                                 }
392                                 FileXML *file = new FileXML;
393                                 EDL *edl = new EDL;
394                                 edl->create_objects();
395                                 file->read_from_file(job->edl_path);
396                                 if(!plugindb && mwindow)
397                                         plugindb = mwindow->plugindb;
398                                 edl->load_xml(plugindb, file, LOAD_ALL);
400                                 check_asset(edl, *job->asset);
401                                 render(0, job->asset, edl, job->strategy, RANGE_BACKCOMPAT);
403                                 delete edl;
404                                 delete file;
405                                 if(!result)
406                                 {
407                                         if(mwindow)
408                                                 mwindow->batch_render->update_done(i, 1, elapsed_time);
409                                         else
410                                         {
411                                                 char string[BCTEXTLEN];
412                                                 elapsed_time = 
413                                                         (double)progress_timer->get_scaled_difference(1);
414                                                 Units::totext(string,
415                                                         elapsed_time,
416                                                         TIME_HMS2);
417                                                 printf("Render::run: done in %s\n", string);
418                                         }
419                                 }
420                                 else
421                                 {
422                                         if(mwindow)
423                                                 mwindow->batch_render->update_active(-1);
424                                         else
425                                                 printf("Render::run: failed\n");
426                                 }
427                         }
428                 }
430                 if(mwindow)
431                 {
432                         mwindow->batch_render->update_active(-1);
433                         mwindow->batch_render->update_done(-1, 0, 0);
434                 }
435         }
436 printf("Render::run 100\n");
441 int Render::check_asset(EDL *edl, Asset &asset)
443         if(asset.video_data && 
444                 edl->tracks->playable_video_tracks() &&
445                 File::supports_video(asset.format))
446         {
447                 asset.video_data = 1;
448                 asset.layers = 1;
449                 asset.width = edl->session->output_w;
450                 asset.height = edl->session->output_h;
451                 asset.interlace_mode = edl->session->interlace_mode;
452                 asset.tcstart = (int64_t) (edl->session->get_frame_offset() +
453                         edl->local_session->get_selectionstart() *
454                                 edl->session->frame_rate);
455                 asset.tcend = (int64_t) (edl->session->get_frame_offset() +
456                         edl->local_session->get_selectionend() *
457                                 edl->session->frame_rate);
458         }
459         else
460         {
461                 asset.video_data = 0;
462                 asset.layers = 0;
463                 asset.tcstart = 0;
464                 asset.tcend = 0;
465         }
467         if(asset.audio_data && 
468                 edl->tracks->playable_audio_tracks() &&
469                 File::supports_audio(asset.format))
470         {
471                 asset.audio_data = 1;
472                 asset.channels = edl->session->audio_channels;
473                 if(asset.format == FILE_MOV) asset.byte_order = 0;
474                 asset.tcstart = (int64_t) (edl->session->get_frame_offset() +
475                         edl->local_session->get_selectionstart() *
476                                 edl->session->sample_rate);
477                 asset.tcend = (int64_t) (edl->session->get_frame_offset() +
478                         edl->local_session->get_selectionend() *
479                                 edl->session->sample_rate);
480         }
481         else
482         {
483                 asset.audio_data = 0;
484                 asset.channels = 0;
485                 asset.tcstart = 0;
486                 asset.tcend = 0;
487         }
489         if(!asset.audio_data &&
490                 !asset.video_data)
491         {
492                 return 1;
493         }
494         return 0;
497 int Render::fix_strategy(int strategy, int use_renderfarm)
499         if(use_renderfarm)
500         {
501                 if(strategy == FILE_PER_LABEL)
502                         strategy = FILE_PER_LABEL_FARM;
503                 else
504                 if(strategy == SINGLE_PASS)
505                         strategy = SINGLE_PASS_FARM;
506         }
507         else
508         {
509                 if(strategy == FILE_PER_LABEL_FARM)
510                         strategy = FILE_PER_LABEL;
511                 else
512                 if(strategy == SINGLE_PASS_FARM)
513                         strategy = SINGLE_PASS;
514         }
515         return strategy;
518 void Render::start_progress()
520         char filename[BCTEXTLEN];
521         char string[BCTEXTLEN];
522         FileSystem fs;
524         progress_max = packages->get_progress_max();
526         progress_timer->update();
527         last_eta = 0;
528         if(mwindow)
529         {
530 // Generate the progress box
531                 fs.extract_name(filename, default_asset->path);
532                 sprintf(string, _("Rendering %s..."), filename);
534 // Don't bother with the filename since renderfarm defeats the meaning
535                 progress = mwindow->mainprogress->start_progress(_("Rendering..."), 
536                         progress_max);
537                 render_progress = new RenderProgress(mwindow, this);
538                 render_progress->start();
539         }
542 void Render::stop_progress()
544         if(progress)
545         {
546                 char string[BCTEXTLEN], string2[BCTEXTLEN];
547                 delete render_progress;
548                 progress->get_time(string);
549                 elapsed_time = progress->get_time();
550                 progress->stop_progress();
551                 delete progress;
553                 sprintf(string2, _("Rendering took %s"), string);
554                 mwindow->gui->lock_window("");
555                 mwindow->gui->show_message(string2);
556                 mwindow->gui->stop_hourglass();
557                 mwindow->gui->unlock_window();
558         }
559         progress = 0;
564 int Render::render(int test_overwrite, 
565         Asset *asset,
566         EDL *edl,
567         int strategy,
568         int range_type)
570         char string[BCTEXTLEN];
571 // Total length in seconds
572         double total_length;
573         int last_audio_buffer;
574         RenderFarmServer *farm_server = 0;
575         FileSystem fs;
576         int total_digits;      // Total number of digits including padding the user specified.
577         int number_start;      // Character in the filename path at which the number begins
578         int current_number;    // The number the being injected into the filename.
579 // Pointer from file
580 // (VFrame*)(VFrame array [])(Channel [])
581         VFrame ***video_output;
582 // Pointer to output buffers
583         VFrame *video_output_ptr[MAX_CHANNELS];
584         double *audio_output_ptr[MAX_CHANNELS];
585         int done = 0;
586         in_progress = 1;
589         this->default_asset = asset;
590         progress = 0;
591         result = 0;
593         if(mwindow)
594         {
595                 if(!preferences)
596                         preferences = new Preferences;
598                 preferences->copy_from(mwindow->preferences);
599         }
602 // Create rendering command
603         command = new TransportCommand;
604         command->command = NORMAL_FWD;
605         command->get_edl()->copy_all(edl);
606         command->change_type = CHANGE_ALL;
607         if (range_type == RANGE_BACKCOMPAT)
608         {
609 // Get highlighted playback range
610                 command->set_playback_range();
611 // Adjust playback range with in/out points
612                 command->playback_range_adjust_inout();
613         } else
614         if (range_type == RANGE_PROJECT)
615         {
616                 command->playback_range_project();
617         } else
618         if (range_type == RANGE_SELECTION)
619         {
620                 command->set_playback_range();
621         } else
622         if (range_type == RANGE_INOUT)
623         {
624                 command->playback_range_inout();
625         }
626         packages = new PackageDispatcher;
629 // Configure preview monitor
630         VideoOutConfig vconfig;
631         PlaybackConfig *playback_config = new PlaybackConfig;
633 // Create caches
634         audio_cache = new CICache(preferences, plugindb);
635         video_cache = new CICache(preferences, plugindb);
637         default_asset->frame_rate = command->get_edl()->session->frame_rate;
638         default_asset->sample_rate = command->get_edl()->session->sample_rate;
640 // Conform asset to EDL.  Find out if any tracks are playable.
641         result = check_asset(command->get_edl(), *default_asset);
643         if(!result)
644         {
645 // Get total range to render
646                 total_start = command->start_position;
647                 total_end = command->end_position;
648                 total_length = total_end - total_start;
650 // Nothing to render
651                 if(EQUIV(total_length, 0))
652                 {
653                         result = 1;
654                 }
655         }
663 // Generate packages
664         if(!result)
665         {
666 // Stop background rendering
667                 if(mwindow) mwindow->stop_brender();
669                 fs.complete_path(default_asset->path);
670                 strategy = Render::fix_strategy(strategy, preferences->use_renderfarm);
672                 result = packages->create_packages(mwindow,
673                         command->get_edl(),
674                         preferences,
675                         strategy, 
676                         default_asset, 
677                         total_start, 
678                         total_end,
679                         test_overwrite);
680         }
691         done = 0;
692         total_rendered = 0;
693         frames_per_second = 0;
695         if(!result)
696         {
697 // Start dispatching external jobs
698                 if(mwindow)
699                 {
700                         mwindow->gui->lock_window("Render::render 1");
701                         mwindow->gui->show_message(_("Starting render farm"));
702                         mwindow->gui->start_hourglass();
703                         mwindow->gui->unlock_window();
704                 }
705                 else
706                 {
707                         printf("Render::render: starting render farm\n");
708                 }
710                 if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM)
711                 {
712                         farm_server = new RenderFarmServer(plugindb, 
713                                 packages,
714                                 preferences, 
715                                 1,
716                                 &result,
717                                 &total_rendered,
718                                 counter_lock,
719                                 default_asset,
720                                 command->get_edl(),
721                                 0);
722                         result = farm_server->start_clients();
724                         if(result)
725                         {
726                                 if(mwindow)
727                                 {
728                                         mwindow->gui->lock_window("Render::render 2");
729                                         mwindow->gui->show_message(_("Failed to start render farm"),
730                                                 mwindow->theme->message_error);
731                                         mwindow->gui->stop_hourglass();
732                                         mwindow->gui->unlock_window();
733                                 }
734                                 else
735                                 {
736                                         printf("Render::render: Failed to start render farm\n");
737                                 }
738                         }
739                 }
740         }
745 // Perform local rendering
748         if(!result)
749         {
750                 start_progress();
751         
755                 MainPackageRenderer package_renderer(this);
756                 result = package_renderer.initialize(mwindow,
757                                 command->get_edl(),   // Copy of master EDL
758                                 preferences, 
759                                 default_asset,
760                                 plugindb);
768                 while(!result)
769                 {
770 // Get unfinished job
771                         RenderPackage *package;
773                         if(strategy == SINGLE_PASS_FARM)
774                         {
775                                 package = packages->get_package(frames_per_second, -1, 1);
776                         }
777                         else
778                         {
779                                 package = packages->get_package(0, -1, 1);
780                         }
782 // Exit point
783                         if(!package) 
784                         {
785                                 done = 1;
786                                 break;
787                         }
791                         Timer timer;
792                         timer.update();
794                         if(package_renderer.render_package(package))
795                                 result = 1;
797 // Result is also set directly by the RenderFarm.
799                         frames_per_second = (double)(package->video_end - package->video_start) / 
800                                 (double)(timer.get_difference() / 1000);
803                 } // file_number
807 printf("Render::run: Session finished.\n");
813                 if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM)
814                 {
815                         farm_server->wait_clients();
816                         result |= packages->packages_are_done();
817                 }
819 printf("Render::render 90\n");
821 // Notify of error
822                 if(result && 
823                         (!progress || !progress->is_cancelled()) &&
824                         !batch_cancelled)
825                 {
826                         if(mwindow)
827                         {
828                                 ErrorBox error_box(PROGRAM_NAME ": Error",
829                                         mwindow->gui->get_abs_cursor_x(1),
830                                         mwindow->gui->get_abs_cursor_y(1));
831                                 error_box.create_objects(_("Error rendering data."));
832                                 error_box.raise_window();
833                                 error_box.run_window();
834                         }
835                         else
836                         {
837                                 printf("Render::render: Error rendering data\n");
838                         }
839                 }
841 // Delete the progress box
842                 stop_progress();
844 //printf("Render::render 100\n");
849         }
852 // Paste all packages into timeline if desired
854         if(!result && 
855                 load_mode != LOAD_NOTHING && 
856                 mwindow &&
857                 mode != Render::BATCH)
858         {
859                 mwindow->gui->lock_window("Render::render 3");
864                 ArrayList<Asset*> *assets = packages->get_asset_list();
865                 if(load_mode == LOAD_PASTE)
866                         mwindow->clear(0);
867                 mwindow->load_assets(assets, 
868                         -1, 
869                         load_mode,
870                         0,
871                         0,
872                         mwindow->edl->session->labels_follow_edits,
873                         mwindow->edl->session->plugins_follow_edits,
874                         0); // overwrite
875                 delete assets;
878                 mwindow->save_backup();
879                 mwindow->undo->update_undo(_("render"), LOAD_ALL);
880                 mwindow->update_plugin_guis();
881                 mwindow->gui->update(1, 
882                         2,
883                         1,
884                         1,
885                         1,
886                         1,
887                         0);
888                 mwindow->sync_parameters(CHANGE_ALL);
889                 mwindow->gui->unlock_window();
890         }
893 // Disable hourglass
894         if(mwindow)
895         {
896                 mwindow->gui->lock_window("Render::render 3");
897                 mwindow->gui->stop_hourglass();
898                 mwindow->gui->unlock_window();
899         }
901 //printf("Render::render 110\n");
902 // Need to restart because brender always stops before render.
903         if(mwindow)
904                 mwindow->restart_brender();
905         if(farm_server) delete farm_server;
906         delete command;
907         delete playback_config;
908         delete audio_cache;
909         delete video_cache;
910 // Must delete packages after server
911         delete packages;
912         in_progress = 0;
913         completion->unlock();
914 //printf("Render::render 120\n");
916         return result;
920 void Render::create_filename(char *path, 
921         char *default_path, 
922         int current_number,
923         int total_digits,
924         int number_start)
926         int i, j, k;
927         int len = strlen(default_path);
928         char printf_string[BCTEXTLEN];
929         int found_number = 0;
931         for(i = 0, j = 0; i < number_start; i++, j++)
932         {
933                 printf_string[j] = default_path[i];
934         }
936 // Found the number
937         sprintf(&printf_string[j], "%%0%dd", total_digits);
938         j = strlen(printf_string);
939         i += total_digits;
941 // Copy remainder of string
942         for( ; i < len; i++, j++)
943         {
944                 printf_string[j] = default_path[i];
945         }
946         printf_string[j] = 0;
947 // Print the printf argument to the path
948         sprintf(path, printf_string, current_number);
951 void Render::get_starting_number(char *path, 
952         int &current_number,
953         int &number_start, 
954         int &total_digits,
955         int min_digits)
957         int i, j;
958         int len = strlen(path);
959         char number_text[BCTEXTLEN];
960         char *ptr = 0;
961         char *ptr2 = 0;
963         total_digits = 0;
964         number_start = 0;
966 // Search for last /
967         ptr2 = strrchr(path, '/');
969 // Search for first 0 after last /.
970         if(ptr2)
971                 ptr = strchr(ptr2, '0');
973         if(ptr && isdigit(*ptr))
974         {
975                 number_start = ptr - path;
977 // Store the first number
978                 char *ptr2 = number_text;
979                 while(isdigit(*ptr))
980                         *ptr2++ = *ptr++;
981                 *ptr2++ = 0;
982                 current_number = atol(number_text);
983                 total_digits = strlen(number_text);
984         }
987 // No number found or number not long enough
988         if(total_digits < min_digits)
989         {
990                 current_number = 1;
991                 number_start = len;
992                 total_digits = min_digits;
993         }
1002 int Render::load_defaults(Asset *asset)
1004         strategy = mwindow->defaults->get("RENDER_STRATEGY", SINGLE_PASS);
1005         load_mode = mwindow->defaults->get("RENDER_LOADMODE", LOAD_NEW_TRACKS);
1006         range_type = mwindow->defaults->get("RENDER_RANGE_TYPE", RANGE_PROJECT);
1009         asset->load_defaults(mwindow->defaults, 
1010                 "RENDER_", 
1011                 1,
1012                 1,
1013                 1,
1014                 1,
1015                 1);
1018         return 0;
1021 int Render::load_profile(int profile_slot, Asset *asset)
1023         char string_name[100];
1024         sprintf(string_name, "RENDER_%i_STRATEGY", profile_slot);
1025         strategy = mwindow->defaults->get(string_name, SINGLE_PASS);
1026 // Load mode is not part of the profile
1027 //      printf(string_name, "RENDER_%i_LOADMODE", profile_slot);
1028 //      load_mode = mwindow->defaults->get(string_name, LOAD_NEW_TRACKS);
1029         sprintf(string_name, "RENDER_%i_RANGE_TYPE", profile_slot);
1030         range_type = mwindow->defaults->get(string_name, RANGE_PROJECT);
1033         sprintf(string_name, "RENDER_%i_", profile_slot);
1034         asset->load_defaults(mwindow->defaults, 
1035                 string_name, 
1036                 1,
1037                 1,
1038                 1,
1039                 1,
1040                 1);
1043         return 0;
1048 int Render::save_defaults(Asset *asset)
1050         mwindow->defaults->update("RENDER_STRATEGY", strategy);
1051         mwindow->defaults->update("RENDER_LOADMODE", load_mode);
1052         mwindow->defaults->update("RENDER_RANGE_TYPE", range_type);
1057         asset->save_defaults(mwindow->defaults, 
1058                 "RENDER_",
1059                 1,
1060                 1,
1061                 1,
1062                 1,
1063                 1);
1065         return 0;
1071 #define WIDTH 410
1072 #define HEIGHT 455
1075 RenderWindow::RenderWindow(MWindow *mwindow, Render *render, Asset *asset)
1076  : BC_Window(PROGRAM_NAME ": Render", 
1077         mwindow->gui->get_root_w(0, 1) / 2 - WIDTH / 2,
1078         mwindow->gui->get_root_h(1) / 2 - HEIGHT / 2,
1079         WIDTH, 
1080         HEIGHT,
1081         (int)BC_INFINITY,
1082         (int)BC_INFINITY,
1083         0,
1084         0,
1085         1)
1087         this->mwindow = mwindow;
1088         this->render = render;
1089         this->asset = asset;
1092 RenderWindow::~RenderWindow()
1094         delete format_tools;
1095         delete loadmode;
1099 int RenderWindow::load_profile(int profile_slot)
1101         render->load_profile(profile_slot, asset);
1102         update_range_type(render->range_type);
1103         format_tools->update(asset, &render->strategy);
1108 int RenderWindow::create_objects()
1110         int x = 5, y = 5;
1111         add_subwindow(new BC_Title(x, 
1112                 y, 
1113                 (char*)((render->strategy == FILE_PER_LABEL || 
1114                                 render->strategy == FILE_PER_LABEL_FARM) ? 
1115                         _("Select the first file to render to:") : 
1116                         _("Select a file to render to:"))));
1117         y += 25;
1119         format_tools = new FormatTools(mwindow,
1120                                         this, 
1121                                         asset);
1122         format_tools->create_objects(x, 
1123                 y, 
1124                 1, 
1125                 1, 
1126                 1, 
1127                 1, 
1128                 0,
1129                 1,
1130                 0,
1131                 0,
1132                 &render->strategy,
1133                 0);
1134         add_subwindow(new BC_Title(x, 
1135                 y, 
1136                         _("Render range:")));
1138         x += 110;
1139         add_subwindow(rangeproject = new RenderRangeProject(this, 
1140                 render->range_type == RANGE_PROJECT, 
1141                 x, 
1142                 y));
1143         y += 20;
1144         add_subwindow(rangeselection = new RenderRangeSelection(this, 
1145                 render->range_type == RANGE_SELECTION, 
1146                 x, 
1147                 y));
1148         y += 20;
1149         add_subwindow(rangeinout = new RenderRangeInOut(this, 
1150                 render->range_type == RANGE_INOUT, 
1151                 x, 
1152                 y));
1153         y += 30;
1154         x = 5;
1156         renderprofile = new RenderProfile(mwindow, this, x, y, 1);
1157         renderprofile->create_objects();
1158         y += 70;
1159         loadmode = new LoadMode(mwindow, this, x, y, &render->load_mode, 1);
1160         loadmode->create_objects();
1164         add_subwindow(new BC_OKButton(this));
1165         add_subwindow(new BC_CancelButton(this));
1166         show_window();
1167         return 0;
1170 void RenderWindow::update_range_type(int range_type)
1172         render->range_type = range_type;
1173         rangeproject->update(range_type == RANGE_PROJECT);
1174         rangeselection->update(range_type == RANGE_SELECTION);
1175         rangeinout->update(range_type == RANGE_INOUT);
1179 RenderRangeProject::RenderRangeProject(RenderWindow *rwindow, int value, int x, int y)
1180  : BC_Radial(x, y, value, _("Project"))
1182         this->rwindow = rwindow;
1184 int RenderRangeProject::handle_event()
1186         rwindow->update_range_type(RANGE_PROJECT);
1187         return 1;
1190 RenderRangeSelection::RenderRangeSelection(RenderWindow *rwindow, int value, int x, int y)
1191  : BC_Radial(x, y, value, _("Selection"))
1193         this->rwindow = rwindow;
1195 int RenderRangeSelection::handle_event()
1197         rwindow->update_range_type(RANGE_SELECTION);
1198         return 1;
1202 RenderRangeInOut::RenderRangeInOut(RenderWindow *rwindow, int value, int x, int y)
1203  : BC_Radial(x, y, value, _("In/Out Points"))
1205         this->rwindow = rwindow;
1207 int RenderRangeInOut::handle_event()
1209         rwindow->update_range_type(RANGE_INOUT);
1210         return 1;