license header for review
[cinelerra_cv/ct.git] / cinelerra / render.C
blob296a0e3661ca4f408668b634b8e950ea1f583124
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_GC asset = Asset_GC(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 printf("Render::run 12\n");
372         }
373         else
374         if(mode == Render::BATCH)
375         {
376                 for(int i = 0; i < jobs->total && !result; i++)
377                 {
378                         BatchRenderJob *job = jobs->values[i];
379                         if(job->enabled)
380                         {
381                                 if(mwindow)
382                                 {
383                                         mwindow->batch_render->update_active(i);
384                                 }
385                                 else
386                                 {
387                                         printf("Render::run: %s\n", job->edl_path);
388                                 }
391                                 FileXML *file = new FileXML;
392                                 EDL *edl = new EDL;
393                                 edl->create_objects();
394                                 file->read_from_file(job->edl_path);
395                                 if(!plugindb && mwindow)
396                                         plugindb = mwindow->plugindb;
397                                 edl->load_xml(plugindb, file, LOAD_ALL);
399                                 check_asset(edl, *job->asset);
400                                 render(0, job->asset, edl, job->strategy, RANGE_BACKCOMPAT);
402                                 delete edl;
403                                 delete file;
404                                 if(!result)
405                                 {
406                                         if(mwindow)
407                                                 mwindow->batch_render->update_done(i, 1, elapsed_time);
408                                         else
409                                         {
410                                                 char string[BCTEXTLEN];
411                                                 elapsed_time = 
412                                                         (double)progress_timer->get_scaled_difference(1);
413                                                 Units::totext(string,
414                                                         elapsed_time,
415                                                         TIME_HMS2);
416                                                 printf("Render::run: done in %s\n", string);
417                                         }
418                                 }
419                                 else
420                                 {
421                                         if(mwindow)
422                                                 mwindow->batch_render->update_active(-1);
423                                         else
424                                                 printf("Render::run: failed\n");
425                                 }
426                         }
427                 }
429                 if(mwindow)
430                 {
431                         mwindow->batch_render->update_active(-1);
432                         mwindow->batch_render->update_done(-1, 0, 0);
433                 }
434         }
435 printf("Render::run 100\n");
440 int Render::check_asset(EDL *edl, Asset &asset)
442         if(asset.video_data && 
443                 edl->tracks->playable_video_tracks() &&
444                 File::supports_video(asset.format))
445         {
446                 asset.video_data = 1;
447                 asset.layers = 1;
448                 asset.width = edl->session->output_w;
449                 asset.height = edl->session->output_h;
450                 asset.interlace_mode = edl->session->interlace_mode;
451                 asset.tcstart = (int64_t) (edl->session->get_frame_offset() +
452                         edl->local_session->get_selectionstart() *
453                                 edl->session->frame_rate);
454                 asset.tcend = (int64_t) (edl->session->get_frame_offset() +
455                         edl->local_session->get_selectionend() *
456                                 edl->session->frame_rate);
457         }
458         else
459         {
460                 asset.video_data = 0;
461                 asset.layers = 0;
462                 asset.tcstart = 0;
463                 asset.tcend = 0;
464         }
466         if(asset.audio_data && 
467                 edl->tracks->playable_audio_tracks() &&
468                 File::supports_audio(asset.format))
469         {
470                 asset.audio_data = 1;
471                 asset.channels = edl->session->audio_channels;
472                 if(asset.format == FILE_MOV) asset.byte_order = 0;
473                 asset.tcstart = (int64_t) (edl->session->get_frame_offset() +
474                         edl->local_session->get_selectionstart() *
475                                 edl->session->sample_rate);
476                 asset.tcend = (int64_t) (edl->session->get_frame_offset() +
477                         edl->local_session->get_selectionend() *
478                                 edl->session->sample_rate);
479         }
480         else
481         {
482                 asset.audio_data = 0;
483                 asset.channels = 0;
484                 asset.tcstart = 0;
485                 asset.tcend = 0;
486         }
488         if(!asset.audio_data &&
489                 !asset.video_data)
490         {
491                 return 1;
492         }
493         return 0;
496 int Render::fix_strategy(int strategy, int use_renderfarm)
498         if(use_renderfarm)
499         {
500                 if(strategy == FILE_PER_LABEL)
501                         strategy = FILE_PER_LABEL_FARM;
502                 else
503                 if(strategy == SINGLE_PASS)
504                         strategy = SINGLE_PASS_FARM;
505         }
506         else
507         {
508                 if(strategy == FILE_PER_LABEL_FARM)
509                         strategy = FILE_PER_LABEL;
510                 else
511                 if(strategy == SINGLE_PASS_FARM)
512                         strategy = SINGLE_PASS;
513         }
514         return strategy;
517 void Render::start_progress()
519         char filename[BCTEXTLEN];
520         char string[BCTEXTLEN];
521         FileSystem fs;
523         progress_max = packages->get_progress_max();
525         progress_timer->update();
526         last_eta = 0;
527         if(mwindow)
528         {
529 // Generate the progress box
530                 fs.extract_name(filename, default_asset->path);
531                 sprintf(string, _("Rendering %s..."), filename);
533 // Don't bother with the filename since renderfarm defeats the meaning
534                 progress = mwindow->mainprogress->start_progress(_("Rendering..."), 
535                         progress_max);
536                 render_progress = new RenderProgress(mwindow, this);
537                 render_progress->start();
538         }
541 void Render::stop_progress()
543         if(progress)
544         {
545                 char string[BCTEXTLEN], string2[BCTEXTLEN];
546                 delete render_progress;
547                 progress->get_time(string);
548                 elapsed_time = progress->get_time();
549                 progress->stop_progress();
550                 delete progress;
552                 sprintf(string2, _("Rendering took %s"), string);
553                 mwindow->gui->lock_window("");
554                 mwindow->gui->show_message(string2);
555                 mwindow->gui->stop_hourglass();
556                 mwindow->gui->unlock_window();
557         }
558         progress = 0;
563 int Render::render(int test_overwrite, 
564         Asset_GC asset,
565         EDL *edl,
566         int strategy,
567         int range_type)
569         char string[BCTEXTLEN];
570 // Total length in seconds
571         double total_length;
572         int last_audio_buffer;
573         RenderFarmServer *farm_server = 0;
574         FileSystem fs;
575         int total_digits;      // Total number of digits including padding the user specified.
576         int number_start;      // Character in the filename path at which the number begins
577         int current_number;    // The number the being injected into the filename.
578 // Pointer from file
579 // (VFrame*)(VFrame array [])(Channel [])
580         VFrame ***video_output;
581 // Pointer to output buffers
582         VFrame *video_output_ptr[MAX_CHANNELS];
583         double *audio_output_ptr[MAX_CHANNELS];
584         int done = 0;
585         in_progress = 1;
588         this->default_asset = asset;
589         progress = 0;
590         result = 0;
592         if(mwindow)
593         {
594                 if(!preferences)
595                         preferences = new Preferences;
597                 preferences->copy_from(mwindow->preferences);
598         }
601 // Create rendering command
602         command = new TransportCommand;
603         command->command = NORMAL_FWD;
604         command->get_edl()->copy_all(edl);
605         command->change_type = CHANGE_ALL;
606         if (range_type == RANGE_BACKCOMPAT)
607         {
608 // Get highlighted playback range
609                 command->set_playback_range();
610 // Adjust playback range with in/out points
611                 command->playback_range_adjust_inout();
612         } else
613         if (range_type == RANGE_PROJECT)
614         {
615                 command->playback_range_project();
616         } else
617         if (range_type == RANGE_SELECTION)
618         {
619                 command->set_playback_range();
620         } else
621         if (range_type == RANGE_INOUT)
622         {
623                 command->playback_range_inout();
624         }
625         packages = new PackageDispatcher;
628 // Configure preview monitor
629         VideoOutConfig vconfig;
630         PlaybackConfig *playback_config = new PlaybackConfig;
632 // Create caches
633         audio_cache = new CICache(preferences, plugindb);
634         video_cache = new CICache(preferences, plugindb);
636         default_asset->frame_rate = command->get_edl()->session->frame_rate;
637         default_asset->sample_rate = command->get_edl()->session->sample_rate;
639 // Conform asset to EDL.  Find out if any tracks are playable.
640         result = check_asset(command->get_edl(), *default_asset);
642         if(!result)
643         {
644 // Get total range to render
645                 total_start = command->start_position;
646                 total_end = command->end_position;
647                 total_length = total_end - total_start;
649 // Nothing to render
650                 if(EQUIV(total_length, 0))
651                 {
652                         result = 1;
653                 }
654         }
662 // Generate packages
663         if(!result)
664         {
665 // Stop background rendering
666                 if(mwindow) mwindow->stop_brender();
668                 fs.complete_path(default_asset->path);
669                 strategy = Render::fix_strategy(strategy, preferences->use_renderfarm);
671                 result = packages->create_packages(mwindow,
672                         command->get_edl(),
673                         preferences,
674                         strategy, 
675                         default_asset, 
676                         total_start, 
677                         total_end,
678                         test_overwrite);
679         }
690         done = 0;
691         total_rendered = 0;
692         frames_per_second = 0;
694         if(!result)
695         {
696 // Start dispatching external jobs
697                 if(mwindow)
698                 {
699                         mwindow->gui->lock_window("Render::render 1");
700                         mwindow->gui->show_message(_("Starting render farm"));
701                         mwindow->gui->start_hourglass();
702                         mwindow->gui->unlock_window();
703                 }
704                 else
705                 {
706                         printf("Render::render: starting render farm\n");
707                 }
709                 if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM)
710                 {
711                         farm_server = new RenderFarmServer(plugindb, 
712                                 packages,
713                                 preferences, 
714                                 1,
715                                 &result,
716                                 &total_rendered,
717                                 counter_lock,
718                                 default_asset,
719                                 command->get_edl(),
720                                 0);
721                         result = farm_server->start_clients();
723                         if(result)
724                         {
725                                 if(mwindow)
726                                 {
727                                         mwindow->gui->lock_window("Render::render 2");
728                                         mwindow->gui->show_message(_("Failed to start render farm"),
729                                                 mwindow->theme->message_error);
730                                         mwindow->gui->stop_hourglass();
731                                         mwindow->gui->unlock_window();
732                                 }
733                                 else
734                                 {
735                                         printf("Render::render: Failed to start render farm\n");
736                                 }
737                         }
738                 }
739         }
744 // Perform local rendering
747         if(!result)
748         {
749                 start_progress();
750         
754                 MainPackageRenderer package_renderer(this);
755                 result = package_renderer.initialize(mwindow,
756                                 command->get_edl(),   // Copy of master EDL
757                                 preferences, 
758                                 default_asset,
759                                 plugindb);
767                 while(!result)
768                 {
769 // Get unfinished job
770                         RenderPackage *package;
772                         if(strategy == SINGLE_PASS_FARM)
773                         {
774                                 package = packages->get_package(frames_per_second, -1, 1);
775                         }
776                         else
777                         {
778                                 package = packages->get_package(0, -1, 1);
779                         }
781 // Exit point
782                         if(!package) 
783                         {
784                                 done = 1;
785                                 break;
786                         }
790                         Timer timer;
791                         timer.update();
793                         if(package_renderer.render_package(package))
794                                 result = 1;
796 // Result is also set directly by the RenderFarm.
798                         frames_per_second = (double)(package->video_end - package->video_start) / 
799                                 (double)(timer.get_difference() / 1000);
802                 } // file_number
806 printf("Render::run: Session finished.\n");
812                 if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM)
813                 {
814                         farm_server->wait_clients();
815                         result |= packages->packages_are_done();
816                 }
818 printf("Render::render 90\n");
820 // Notify of error
821                 if(result && 
822                         (!progress || !progress->is_cancelled()) &&
823                         !batch_cancelled)
824                 {
825                         if(mwindow)
826                         {
827                                 ErrorBox error_box(PROGRAM_NAME ": Error",
828                                         mwindow->gui->get_abs_cursor_x(1),
829                                         mwindow->gui->get_abs_cursor_y(1));
830                                 error_box.create_objects(_("Error rendering data."));
831                                 error_box.raise_window();
832                                 error_box.run_window();
833                         }
834                         else
835                         {
836                                 printf("Render::render: Error rendering data\n");
837                         }
838                 }
840 // Delete the progress box
841                 stop_progress();
843 //printf("Render::render 100\n");
848         }
851 // Paste all packages into timeline if desired
853         if(!result && 
854                 load_mode != LOAD_NOTHING && 
855                 mwindow &&
856                 mode != Render::BATCH)
857         {
858                 mwindow->gui->lock_window("Render::render 3");
863                 Assets_vector assets;
864                 packages->get_asset_list(assets);
866                 if(load_mode == LOAD_PASTE)
867                         mwindow->clear(0);
868                 mwindow->load_assets(assets, 
869                         -1, 
870                         load_mode,
871                         0,
872                         0,
873                         mwindow->edl->session->labels_follow_edits,
874                         mwindow->edl->session->plugins_follow_edits,
875                         0); // overwrite
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_GC 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_GC 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_GC 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_GC 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;
1215 //      Local Variables:
1216 //      mode: C++
1217 //      c-file-style: "linux"
1218 //      End: