X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Frender.C;h=e7b3e12d54b3dafc3ca942a31ab9b19ef8853a14;hp=03709b103a0bcbac8e30d4fcfba4a052368d45f8;hb=a19a685a46ddc630010788707d9e5b9d2342af46;hpb=0b78779e9e75131eee81d2e4689b98df0e91c092 diff --git a/cinelerra-5.1/cinelerra/render.C b/cinelerra-5.1/cinelerra/render.C index 03709b10..e7b3e12d 100644 --- a/cinelerra-5.1/cinelerra/render.C +++ b/cinelerra-5.1/cinelerra/render.C @@ -187,40 +187,12 @@ void MainPackageRenderer::set_progress(int64_t value) // If non interactive, print progress out if(!render->progress) - { - int64_t current_eta = render->progress_timer->get_scaled_difference(1000); - if(current_eta - render->last_eta > 1000) - { - double eta = 0; - - - if(render->total_rendered) - { - eta = current_eta / - 1000 * - render->progress_max / - render->total_rendered - - current_eta / - 1000; - } - - char string[BCTEXTLEN]; - Units::totext(string, - eta, - TIME_HMS2); - - printf("\r%d%% %s: %s ", - (int)(100 * (float)render->total_rendered / render->progress_max), - _("ETA"), string); - fflush(stdout); - render->last_eta = current_eta; - } - } + render->show_progress(); render->counter_lock->unlock(); -// This locks the preferences - if(mwindow) mwindow->preferences->copy_rates_from(preferences); + if( mwindow ) + mwindow->preferences->copy_rates_from(preferences); } int MainPackageRenderer::progress_cancelled() @@ -236,17 +208,18 @@ Render::Render(MWindow *mwindow) this->mwindow = mwindow; in_progress = 0; progress = 0; - preferences = 0; elapsed_time = 0.0; package_lock = new Mutex("Render::package_lock"); counter_lock = new Mutex("Render::counter_lock"); completion = new Condition(0, "Render::completion"); progress_timer = new Timer; range_type = RANGE_BACKCOMPAT; + preferences = new Preferences(); thread = new RenderThread(mwindow, this); render_window = 0; asset = 0; result = 0; + beep = 0; } Render::~Render() @@ -255,9 +228,7 @@ Render::~Render() delete package_lock; delete counter_lock; delete completion; -// May be owned by someone else. This is owned by mwindow, so we don't care -// about deletion. -// delete preferences; + delete preferences; delete progress_timer; if( asset ) asset->Garbage::remove_user(); delete thread; @@ -270,9 +241,9 @@ void Render::start_interactive() BC_DialogThread::start(); } else if( in_progress ) { - ErrorBox error_box(_(PROGRAM_NAME ": Error"), - mwindow->gui->get_abs_cursor_x(1), - mwindow->gui->get_abs_cursor_y(1)); + int cx, cy; + mwindow->gui->get_abs_cursor(cx, cy, 1); + ErrorBox error_box(_(PROGRAM_NAME ": Error"), cx, cy); error_box.create_objects(_("Already rendering")); error_box.raise_window(); error_box.run_window(); @@ -294,9 +265,9 @@ void Render::start_batches(ArrayList *jobs) start_render(); } else if( in_progress ) { - ErrorBox error_box(_(PROGRAM_NAME ": Error"), - mwindow->gui->get_abs_cursor_x(1), - mwindow->gui->get_abs_cursor_y(1)); + int cx, cy; + mwindow->gui->get_abs_cursor(cx, cy, 1); + ErrorBox error_box(_(PROGRAM_NAME ": Error"), cx, cy); error_box.create_objects("Already rendering"); error_box.raise_window(); error_box.run_window(); @@ -308,19 +279,15 @@ void Render::start_batches(ArrayList *jobs) } void Render::start_batches(ArrayList *jobs, - BC_Hash *boot_defaults, - Preferences *preferences) + BC_Hash *boot_defaults, Preferences *batch_prefs) { mode = Render::BATCH; batch_cancelled = 0; + preferences->copy_from(batch_prefs); this->jobs = jobs; - this->preferences = preferences; completion->reset(); -PRINT_TRACE thread->run(); -PRINT_TRACE - this->preferences = 0; } @@ -328,22 +295,17 @@ BC_Window* Render::new_gui() { this->jobs = 0; batch_cancelled = 0; - format_error = 0; result = 0; - completion->reset(); if(mode == Render::INTERACTIVE) { // Fix the asset for rendering if(!asset) asset = new Asset; load_defaults(asset); check_asset(mwindow->edl, *asset); - + int px = mwindow->gui->get_pop_cursor_x(1); + int py = mwindow->gui->get_pop_cursor_y(1); // Get format from user - render_window = new RenderWindow(mwindow, - this, - asset, - mwindow->gui->get_abs_cursor_x(1), - mwindow->gui->get_abs_cursor_y(1)); + render_window = new RenderWindow(mwindow, this, asset, px, py); render_window->create_objects(); } @@ -353,22 +315,66 @@ BC_Window* Render::new_gui() void Render::handle_done_event(int result) { if(!result) { + mwindow->edl->session->render_beep = beep; // add to recentlist only on OK - render_window->format_tools->path_recent-> + render_window->render_format->path_recent-> add_item(File::formattostr(asset->format), asset->path); + setenv("CIN_RENDER", asset->path, 1); } render_window = 0; } void Render::handle_close_event(int result) { - int format_error = 0; const int debug = 0; + double render_range = get_render_range(); + const char *err_msg = 0; + + if( !result && !render_range ) { + err_msg = _("zero render range"); + result = 1; + } + if( !result && asset->video_data ) { + double frame_rate = mwindow->edl->session->frame_rate; + if( frame_rate > 0 && render_range+1e-3 < 1./frame_rate ) { + err_msg = _("Video data and range less than 1 frame"); + result = 1; + } + } + if( !result && asset->audio_data ) { + double sample_rate = mwindow->edl->session->sample_rate; + if( sample_rate > 0 && render_range+1e-6 < 1./sample_rate ) { + err_msg = _("Audio data and range less than 1 sample"); + result = 1; + } + } + if( !result && File::is_image_render(asset->format) ) { + if( asset->video_data ) { + double frames = render_range * mwindow->edl->session->frame_rate; + if( !EQUIV(frames, 1.) ) { + err_msg = _("Image format and not 1 frame"); + result = 1; + } + } + else { + err_msg = _("Image format and no video data"); + result = 1; + } + } + if( err_msg ) { + int cx, cy; + mwindow->gui->get_abs_cursor(cx, cy, 1); + ErrorBox error_box(_(PROGRAM_NAME ": Error"),cx, cy); + error_box.create_objects(err_msg); + error_box.raise_window(); + error_box.run_window(); + } if(!result) { // Check the asset format for errors. FormatCheck format_check(asset); - format_error = format_check.check_format(); + if( format_check.check_format() ) + result = 1; } //PRINT_TRACE @@ -378,8 +384,7 @@ void Render::handle_close_event(int result) mwindow->save_defaults(); //PRINT_TRACE - if(!format_error && !result) - { + if( !result ) { if(debug) printf("Render::handle_close_event %d\n", __LINE__); if(!result) start_render(); if(debug) printf("Render::handle_close_event %d\n", __LINE__); @@ -400,53 +405,35 @@ void Render::stop_operation() } } - - int Render::check_asset(EDL *edl, Asset &asset) { if(asset.video_data && edl->tracks->playable_video_tracks() && - File::supports_video(asset.format)) + File::renders_video(&asset)) { asset.video_data = 1; asset.layers = 1; asset.width = edl->session->output_w; asset.height = edl->session->output_h; asset.interlace_mode = edl->session->interlace_mode; - asset.tcstart = (int64_t) (edl->session->get_frame_offset() + - edl->local_session->get_selectionstart() * - edl->session->frame_rate); - asset.tcend = (int64_t) (edl->session->get_frame_offset() + - edl->local_session->get_selectionend() * - edl->session->frame_rate); } else { asset.video_data = 0; asset.layers = 0; - asset.tcstart = 0; - asset.tcend = 0; } if(asset.audio_data && edl->tracks->playable_audio_tracks() && - File::supports_audio(asset.format)) + File::renders_audio(&asset)) { asset.audio_data = 1; asset.channels = edl->session->audio_channels; - asset.tcstart = (int64_t) (edl->session->get_frame_offset() + - edl->local_session->get_selectionstart() * - edl->session->sample_rate); - asset.tcend = (int64_t) (edl->session->get_frame_offset() + - edl->local_session->get_selectionend() * - edl->session->sample_rate); } else { asset.audio_data = 0; asset.channels = 0; - asset.tcstart = 0; - asset.tcend = 0; } if(!asset.audio_data && @@ -457,25 +444,15 @@ int Render::check_asset(EDL *edl, Asset &asset) return 0; } -int Render::fix_strategy(int strategy, int use_renderfarm) +int Render::get_strategy(int use_renderfarm, int use_labels) { - if(use_renderfarm) - { - if(strategy == FILE_PER_LABEL) - strategy = FILE_PER_LABEL_FARM; - else - if(strategy == SINGLE_PASS) - strategy = SINGLE_PASS_FARM; - } - else - { - if(strategy == FILE_PER_LABEL_FARM) - strategy = FILE_PER_LABEL; - else - if(strategy == SINGLE_PASS_FARM) - strategy = SINGLE_PASS; - } - return strategy; + return use_renderfarm ? + (use_labels ? FILE_PER_LABEL_FARM : SINGLE_PASS_FARM) : + (use_labels ? FILE_PER_LABEL : SINGLE_PASS ) ; +} +int Render::get_strategy() +{ + return get_strategy(preferences->use_renderfarm, use_labels); } void Render::start_progress() @@ -516,12 +493,26 @@ void Render::stop_progress() sprintf(string2, _("Rendering took %s"), string); mwindow->gui->lock_window(""); mwindow->gui->show_message(string2); + mwindow->gui->update_default_message(); mwindow->gui->stop_hourglass(); mwindow->gui->unlock_window(); } progress = 0; } +void Render::show_progress() +{ + int64_t current_eta = progress_timer->get_scaled_difference(1000); + if (current_eta - last_eta < 1000 ) return; + double eta = !total_rendered ? 0 : + current_eta / 1000. * (progress_max / (double)total_rendered - 1.); + char string[BCTEXTLEN]; Units::totext(string, eta, TIME_HMS2); + printf("\r%d%% %s: %s ", + (int)(100 * (float)total_rendered / progress_max), _("ETA"), string); + fflush(stdout); + last_eta = current_eta; +} + void Render::start_render() @@ -529,6 +520,7 @@ void Render::start_render() in_progress = 0; elapsed_time = 0.0; result = 0; + completion->reset(); thread->start(); } @@ -610,7 +602,7 @@ void Render::get_starting_number(char *path, int Render::load_defaults(Asset *asset) { - strategy = mwindow->defaults->get("RENDER_STRATEGY", SINGLE_PASS); + use_labels = mwindow->defaults->get("RENDER_FILE_PER_LABEL", 0); load_mode = mwindow->defaults->get("RENDER_LOADMODE", LOADMODE_NEW_TRACKS); range_type = mwindow->defaults->get("RENDER_RANGE_TYPE", RANGE_PROJECT); @@ -629,8 +621,8 @@ int Render::load_defaults(Asset *asset) int Render::load_profile(int profile_slot, Asset *asset) { char string_name[100]; - sprintf(string_name, "RENDER_%i_STRATEGY", profile_slot); - strategy = mwindow->defaults->get(string_name, SINGLE_PASS); + sprintf(string_name, "RENDER_%i_FILE_PER_LABEL", profile_slot); + use_labels = mwindow->defaults->get(string_name, 0); // Load mode is not part of the profile // printf(string_name, "RENDER_%i_LOADMODE", profile_slot); // load_mode = mwindow->defaults->get(string_name, LOADMODE_NEW_TRACKS); @@ -646,7 +638,7 @@ int Render::load_profile(int profile_slot, Asset *asset) int Render::save_defaults(Asset *asset) { - mwindow->defaults->update("RENDER_STRATEGY", strategy); + mwindow->defaults->update("RENDER_FILE_PER_LABEL", use_labels); mwindow->defaults->update("RENDER_LOADMODE", load_mode); mwindow->defaults->update("RENDER_RANGE_TYPE", range_type); @@ -676,17 +668,13 @@ RenderThread::~RenderThread() } -void RenderThread::render_single(int test_overwrite, - Asset *asset, - EDL *edl, - int strategy, - int range_type) +void RenderThread::render_single(int test_overwrite, Asset *asset, EDL *edl, + int strategy, int range_type) { // Total length in seconds double total_length; RenderFarmServer *farm_server = 0; FileSystem fs; - //int done = 0; const int debug = 0; render->in_progress = 1; @@ -696,35 +684,31 @@ void RenderThread::render_single(int test_overwrite, render->progress = 0; render->result = 0; - if(mwindow) - { - if(!render->preferences) - render->preferences = new Preferences; - - render->preferences->copy_from(mwindow->preferences); - } - - // Create rendering command TransportCommand *command = new TransportCommand; command->command = NORMAL_FWD; command->get_edl()->copy_all(edl); command->change_type = CHANGE_ALL; - if (range_type == RANGE_BACKCOMPAT) { + switch( range_type ) { + case RANGE_BACKCOMPAT: // Get highlighted playback range command->set_playback_range(); // Adjust playback range with in/out points command->playback_range_adjust_inout(); - } - else if (range_type == RANGE_PROJECT) { + break; + case RANGE_PROJECT: command->playback_range_project(); - } - else if (range_type == RANGE_SELECTION) { + break; + case RANGE_SELECTION: command->set_playback_range(); - } - else if (range_type == RANGE_INOUT) { + break; + case RANGE_INOUT: command->playback_range_inout(); + break; + case RANGE_1FRAME: + command->playback_range_1frame(); + break; } render->packages = new PackageDispatcher; @@ -761,7 +745,6 @@ void RenderThread::render_single(int test_overwrite, if(mwindow) mwindow->stop_brender(); fs.complete_path(render->default_asset->path); - strategy = Render::fix_strategy(strategy, render->preferences->use_renderfarm); render->result = render->packages->create_packages(mwindow, command->get_edl(), @@ -773,7 +756,6 @@ void RenderThread::render_single(int test_overwrite, test_overwrite); } - //done = 0; render->total_rendered = 0; if(!render->result) @@ -865,15 +847,9 @@ void RenderThread::render_single(int test_overwrite, // Exit point if(!package) { - //done = 1; break; } - - - Timer timer; - timer.update(); - if(package_renderer.render_package(package)) render->result = 1; @@ -888,8 +864,14 @@ printf("Render::render_single: Session finished.\n"); - if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM) - { + if( strategy == SINGLE_PASS_FARM || + strategy == FILE_PER_LABEL_FARM ) { + if( !render->progress ) { + while( farm_server->active_clients() > 0 ) { + sleep(1); + render->show_progress(); + } + } farm_server->wait_clients(); render->result |= render->packages->packages_are_done(); } @@ -905,9 +887,9 @@ if(debug) printf("Render::render %d\n", __LINE__); if(mwindow) { if(debug) printf("Render::render %d\n", __LINE__); - ErrorBox error_box(_(PROGRAM_NAME ": Error"), - mwindow->gui->get_abs_cursor_x(1), - mwindow->gui->get_abs_cursor_y(1)); + int cx, cy; + mwindow->gui->get_abs_cursor(cx, cy, 1); + ErrorBox error_box(_(PROGRAM_NAME ": Error"), cx, cy); error_box.create_objects(_("Error rendering data.")); error_box.raise_window(); error_box.run_window(); @@ -948,11 +930,7 @@ if(debug) printf("Render::render %d\n", __LINE__); if(render->load_mode == LOADMODE_PASTE) mwindow->clear(0); if(debug) printf("Render::render %d\n", __LINE__); - mwindow->load_assets(assets, - -1, - render->load_mode, - 0, - 0, + mwindow->load_assets(assets, -1, render->load_mode, 0, 0, mwindow->edl->session->labels_follow_edits, mwindow->edl->session->plugins_follow_edits, mwindow->edl->session->autos_follow_edits, @@ -1011,15 +989,18 @@ if(debug) printf("Render::render %d\n", __LINE__); render->packages = 0; render->in_progress = 0; - render->completion->unlock(); if(debug) printf("Render::render %d\n", __LINE__); } void RenderThread::run() { + if( mwindow ) + render->preferences->copy_from(mwindow->preferences); + if(render->mode == Render::INTERACTIVE) { - render_single(1, render->asset, mwindow->edl, render->strategy, render->range_type); + render_single(1, render->asset, mwindow->edl, + render->get_strategy(), render->range_type); } else if(render->mode == Render::BATCH) @@ -1057,9 +1038,8 @@ void RenderThread::run() edl->create_objects(); file->read_from_file(job->edl_path); edl->load_xml(file, LOAD_ALL); - //PRINT_TRACE - render_single(0, job->asset, edl, job->strategy, RANGE_BACKCOMPAT); + render_single(0, job->asset, edl, job->get_strategy(), RANGE_BACKCOMPAT); //PRINT_TRACE edl->Garbage::remove_user(); @@ -1096,11 +1076,15 @@ void RenderThread::run() mwindow->batch_render->update_done(-1, 0, 0); } } + render->completion->unlock(); + + if( render->mode == Render::INTERACTIVE && render->beep ) + mwindow->beep(3000., 1.5, 0.5); } -#define WIDTH 440 -#define HEIGHT 455 +#define WIDTH 480 +#define HEIGHT 480 RenderWindow::RenderWindow(MWindow *mwindow, @@ -1108,27 +1092,28 @@ RenderWindow::RenderWindow(MWindow *mwindow, Asset *asset, int x, int y) - : BC_Window(_(PROGRAM_NAME ": Render"), - x - WIDTH / 2, y - HEIGHT / 2, - WIDTH, HEIGHT, WIDTH, HEIGHT, - 0, 0, 1) + : BC_Window(_(PROGRAM_NAME ": Render"), x, y, + WIDTH, HEIGHT, WIDTH, HEIGHT, 0, 0, 1) { this->mwindow = mwindow; this->render = render; this->asset = asset; + render_format = 0; + loadmode = 0; + renderprofile = 0; + rangeproject = 0; + rangeselection = 0; + rangeinout = 0; + range1frame = 0; } RenderWindow::~RenderWindow() { -SET_TRACE lock_window("RenderWindow::~RenderWindow"); -SET_TRACE - delete format_tools; -SET_TRACE + delete render_format; delete loadmode; -SET_TRACE + delete renderprofile; unlock_window(); -SET_TRACE } @@ -1136,39 +1121,57 @@ void RenderWindow::load_profile(int profile_slot) { render->load_profile(profile_slot, asset); update_range_type(render->range_type); - format_tools->update(asset, &render->strategy); + render_format->update(asset, &render->use_labels); } void RenderWindow::create_objects() { - int x = 10, y = 5; + int x = 10, y = 10; lock_window("RenderWindow::create_objects"); - add_subwindow(new BC_Title(x, - y, - (char*)((render->strategy == FILE_PER_LABEL || - render->strategy == FILE_PER_LABEL_FARM) ? + add_subwindow(new BC_Title(x, y, + (char*)(render->use_labels ? _("Select the first file to render to:") : _("Select a file to render to:")))); y += 25; - format_tools = new FormatTools(mwindow, this, asset); - format_tools->create_objects(x, y, - 1, 1, 1, 1, 0, 1, 0, 0, &render->strategy, 0); + render_format = new RenderFormat(mwindow, this, asset); + render_format->create_objects(x, y, + 1, 1, 1, 1, 0, 1, 0, 0, &render->use_labels, 0); - add_subwindow(new BC_Title(x, y, _("Render range:"))); + BC_Title *title; + add_subwindow(title = new BC_Title(x, y, _("Render range:"))); - x += 110; + int is_image = File::is_image_render(asset->format); + if( is_image ) + render->range_type = RANGE_1FRAME; + + int x1 = x + title->get_w() + 20, y1 = y; add_subwindow(rangeproject = new RenderRangeProject(this, - render->range_type == RANGE_PROJECT, x, y)); + render->range_type == RANGE_PROJECT, x1, y)); + int x2 = x1 + rangeproject->get_w(); y += 20; add_subwindow(rangeselection = new RenderRangeSelection(this, - render->range_type == RANGE_SELECTION, x, y)); + render->range_type == RANGE_SELECTION, x1, y)); + int x3 = x1 + rangeselection->get_w(); + if( x2 < x3 ) x2 = x3; y += 20; add_subwindow(rangeinout = new RenderRangeInOut(this, - render->range_type == RANGE_INOUT, x, y)); + render->range_type == RANGE_INOUT, x1, y)); + x3 = x1 + rangeinout->get_w(); + if( x2 < x3 ) x2 = x3; + y += 20; + add_subwindow(range1frame = new RenderRange1Frame(this, + render->range_type == RANGE_1FRAME, x1, y)); + x3 = x1 + range1frame->get_w(); + if( x2 < x3 ) x2 = x3; y += 30; - x = 5; + if( is_image ) + enable_render_range(0); + + x1 = x2 + 20; + render->beep = mwindow->edl->session->render_beep; + add_subwindow(beep_on_done = new RenderBeepOnDone(this, x1, y1)); renderprofile = new RenderProfile(mwindow, this, x, y, 1); renderprofile->create_objects(); @@ -1179,16 +1182,35 @@ void RenderWindow::create_objects() add_subwindow(new BC_OKButton(this)); add_subwindow(new BC_CancelButton(this)); + show_window(); unlock_window(); } void RenderWindow::update_range_type(int range_type) { + if( render->range_type == range_type ) return; render->range_type = range_type; rangeproject->update(range_type == RANGE_PROJECT); rangeselection->update(range_type == RANGE_SELECTION); rangeinout->update(range_type == RANGE_INOUT); + range1frame->update(range_type == RANGE_1FRAME); +} + +void RenderWindow::enable_render_range(int v) +{ + if( v ) { + rangeproject->enable(); + rangeselection->enable(); + rangeinout->enable(); + range1frame->enable(); + } + else { + rangeproject->disable(); + rangeselection->disable(); + rangeinout->disable(); + range1frame->disable(); + } } @@ -1226,4 +1248,86 @@ int RenderRangeInOut::handle_event() return 1; } +RenderRange1Frame::RenderRange1Frame(RenderWindow *rwindow, int value, int x, int y) + : BC_Radial(x, y, value, _("One Frame")) +{ + this->rwindow = rwindow; +} +int RenderRange1Frame::handle_event() +{ + rwindow->update_range_type(RANGE_1FRAME); + return 1; +} + +double Render::get_render_range() +{ + EDL *edl = mwindow->edl; + double last = edl->tracks->total_playable_length(); + double framerate = edl->session->frame_rate; + if( framerate <= 0 ) framerate = 1; + double start = 0, end = last; + switch( range_type ) { + default: + case RANGE_BACKCOMPAT: + start = edl->local_session->get_selectionstart(1); + end = edl->local_session->get_selectionend(1); + if( EQUIV(start, end) ) end = last; + break; + case RANGE_PROJECT: + break; + case RANGE_SELECTION: + start = edl->local_session->get_selectionstart(1); + end = edl->local_session->get_selectionend(1); + break; + case RANGE_INOUT: + start = edl->local_session->inpoint_valid() ? + edl->local_session->get_inpoint() : 0; + end = edl->local_session->outpoint_valid() ? + edl->local_session->get_outpoint() : last; + break; + case RANGE_1FRAME: + start = end = edl->local_session->get_selectionstart(1); + if( edl->session->frame_rate > 0 ) end += 1./edl->session->frame_rate; + break; + } + if( start < 0 ) start = 0; + if( end > last ) end = last; + return end - start; +} + +RenderFormat::RenderFormat(MWindow *mwindow, BC_WindowBase *window, Asset *asset) + : FormatTools(mwindow, window, asset) +{ +} +RenderFormat::~RenderFormat() +{ +} + +void RenderFormat::update_format() +{ + FormatTools::update_format(); + RenderWindow *render_window = (RenderWindow *)window; + if( render_window->is_hidden() ) return; + + int is_image = File::is_image_render(asset->format); + if( is_image ) { + render_window->update_range_type(RANGE_1FRAME); + render_window->enable_render_range(0); + } + else + render_window->enable_render_range(1); +} + +RenderBeepOnDone::RenderBeepOnDone(RenderWindow *rwindow, int x, int y) + : BC_CheckBox(x, y, rwindow->render->beep, _("Beep on done")) +{ + this->rwindow = rwindow; +} + +int RenderBeepOnDone::handle_event() +{ + rwindow->render->beep = get_value(); + return 1; +} +