From 94fc059e6ed3f77f20531338cbb03bdb3b4d9eab Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 6 Mar 2019 09:21:27 -0700 Subject: [PATCH] batchrender cleanup, bd/dvd create upgrades, remote ctrl booby fix --- cinelerra-5.1/cinelerra/batchrender.C | 146 +++++--- cinelerra-5.1/cinelerra/batchrender.h | 24 +- cinelerra-5.1/cinelerra/bdcreate.C | 219 ++++++----- cinelerra-5.1/cinelerra/bdcreate.h | 27 +- cinelerra-5.1/cinelerra/dvdcreate.C | 314 ++++++++++------ cinelerra-5.1/cinelerra/dvdcreate.h | 36 +- cinelerra-5.1/cinelerra/dvdcreate.inc | 1 + cinelerra-5.1/cinelerra/file.C | 29 +- cinelerra-5.1/cinelerra/main.C | 2 +- cinelerra-5.1/cinelerra/packagedispatcher.C | 238 ++++-------- cinelerra-5.1/cinelerra/packagedispatcher.h | 7 +- cinelerra-5.1/cinelerra/packagerenderer.C | 287 +++++--------- cinelerra-5.1/cinelerra/packagingengine.C | 194 ++++------ cinelerra-5.1/cinelerra/packagingengine.h | 3 + cinelerra-5.1/cinelerra/remotecontrol.C | 2 + cinelerra-5.1/cinelerra/render.C | 391 +++++++------------- cinelerra-5.1/cinelerra/render.h | 10 + cinelerra-5.1/cinelerra/track.C | 5 +- 18 files changed, 897 insertions(+), 1038 deletions(-) diff --git a/cinelerra-5.1/cinelerra/batchrender.C b/cinelerra-5.1/cinelerra/batchrender.C index d67b6ad1..40ed1b0b 100644 --- a/cinelerra-5.1/cinelerra/batchrender.C +++ b/cinelerra-5.1/cinelerra/batchrender.C @@ -34,6 +34,7 @@ #include "file.h" #include "filesystem.h" #include "filexml.h" +#include "indexable.h" #include "keyframe.h" #include "keys.h" #include "labels.h" @@ -55,7 +56,9 @@ #include "transportque.h" #include "vframe.h" -// Farmed is not present if not preferences->use_renderfarm +#include "dvdcreate.h" +#include "bdcreate.h" + int BatchRenderThread::column_widths[] = { 42, 42, 42, 222, 222, 150 }; const char *BatchRenderThread::column_titles[] = { N_("Enabled"), N_("Labeled"), N_("Farmed"), N_("Output"), N_("EDL"), N_("Elapsed") @@ -70,13 +73,14 @@ BatchRenderMenuItem::BatchRenderMenuItem(MWindow *mwindow) int BatchRenderMenuItem::handle_event() { - mwindow->batch_render->start(); + mwindow->batch_render->start(1, 1); return 1; } - -BatchRenderJob::BatchRenderJob(Preferences *preferences, int labeled, int farmed) +BatchRenderJob::BatchRenderJob(const char *tag, + Preferences *preferences, int labeled, int farmed) { + this->tag = tag; this->preferences = preferences; this->labeled = labeled; this->farmed = farmed >= 0 ? farmed : preferences->use_renderfarm; @@ -86,6 +90,11 @@ BatchRenderJob::BatchRenderJob(Preferences *preferences, int labeled, int farmed elapsed = 0; } +BatchRenderJob::BatchRenderJob(Preferences *preferences, int labeled, int farmed) + : BatchRenderJob("JOB", preferences, labeled, farmed) +{ +} + BatchRenderJob::~BatchRenderJob() { asset->Garbage::remove_user(); @@ -101,13 +110,20 @@ void BatchRenderJob::copy_from(BatchRenderJob *src) elapsed = 0; } +BatchRenderJob *BatchRenderJob::copy() +{ + BatchRenderJob *t = new BatchRenderJob(tag, preferences, labeled, farmed); + t->copy_from(this); + return t; +} + void BatchRenderJob::load(FileXML *file) { int result = 0; enabled = file->tag.get_property("ENABLED", enabled); farmed = file->tag.get_property("FARMED", farmed); - labeled = file->tag.get_property("STRATEGY", labeled); + labeled = file->tag.get_property("LABELED", labeled); edl_path[0] = 0; file->tag.get_property("EDL_PATH", edl_path); elapsed = file->tag.get_property("ELAPSED", elapsed); @@ -130,6 +146,8 @@ void BatchRenderJob::load(FileXML *file) void BatchRenderJob::save(FileXML *file) { + char end_tag[BCSTRLEN]; end_tag[0] = '/'; + strcpy(&end_tag[1], file->tag.get_title()); file->tag.set_property("ENABLED", enabled); file->tag.set_property("FARMED", farmed); file->tag.set_property("LABELED", labeled); @@ -148,16 +166,19 @@ void BatchRenderJob::save(FileXML *file) defaults.save_string(string); file->append_text(string); free(string); - file->tag.set_title("/JOB"); + file->tag.set_title(end_tag); file->append_tag(); file->append_newline(); } +char *BatchRenderJob::create_script(EDL *edl, ArrayList *idxbls) +{ + return 0; +} + int BatchRenderJob::get_strategy() { -// if set, overrides farmed, labeled - int use_renderfarm = farmed && preferences->use_renderfarm ? 1 : 0; - return Render::get_strategy(use_renderfarm, labeled); + return Render::get_strategy(farmed, labeled); } @@ -174,21 +195,8 @@ BatchRenderThread::BatchRenderThread(MWindow *mwindow) warn = 1; render = 0; batch_path[0] = 0; -} - -BatchRenderThread::BatchRenderThread() - : BC_DialogThread() -{ - mwindow = 0; - current_job = 0; - rendering_job = -1; - is_rendering = 0; - default_job = 0; - boot_defaults = 0; - preferences = 0; - warn = 1; - render = 0; - batch_path[0] = 0; + do_farmed = 0; + do_labeled = 0; } BatchRenderThread::~BatchRenderThread() @@ -196,6 +204,7 @@ BatchRenderThread::~BatchRenderThread() close_window(); delete boot_defaults; delete preferences; + delete default_job; delete render; } @@ -211,6 +220,13 @@ void BatchRenderThread::reset(const char *path) jobs.remove_all_objects(); } +void BatchRenderThread::start(int do_farmed, int do_labeled) +{ + this->do_farmed = do_farmed; + this->do_labeled = do_labeled; + BC_DialogThread::start(); +} + void BatchRenderThread::handle_close_event(int result) { // Save settings @@ -223,7 +239,7 @@ BC_Window* BatchRenderThread::new_gui() { current_start = 0.0; current_end = 0.0; - default_job = new BatchRenderJob(mwindow->preferences); + default_job = new BatchRenderJob(mwindow->preferences, 0, -1); load_jobs(batch_path, mwindow->preferences); load_defaults(mwindow->defaults); this->gui = new BatchRenderGUI(mwindow, this, @@ -250,7 +266,17 @@ void BatchRenderThread::load_jobs(char *path, Preferences *preferences) warn = file.tag.get_property("WARN", 1); } else if( file.tag.title_is("JOB") ) { - BatchRenderJob *job = new BatchRenderJob(preferences); + BatchRenderJob *job = new BatchRenderJob(preferences, 0,0); + jobs.append(job); + job->load(&file); + } + else if( file.tag.title_is("DVD_JOB") ) { + DVD_BatchRenderJob *job = new DVD_BatchRenderJob(preferences, 0,0,0,0); + jobs.append(job); + job->load(&file); + } + else if( file.tag.title_is("BD_JOB") ) { + BD_BatchRenderJob *job = new BD_BatchRenderJob(preferences, 0,0); jobs.append(job); job->load(&file); } @@ -267,8 +293,8 @@ void BatchRenderThread::save_jobs(char *path) file.append_newline(); for( int i = 0; i < jobs.total; i++ ) { - file.tag.set_title("JOB"); - jobs.values[i]->save(&file); + file.tag.set_title(jobs[i]->tag); + jobs[i]->save(&file); } file.tag.set_title("/JOBS"); file.append_tag(); @@ -322,8 +348,7 @@ char* BatchRenderThread::create_path(char *string) void BatchRenderThread::new_job() { - BatchRenderJob *result = new BatchRenderJob(mwindow->preferences); - result->copy_from(get_current_job()); + BatchRenderJob *result = get_current_job()->copy(); jobs.append(result); current_job = jobs.total - 1; gui->create_list(1); @@ -481,14 +506,9 @@ void BatchRenderThread::calculate_dest_paths(ArrayList *paths, command->playback_range_adjust_inout(); // Create test packages - packages->create_packages(mwindow, - command->get_edl(), - preferences, - job->get_strategy(), - job->asset, - command->start_position, - command->end_position, - 0); + packages->create_packages(mwindow, command->get_edl(), + preferences, job->get_strategy(), job->asset, + command->start_position, command->end_position, 0); // Append output paths allocated to total packages->get_package_paths(paths); @@ -693,7 +713,7 @@ void BatchRenderGUI::create_objects() int x = mwindow->theme->batchrender_x1; int y = 5; - int x1 = x, x2 = get_w()/2 + 10; // mwindow->theme->batchrender_x2; + int x1 = x, x2 = get_w()/2 + 30; // mwindow->theme->batchrender_x2; int y1 = 5, y2 = 5; // output file @@ -701,16 +721,21 @@ void BatchRenderGUI::create_objects() y1 += output_path_title->get_h() + mwindow->theme->widget_border; format_tools = new BatchFormat(mwindow, this, thread->get_current_asset()); - format_tools->set_w(get_w() / 2); + format_tools->set_w(x2 - 40); BatchRenderJob *current_job = thread->get_current_job(); format_tools->create_objects(x1, y1, 1, 1, 1, 1, 0, 1, 0, 0, - ¤t_job->labeled, 0); - if( mwindow->preferences->use_renderfarm ) { + thread->do_labeled ? ¤t_job->labeled : 0, 0); + if( thread->do_labeled < 0 ) + format_tools->labeled_files->disable(); + if( thread->do_farmed ) { use_renderfarm = new BatchRenderUseFarm(thread, x1, y1, ¤t_job->farmed); add_subwindow(use_renderfarm); y1 += use_renderfarm->get_h() + 10; + if( thread->do_farmed < 0 ) + use_renderfarm->disable(); } + // input EDL add_subwindow(edl_path_title = new BC_Title(x2, y2, _("EDL Path:"))); y2 += edl_path_title->get_h() + mwindow->theme->widget_border; @@ -795,7 +820,7 @@ int BatchRenderGUI::resize_event(int w, int h) output_path_title->reposition_window(x1, y1); y1 += output_path_title->get_h() + mwindow->theme->widget_border; format_tools->reposition_window(x1, y1); - if( use_renderfarm ) + if( thread->do_farmed ) use_renderfarm->reposition_window(x1, y1); // input EDL x = x2, y = y2; @@ -867,9 +892,11 @@ void BatchRenderGUI::create_list(int update_widget) list_columns = 0; list_titles[list_columns] = _(column_titles[ENABLED_COL]); list_width[list_columns++] = thread->list_width[ENABLED_COL]; - list_titles[list_columns] = _(column_titles[LABELED_COL]); - list_width[list_columns++] = thread->list_width[LABELED_COL]; - if( mwindow->preferences->use_renderfarm ) { + if( thread->do_labeled > 0 ) { + list_titles[list_columns] = _(column_titles[LABELED_COL]); + list_width[list_columns++] = thread->list_width[LABELED_COL]; + } + if( thread->do_farmed > 0 ) { list_titles[list_columns] = _(column_titles[FARMED_COL]); list_width[list_columns++] = thread->list_width[FARMED_COL]; } @@ -884,23 +911,24 @@ void BatchRenderGUI::create_list(int update_widget) BatchRenderJob *job = thread->jobs.values[i]; char string[BCTEXTLEN]; BC_ListBoxItem *enabled = new BC_ListBoxItem(job->enabled ? "X" : " "); - BC_ListBoxItem *labeled = new BC_ListBoxItem(job->labeled ? "X" : " "); - BC_ListBoxItem *farmed = !mwindow->preferences->use_renderfarm ? 0 : - new BC_ListBoxItem(job->farmed ? "X" : " "); + BC_ListBoxItem *labeled = thread->do_labeled > 0 ? + new BC_ListBoxItem(job->labeled ? "X" : " ") : 0; + BC_ListBoxItem *farmed = thread->do_farmed > 0 ? + new BC_ListBoxItem(job->farmed ? "X" : " ") : 0; BC_ListBoxItem *out_path = new BC_ListBoxItem(job->asset->path); BC_ListBoxItem *edl_path = new BC_ListBoxItem(job->edl_path); BC_ListBoxItem *elapsed = new BC_ListBoxItem(!job->elapsed ? _("Unknown") : Units::totext(string, job->elapsed, TIME_HMS2)); int col = 0; list_items[col++].append(enabled); - list_items[col++].append(labeled); + if( labeled ) list_items[col++].append(labeled); if( farmed ) list_items[col++].append(farmed); list_items[col++].append(out_path); list_items[col++].append(edl_path); list_items[col].append(elapsed); if( i == thread->current_job ) { enabled->set_selected(1); - labeled->set_selected(1); + if( labeled ) labeled->set_selected(1); if( farmed ) farmed->set_selected(1); out_path->set_selected(1); edl_path->set_selected(1); @@ -908,7 +936,7 @@ void BatchRenderGUI::create_list(int update_widget) } if( i == thread->rendering_job ) { enabled->set_color(RED); - labeled->set_color(RED); + if( labeled ) labeled->set_color(RED); if( farmed ) farmed->set_color(RED); out_path->set_color(RED); edl_path->set_color(RED); @@ -926,8 +954,8 @@ void BatchRenderGUI::create_list(int update_widget) void BatchRenderGUI::change_job() { BatchRenderJob *job = thread->get_current_job(); - format_tools->update(job->asset, &job->labeled); - if( use_renderfarm ) use_renderfarm->update(&job->farmed); + format_tools->update(job->asset, thread->do_labeled ? &job->labeled : 0); + if( thread->do_farmed ) use_renderfarm->update(&job->farmed); edl_path_text->update(job->edl_path); } @@ -1201,9 +1229,10 @@ int BatchRenderList::selection_changed() int col_x = 0, changed = 1; if( cursor_x < (col_x += thread->list_width[ENABLED_COL]) ) job->enabled = !job->enabled; - else if( cursor_x < (col_x += thread->list_width[LABELED_COL]) ) + else if( thread->do_labeled > 0 && + cursor_x < (col_x += thread->list_width[LABELED_COL]) ) job->labeled = job->edl_path[0] != '@' ? !job->labeled : 0; - else if( thread->gui->use_renderfarm && + else if( thread->do_farmed > 0 && cursor_x < (col_x += thread->list_width[FARMED_COL]) ) job->farmed = job->edl_path[0] != '@' ? !job->farmed : 0; else @@ -1219,8 +1248,9 @@ int BatchRenderList::column_resize_event() { int col = 0; thread->list_width[ENABLED_COL] = get_column_width(col++); - thread->list_width[LABELED_COL] = get_column_width(col++); - if( thread->gui->use_renderfarm ) + if( thread->do_labeled > 0 ) + thread->list_width[LABELED_COL] = get_column_width(col++); + if( thread->do_farmed > 0 ) thread->list_width[FARMED_COL] = get_column_width(col++); thread->list_width[OUTPUT_COL] = get_column_width(col++); thread->list_width[EDL_COL] = get_column_width(col++); diff --git a/cinelerra-5.1/cinelerra/batchrender.h b/cinelerra-5.1/cinelerra/batchrender.h index 4a81520b..90e35855 100644 --- a/cinelerra-5.1/cinelerra/batchrender.h +++ b/cinelerra-5.1/cinelerra/batchrender.h @@ -30,6 +30,7 @@ #include "browsebutton.inc" #include "filexml.inc" #include "formattools.h" +#include "indexable.inc" #include "keyframe.inc" #include "mwindow.inc" #include "preferences.inc" @@ -55,14 +56,19 @@ public: class BatchRenderJob { public: - BatchRenderJob(Preferences *preferences, int labeled=0, int farmed=-1); - ~BatchRenderJob(); - + BatchRenderJob(const char *tag, + Preferences *preferences, int labeled, int farmed); + BatchRenderJob(Preferences *preferences, int labeled, int farmed); + BatchRenderJob(const char *tag); + virtual ~BatchRenderJob(); + virtual BatchRenderJob *copy(); + virtual void load(FileXML *file); + virtual void save(FileXML *file); + virtual int get_strategy(); + virtual char *create_script(EDL *edl, ArrayList *idxbls); void copy_from(BatchRenderJob *src); - void load(FileXML *file); - void save(FileXML *file); - int get_strategy(); + const char *tag; // Source EDL to render char edl_path[BCTEXTLEN]; // Destination file for output @@ -84,8 +90,7 @@ public: class BatchRenderThread : public BC_DialogThread { public: - BatchRenderThread(MWindow *mwindow); - BatchRenderThread(); + BatchRenderThread(MWindow *mwindow=0); ~BatchRenderThread(); void handle_close_event(int result); BC_Window* new_gui(); @@ -119,6 +124,7 @@ public: void update_active(int number); void update_done(int number, int create_list, double elapsed_time); void move_batch(int src, int dst); + void start(int do_farmed, int do_labeled); static void trap_hook(FILE *fp, void *vp); MWindow *mwindow; @@ -135,6 +141,8 @@ public: static const char *column_titles[BATCHRENDER_COLUMNS]; static int column_widths[BATCHRENDER_COLUMNS]; int list_width[BATCHRENDER_COLUMNS]; + int do_farmed; + int do_labeled; // job being edited int current_job; // job being rendered diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C index 27f728ad..dcae332d 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.C +++ b/cinelerra-5.1/cinelerra/bdcreate.C @@ -10,7 +10,6 @@ #include "filexml.h" #include "interlacemodes.h" #include "keyframe.h" -#include "labels.h" #include "mainerror.h" #include "mainundo.h" #include "mwindow.h" @@ -90,44 +89,18 @@ int CreateBD_MenuItem::handle_event() return 1; } - -CreateBD_Thread::CreateBD_Thread(MWindow *mwindow) - : BC_DialogThread() +BD_BatchRenderJob::BD_BatchRenderJob(Preferences *preferences, int labeled, int farmed) + : BatchRenderJob("BD_JOB", preferences, labeled, farmed) { - this->mwindow = mwindow; - this->gui = 0; - this->use_deinterlace = 0; - this->use_scale = Rescale::none; - this->use_histogram = 0; - this->use_inverse_telecine = 0; - this->use_wide_audio = 0; - this->use_resize_tracks = 0; - this->use_label_chapters = 0; - - this->bd_size = BD_SIZE; - this->bd_width = BD_WIDTH; - this->bd_height = BD_HEIGHT; - this->bd_aspect_width = BD_WIDE_ASPECT_WIDTH; - this->bd_aspect_height = BD_WIDE_ASPECT_HEIGHT; - this->bd_framerate = BD_FRAMERATE; - this->bd_samplerate = BD_SAMPLERATE; - this->bd_max_bitrate = BD_MAX_BITRATE; - this->bd_kaudio_rate = BD_KAUDIO_RATE; - this->max_w = this->max_h = 0; } -CreateBD_Thread::~CreateBD_Thread() -{ - close_window(); -} - -int CreateBD_Thread::get_udfs_mount(char *udfs, char *mopts, char *mntpt) +int BD_BatchRenderJob::get_udfs_mount(char *udfs, char *mopts, char *mntpt) { int ret = 0; -// default: mount -t udf -o loop $1/bd.udfs $1/udfs - strcpy(udfs,"$1/bd.udfs"); - strcpy(mopts,"-t udf -o loop $1/bd.udfs "); - strcpy(mntpt,"$1/udfs"); +// default: mount -t udf -o loop $dir/bd.udfs $dir/udfs + strcpy(udfs,"$dir/bd.udfs"); + strcpy(mopts,"-t udf -o loop $dir/bd.udfs "); + strcpy(mntpt,"$dir/udfs"); const char *home = getenv("HOME"); if( !home ) return ret; FILE *fp = fopen("/etc/fstab","r"); @@ -167,6 +140,83 @@ int CreateBD_Thread::get_udfs_mount(char *udfs, char *mopts, char *mntpt) return ret; } +char *BD_BatchRenderJob::create_script(EDL *edl, ArrayList *idxbls) +{ + char script[BCTEXTLEN]; + strcpy(script, edl_path); + FILE *fp = 0; + char *bp = strrchr(script,'/'); + int fd = -1; + if( bp ) { + strcpy(bp, "/bd.sh"); + fd = open(script, O_WRONLY+O_CREAT+O_TRUNC, 0755); + } + if( fd >= 0 ) + fp = fdopen(fd, "w"); + if( !fp ) { + char err[BCTEXTLEN], msg[BCTEXTLEN]; + strerror_r(errno, err, sizeof(err)); + sprintf(msg, _("Unable to save: %s\n-- %s"), script, err); + MainError::show_error(msg); + return 0; + } + char udfs[BCTEXTLEN], mopts[BCTEXTLEN], mntpt[BCTEXTLEN]; + int is_usr_mnt = get_udfs_mount(udfs, mopts, mntpt); + const char *exec_path = File::get_cinlib_path(); + fprintf(fp,"#!/bin/bash -ex\n"); + fprintf(fp,"dir=`dirname $0`\n"); + fprintf(fp,"PATH=$PATH:%s\n",exec_path); + fprintf(fp,"mkdir -p $dir/udfs\n"); + fprintf(fp,"sz=`du -cb $dir/bd.m2ts* | tail -1 | sed -e 's/[ \t].*//'`\n"); + fprintf(fp,"blks=$((sz/2048 + 4096))\n"); + fprintf(fp,"rm -f %s\n", udfs); + fprintf(fp,"mkudffs -b 2048 %s $blks\n", udfs); + fprintf(fp,"mount %s%s\n", mopts, mntpt); + fprintf(fp,"bdwrite %s $dir/bd.m2ts*\n",mntpt); + fprintf(fp,"umount %s\n",mntpt); + if( is_usr_mnt ) + fprintf(fp,"mv -f %s $dir/bd.udfs\n", udfs); + fprintf(fp,"echo To burn bluray, load writable media and run:\n"); + fprintf(fp,"echo for WORM: growisofs -dvd-compat -Z /dev/bd=$dir/bd.udfs\n"); + fprintf(fp,"echo for RW: dd if=$dir/bd.udfs of=/dev/bd bs=2048000\n"); + fprintf(fp,"kill $$\n"); + fprintf(fp,"\n"); + fclose(fp); + return cstrdup(script); +} + + +CreateBD_Thread::CreateBD_Thread(MWindow *mwindow) + : BC_DialogThread() +{ + this->mwindow = mwindow; + this->gui = 0; + this->use_deinterlace = 0; + this->use_scale = Rescale::none; + this->use_histogram = 0; + this->use_inverse_telecine = 0; + this->use_wide_audio = 0; + this->use_resize_tracks = 0; + this->use_labeled = 0; + this->use_farmed = 0; + + this->bd_size = BD_SIZE; + this->bd_width = BD_WIDTH; + this->bd_height = BD_HEIGHT; + this->bd_aspect_width = BD_WIDE_ASPECT_WIDTH; + this->bd_aspect_height = BD_WIDE_ASPECT_HEIGHT; + this->bd_framerate = BD_FRAMERATE; + this->bd_samplerate = BD_SAMPLERATE; + this->bd_max_bitrate = BD_MAX_BITRATE; + this->bd_kaudio_rate = BD_KAUDIO_RATE; + this->max_w = this->max_h = 0; +} + +CreateBD_Thread::~CreateBD_Thread() +{ + close_window(); +} + int CreateBD_Thread::create_bd_jobs(ArrayList *jobs, const char *asset_dir) { EDL *edl = mwindow->edl; @@ -209,39 +259,6 @@ int CreateBD_Thread::create_bd_jobs(ArrayList *jobs, const char use_wide_audio ? BD_WIDE_CHANNELS : BD_CHANNELS; session->interlace_mode = bd_interlace_mode; - char script_filename[BCTEXTLEN]; - sprintf(script_filename, "%s/bd.sh", asset_dir); - int fd = open(script_filename, O_WRONLY+O_CREAT+O_TRUNC, 0755); - FILE *fp = fdopen(fd, "w"); - if( !fp ) { - char err[BCTEXTLEN], msg[BCTEXTLEN]; - strerror_r(errno, err, sizeof(err)); - sprintf(msg, _("Unable to save: %s\n-- %s"), script_filename, err); - MainError::show_error(msg); - return 1; - } - char udfs[BCTEXTLEN], mopts[BCTEXTLEN], mntpt[BCTEXTLEN]; - int is_usr_mnt = get_udfs_mount(udfs, mopts, mntpt); - const char *exec_path = File::get_cinlib_path(); - fprintf(fp,"#!/bin/bash -ex\n"); - fprintf(fp,"PATH=$PATH:%s\n",exec_path); - fprintf(fp,"mkdir -p $1/udfs\n"); - fprintf(fp,"sz=`du -cb $1/bd.m2ts* | tail -1 | sed -e 's/[ \t].*//'`\n"); - fprintf(fp,"blks=$((sz/2048 + 4096))\n"); - fprintf(fp,"rm -f %s\n", udfs); - fprintf(fp,"mkudffs -b 2048 %s $blks\n", udfs); - fprintf(fp,"mount %s%s\n", mopts, mntpt); - fprintf(fp,"bdwrite %s $1/bd.m2ts*\n",mntpt); - fprintf(fp,"umount %s\n",mntpt); - if( is_usr_mnt ) - fprintf(fp,"mv -f %s $1/bd.udfs\n", udfs); - fprintf(fp,"echo To burn bluray, load writable media and run:\n"); - fprintf(fp,"echo for WORM: growisofs -dvd-compat -Z /dev/bd=$1/bd.udfs\n"); - fprintf(fp,"echo for RW: dd if=$1/bd.udfs of=/dev/bd bs=2048000\n"); - fprintf(fp,"kill $$\n"); - fprintf(fp,"\n"); - fclose(fp); - session->audio_channels = session->audio_tracks = !use_wide_audio ? BD_CHANNELS : BD_WIDE_CHANNELS; for( int i=0; i *jobs, const char return 1; } - BatchRenderJob *job = new BatchRenderJob(mwindow->preferences, use_label_chapters); + BatchRenderJob *job = new BD_BatchRenderJob(mwindow->preferences, + use_labeled, use_farmed); jobs->append(job); strcpy(&job->edl_path[0], xml_filename); Asset *asset = job->asset; @@ -318,13 +336,6 @@ int CreateBD_Thread::create_bd_jobs(ArrayList *jobs, const char } asset->ff_video_bitrate = vid_bitrate; asset->ff_video_quality = -1; - - job = new BatchRenderJob(mwindow->preferences, 0, 0); - jobs->append(job); - job->edl_path[0] = '@'; - strcpy(&job->edl_path[1], script_filename); - strcpy(&job->asset->path[0], asset_dir); - return 0; } @@ -413,7 +424,7 @@ void CreateBD_Thread::handle_close_event(int result) mwindow->resync_guis(); if( ret ) return; mwindow->batch_render->save_jobs(); - mwindow->batch_render->start(); + mwindow->batch_render->start(-use_farmed, -use_labeled); } BC_Window* CreateBD_Thread::new_gui() @@ -432,7 +443,8 @@ BC_Window* CreateBD_Thread::new_gui() use_inverse_telecine = 0; use_wide_audio = 0; use_resize_tracks = 0; - use_label_chapters = 0; + use_labeled = 0; + use_farmed = 0; use_standard = !strcmp(mwindow->default_std(),"NTSC") ? BD_1920x1080_2997i : BD_1920x1080_25i; bd_size = BD_SIZE; @@ -465,7 +477,7 @@ BC_Window* CreateBD_Thread::new_gui() int scr_x = mwindow->gui->get_screen_x(0, -1); int scr_w = mwindow->gui->get_screen_w(0, -1); int scr_h = mwindow->gui->get_screen_h(0, -1); - int w = 500, h = 280; + int w = 500, h = 290; int x = scr_x + scr_w/2 - w/2, y = scr_h/2 - h/2; gui = new CreateBD_GUI(this, x, y, w, h); @@ -664,7 +676,7 @@ CreateBD_Histogram::~CreateBD_Histogram() } CreateBD_LabelChapters::CreateBD_LabelChapters(CreateBD_GUI *gui, int x, int y) - : BC_CheckBox(x, y, &gui->thread->use_label_chapters, _("Chapters at Labels")) + : BC_CheckBox(x, y, &gui->thread->use_labeled, _("Chapters at Labels")) { this->gui = gui; } @@ -673,6 +685,17 @@ CreateBD_LabelChapters::~CreateBD_LabelChapters() { } +CreateBD_UseRenderFarm::CreateBD_UseRenderFarm(CreateBD_GUI *gui, int x, int y) + : BC_CheckBox(x, y, &gui->thread->use_farmed, _("Use render farm")) +{ + this->gui = gui; +} + +CreateBD_UseRenderFarm::~CreateBD_UseRenderFarm() +{ +} + + CreateBD_WideAudio::CreateBD_WideAudio(CreateBD_GUI *gui, int x, int y) : BC_CheckBox(x, y, &gui->thread->use_wide_audio, _("Audio 5.1")) { @@ -703,7 +726,8 @@ CreateBD_GUI::CreateBD_GUI(CreateBD_Thread *thread, int x, int y, int w, int h) need_histogram = 0; non_standard = 0; need_wide_audio = 0; - need_label_chapters = 0; + need_labeled = 0; + need_farmed = 0; ok = 0; cancel = 0; } @@ -762,23 +786,30 @@ void CreateBD_GUI::create_objects() add_subwindow(scale); scale->create_objects(); y += standard->get_h() + pady/2; - need_deinterlace = new CreateBD_Deinterlace(this, x, y); + x1 = x; int y1 = y; + need_deinterlace = new CreateBD_Deinterlace(this, x1, y); add_subwindow(need_deinterlace); - x1 = x + 170; //, x2 = x1 + 150; - need_inverse_telecine = new CreateBD_InverseTelecine(this, x1, y); - add_subwindow(need_inverse_telecine); y += need_deinterlace->get_h() + pady/2; - need_histogram = new CreateBD_Histogram(this, x, y); + need_histogram = new CreateBD_Histogram(this, x1, y); add_subwindow(need_histogram); - need_wide_audio = new CreateBD_WideAudio(this, x1, y); - add_subwindow(need_wide_audio); y += need_histogram->get_h() + pady/2; - non_standard = new BC_Title(x, y+5, "", MEDIUMFONT, RED); + non_standard = new BC_Title(x1, y+5, "", MEDIUMFONT, RED); add_subwindow(non_standard); + x1 += 160; y = y1; + need_inverse_telecine = new CreateBD_InverseTelecine(this, x1, y); + add_subwindow(need_inverse_telecine); + y += need_inverse_telecine->get_h() + pady/2; + need_wide_audio = new CreateBD_WideAudio(this, x1, y); + add_subwindow(need_wide_audio); + y += need_wide_audio->get_h() + pady/2; need_resize_tracks = new CreateBD_ResizeTracks(this, x1, y); add_subwindow(need_resize_tracks); -// need_label_chapters = new CreateBD_LabelChapters(this, x2, y); -// add_subwindow(need_label_chapters); + x1 += 160; y = y1; + need_labeled = new CreateBD_LabelChapters(this, x1, y); + add_subwindow(need_labeled); + y += need_labeled->get_h() + pady/2; + need_farmed = new CreateBD_UseRenderFarm(this, x1, y); + add_subwindow(need_farmed); ok_w = BC_OKButton::calculate_w(); ok_h = BC_OKButton::calculate_h(); ok_x = 10; @@ -827,7 +858,8 @@ void CreateBD_GUI::update() need_resize_tracks->set_value(thread->use_resize_tracks); need_histogram->set_value(thread->use_histogram); need_wide_audio->set_value(thread->use_wide_audio); -// need_label_chapters->set_value(thread->use_label_chapters); + need_labeled->set_value(thread->use_labeled); + need_farmed->set_value(thread->use_farmed); } int CreateBD_Thread:: @@ -875,7 +907,8 @@ option_presets() use_scale = Rescale::none; use_resize_tracks = 0; use_wide_audio = 0; - use_label_chapters = 0; + use_labeled = 0; + use_farmed = 0; if( !mwindow->edl ) return 1; @@ -943,8 +976,6 @@ option_presets() } } if( !has_deinterlace && max_h > 2*bd_height ) use_deinterlace = 1; - // Labels *labels = mwindow->edl->labels; - // use_label_chapters = labels && labels->first ? 1 : 0; if( tracks->recordable_audio_tracks() == BD_WIDE_CHANNELS ) use_wide_audio = 1; diff --git a/cinelerra-5.1/cinelerra/bdcreate.h b/cinelerra-5.1/cinelerra/bdcreate.h index f69ee1aa..89ee83bb 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.h +++ b/cinelerra-5.1/cinelerra/bdcreate.h @@ -24,6 +24,14 @@ public: MWindow *mwindow; }; +class BD_BatchRenderJob : public BatchRenderJob +{ +public: + static int get_udfs_mount(char *udfs, char *mopts, char *mntpt); + BD_BatchRenderJob(Preferences *preferences, int labeled, int farmed); + char *create_script(EDL *edl, ArrayList *idxbls); +}; + class CreateBD_Thread : public BC_DialogThread { @@ -34,13 +42,13 @@ class CreateBD_Thread : public BC_DialogThread static const int BD_MAX_BITRATE, BD_CHANNELS, BD_WIDE_CHANNELS; static const double BD_FRAMERATE, BD_SAMPLERATE, BD_KAUDIO_RATE; static const int BD_INTERLACE_MODE; - static int get_udfs_mount(char *udfs, char *mopts, char *mntpt); public: CreateBD_Thread(MWindow *mwindow); ~CreateBD_Thread(); void handle_close_event(int result); BC_Window* new_gui(); int option_presets(); + int create_bd_script(const char *path, EDL *edl); int create_bd_jobs(ArrayList *jobs, const char *asset_dir); int insert_video_plugin(const char *title, KeyFrame *default_keyframe); int resize_tracks(); @@ -51,8 +59,8 @@ public: char tmp_path[BCTEXTLEN]; int use_deinterlace, use_inverse_telecine; int use_scale, use_resize_tracks; - int use_wide_audio; - int use_histogram, use_label_chapters; + int use_wide_audio, use_farmed; + int use_histogram, use_labeled; int use_standard; int64_t bd_size; @@ -169,6 +177,16 @@ public: CreateBD_GUI *gui; }; +class CreateBD_UseRenderFarm : public BC_CheckBox +{ +public: + CreateBD_UseRenderFarm(CreateBD_GUI *gui, int x, int y); + ~CreateBD_UseRenderFarm(); + + CreateBD_GUI *gui; +}; + + class CreateBD_WideAudio : public BC_CheckBox { public: @@ -208,7 +226,8 @@ public: CreateBD_Histogram *need_histogram; BC_Title *non_standard; CreateBD_WideAudio *need_wide_audio; - CreateBD_LabelChapters *need_label_chapters; + CreateBD_LabelChapters *need_labeled; + CreateBD_UseRenderFarm *need_farmed; int ok_x, ok_y, ok_w, ok_h; CreateBD_OK *ok; int cancel_x, cancel_y, cancel_w, cancel_h; diff --git a/cinelerra-5.1/cinelerra/dvdcreate.C b/cinelerra-5.1/cinelerra/dvdcreate.C index 1014baf5..3e69b52d 100644 --- a/cinelerra-5.1/cinelerra/dvdcreate.C +++ b/cinelerra-5.1/cinelerra/dvdcreate.C @@ -96,6 +96,164 @@ int CreateDVD_MenuItem::handle_event() } +DVD_BatchRenderJob::DVD_BatchRenderJob(Preferences *preferences, + int labeled, int farmed, int standard, int muxed) + : BatchRenderJob("DVD_JOB", preferences, labeled, farmed) +{ + this->standard = standard; + this->muxed = muxed; + + chapter = -1; + edl = 0; + fp =0; +} + +void DVD_BatchRenderJob::copy_from(DVD_BatchRenderJob *src) +{ + standard = src->standard; + muxed = src->muxed; + BatchRenderJob::copy_from(src); +} + +DVD_BatchRenderJob *DVD_BatchRenderJob::copy() +{ + DVD_BatchRenderJob *t = new DVD_BatchRenderJob(preferences, + labeled, farmed, standard, muxed); + t->copy_from(this); + return t; +} + +void DVD_BatchRenderJob::load(FileXML *file) +{ + standard = file->tag.get_property("STANDARD", standard); + muxed = file->tag.get_property("MUXED", muxed); + BatchRenderJob::load(file); +} + +void DVD_BatchRenderJob::save(FileXML *file) +{ + file->tag.set_property("STANDARD", standard); + file->tag.set_property("MUXED", muxed); + BatchRenderJob::save(file); +} + +void DVD_BatchRenderJob::create_chapter(double pos) +{ + fprintf(fp,"%s", !chapter++? "\" chapters=\"" : ","); + int secs = pos, mins = secs/60; + int frms = (pos-secs) * edl->session->frame_rate; + fprintf(fp,"%d:%02d:%02d.%d", mins/60, mins%60, secs%60, frms); +} + +char *DVD_BatchRenderJob::create_script(EDL *edl, ArrayList *idxbls) +{ + char script[BCTEXTLEN]; + strcpy(script, edl_path); + this->edl = edl; + this->fp = 0; + char *bp = strrchr(script,'/'); + int fd = -1; + if( bp ) { + strcpy(bp, "/dvd.sh"); + fd = open(script, O_WRONLY+O_CREAT+O_TRUNC, 0755); + } + if( fd >= 0 ) + fp = fdopen(fd, "w"); + if( !fp ) { + char err[BCTEXTLEN], msg[BCTEXTLEN]; + strerror_r(errno, err, sizeof(err)); + sprintf(msg, _("Unable to save: %s\n-- %s"), script, err); + MainError::show_error(msg); + return 0; + } + + fprintf(fp,"#!/bin/bash\n"); + fprintf(fp,"dir=`dirname $0`\n"); + fprintf(fp,"echo \"running %s\"\n", script); + fprintf(fp,"\n"); + const char *exec_path = File::get_cinlib_path(); + fprintf(fp,"PATH=$PATH:%s\n",exec_path); + int file_seq = farmed || labeled ? 1 : 0; + if( !muxed ) { + if( file_seq ) { + fprintf(fp, "cat > $dir/dvd.m2v $dir/dvd.m2v0*\n"); + fprintf(fp, "mplex -M -f 8 -o $dir/dvd.mpg $dir/dvd.m2v $dir/dvd.ac3\n"); + file_seq = 0; + } + else + fprintf(fp, "mplex -f 8 -o $dir/dvd.mpg $dir/dvd.m2v $dir/dvd.ac3\n"); + } + fprintf(fp,"rm -rf $dir/iso\n"); + fprintf(fp,"mkdir -p $dir/iso\n"); + fprintf(fp,"\n"); +// dvdauthor ver 0.7.0 requires this to work + int norm = dvd_formats[standard].norm; + const char *name = dvd_norms[norm].name; + fprintf(fp,"export VIDEO_FORMAT=%s\n", name); + fprintf(fp,"dvdauthor -x - <\n"); + fprintf(fp," \n"); + fprintf(fp," jump title 1; \n"); + fprintf(fp," \n"); + fprintf(fp," \n"); + fprintf(fp," \n"); + char std[BCSTRLEN], *cp = std; + for( const char *np=name; *np!=0; ++cp,++np) *cp = *np + 'a'-'A'; + *cp = 0; + EDLSession *session = edl->session; + fprintf(fp," \n"); + fprintf(fp," \n"); + fprintf(fp,"\n"); + fprintf(fp,"eof\n"); + fprintf(fp,"\n"); + fprintf(fp,"echo To burn dvd, load blank media and run:\n"); + fprintf(fp,"echo growisofs -dvd-compat -Z /dev/dvd -dvd-video $dir/iso\n"); + fprintf(fp,"kill $$\n"); + fprintf(fp,"\n"); + fclose(fp); + return cstrdup(script); +} + + CreateDVD_Thread::CreateDVD_Thread(MWindow *mwindow) : BC_DialogThread() { @@ -108,7 +266,8 @@ CreateDVD_Thread::CreateDVD_Thread(MWindow *mwindow) this->use_wide_audio = 0; this->use_ffmpeg = 0; this->use_resize_tracks = 0; - this->use_label_chapters = 0; + this->use_labeled = 0; + this->use_farmed = 0; this->dvd_size = DVD_SIZE; this->dvd_width = DVD_WIDTH; @@ -137,7 +296,6 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, const ch return 1; } EDLSession *session = edl->session; - double total_length = edl->tracks->total_length(); if( total_length <= 0 ) { char msg[BCTEXTLEN]; @@ -168,88 +326,6 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, const ch session->audio_channels = session->audio_tracks = use_wide_audio ? DVD_WIDE_CHANNELS : DVD_CHANNELS; - char script_filename[BCTEXTLEN]; - sprintf(script_filename, "%s/dvd.sh", asset_dir); - int fd = open(script_filename, O_WRONLY+O_CREAT+O_TRUNC, 0755); - FILE *fp = fdopen(fd, "w"); - if( !fp ) { - char err[BCTEXTLEN], msg[BCTEXTLEN]; - strerror_r(errno, err, sizeof(err)); - sprintf(msg, _("Unable to save: %s\n-- %s"), script_filename, err); - MainError::show_error(msg); - return 1; - } - fprintf(fp,"#!/bin/bash\n"); - fprintf(fp,"echo \"running %s\" $# $*\n", script_filename); - fprintf(fp,"\n"); - const char *exec_path = File::get_cinlib_path(); - fprintf(fp,"PATH=$PATH:%s\n",exec_path); - if( mwindow->preferences->use_renderfarm || - (use_label_chapters && edl->labels ) ) { - if( !use_ffmpeg ) { - fprintf(fp, "cat > $1/dvd.m2v $1/dvd.m2v0*\n"); - fprintf(fp, "mplex -M -f 8 -o $1/dvd.mpg $1/dvd.m2v $1/dvd.ac3\n"); - } - else - fprintf(fp, "ffmpeg -f concat -safe 0 -i <(for f in \"$1/dvd.mpg0\"*; do " - "echo \"file '$f'\"; done) -c copy -y $1/dvd.mpg\n"); - } - else - fprintf(fp, "mplex -f 8 -o $1/dvd.mpg $1/dvd.m2v $1/dvd.ac3\n"); - fprintf(fp,"rm -rf $1/iso\n"); - fprintf(fp,"mkdir -p $1/iso\n"); - fprintf(fp,"\n"); -// dvdauthor ver 0.7.0 requires this to work - int norm = dvd_formats[use_standard].norm; - const char *name = dvd_norms[norm].name; - fprintf(fp,"export VIDEO_FORMAT=%s\n", name); - fprintf(fp,"dvdauthor -x - <\n"); - fprintf(fp," \n"); - fprintf(fp," jump title 1; \n"); - fprintf(fp," \n"); - fprintf(fp," \n"); - fprintf(fp," \n"); - char std[BCSTRLEN], *cp = std; - for( const char *np=name; *np!=0; ++cp,++np) *cp = *np + 'a'-'A'; - *cp = 0; - fprintf(fp," \n"); - fprintf(fp," \n"); - fprintf(fp,"\n"); - fprintf(fp,"eof\n"); - fprintf(fp,"\n"); - fprintf(fp,"echo To burn dvd, load blank media and run:\n"); - fprintf(fp,"echo growisofs -dvd-compat -Z /dev/dvd -dvd-video $1/iso\n"); - fprintf(fp,"kill $$\n"); - fprintf(fp,"\n"); - fclose(fp); - session->audio_channels = session->audio_tracks = !use_wide_audio ? DVD_CHANNELS : DVD_WIDE_CHANNELS; for( int i=0; i *jobs, const ch return 1; } - BatchRenderJob *job = new BatchRenderJob(mwindow->preferences, use_label_chapters); + BatchRenderJob *job = new DVD_BatchRenderJob(mwindow->preferences, + use_labeled, use_farmed, use_standard, use_ffmpeg); jobs->append(job); strcpy(&job->edl_path[0], xml_filename); Asset *asset = job->asset; @@ -302,6 +379,8 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, const ch strcpy(asset->fformat, "dvd"); asset->audio_data = 1; + asset->channels = session->audio_channels; + asset->sample_rate = session->sample_rate; strcpy(asset->acodec, "dvd.dvd"); FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec); FFMPEG::load_options(option_path, asset->ff_audio_options, @@ -315,6 +394,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, const ch sizeof(asset->ff_video_options)); asset->ff_video_bitrate = vid_bitrate; asset->ff_video_quality = -1; + use_farmed = job->farmed; } else { sprintf(&asset->path[0],"%s/dvd.m2v", asset_dir); @@ -332,6 +412,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, const ch asset->vmpeg_preset = 8; asset->vmpeg_field_order = 0; asset->vmpeg_pframe_distance = 0; + use_farmed = job->farmed; job = new BatchRenderJob(mwindow->preferences, 0, 0); jobs->append(job); strcpy(&job->edl_path[0], xml_filename); @@ -350,12 +431,6 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, const ch asset->ac3_bitrate = dvd_kaudio_rate; } - job = new BatchRenderJob(mwindow->preferences, 0, 0); - jobs->append(job); - job->edl_path[0] = '@'; - strcpy(&job->edl_path[1], script_filename); - strcpy(&job->asset->path[0], asset_dir); - return 0; } @@ -444,7 +519,7 @@ void CreateDVD_Thread::handle_close_event(int result) mwindow->resync_guis(); if( ret ) return; mwindow->batch_render->save_jobs(); - mwindow->batch_render->start(); + mwindow->batch_render->start(-use_farmed, -use_labeled); } BC_Window* CreateDVD_Thread::new_gui() @@ -464,7 +539,8 @@ BC_Window* CreateDVD_Thread::new_gui() use_wide_audio = 0; use_ffmpeg = 0; use_resize_tracks = 0; - use_label_chapters = 0; + use_labeled = 0; + use_farmed = 0; use_standard = DVD_NTSC_4x3; dvd_size = DVD_SIZE; @@ -705,7 +781,7 @@ CreateDVD_Histogram::~CreateDVD_Histogram() } CreateDVD_LabelChapters::CreateDVD_LabelChapters(CreateDVD_GUI *gui, int x, int y) - : BC_CheckBox(x, y, &gui->thread->use_label_chapters, _("Chapters at Labels")) + : BC_CheckBox(x, y, &gui->thread->use_labeled, _("Chapters at Labels")) { this->gui = gui; } @@ -714,6 +790,16 @@ CreateDVD_LabelChapters::~CreateDVD_LabelChapters() { } +CreateDVD_UseRenderFarm::CreateDVD_UseRenderFarm(CreateDVD_GUI *gui, int x, int y) + : BC_CheckBox(x, y, &gui->thread->use_farmed, _("Use render farm")) +{ + this->gui = gui; +} + +CreateDVD_UseRenderFarm::~CreateDVD_UseRenderFarm() +{ +} + CreateDVD_WideAudio::CreateDVD_WideAudio(CreateDVD_GUI *gui, int x, int y) : BC_CheckBox(x, y, &gui->thread->use_wide_audio, _("Audio 5.1")) { @@ -755,7 +841,8 @@ CreateDVD_GUI::CreateDVD_GUI(CreateDVD_Thread *thread, int x, int y, int w, int need_resize_tracks = 0; need_histogram = 0; need_wide_audio = 0; - need_label_chapters = 0; + need_labeled = 0; + need_farmed = 0; ok = 0; cancel = 0; } @@ -813,24 +900,30 @@ void CreateDVD_GUI::create_objects() add_subwindow(scale); scale->create_objects(); y += standard->get_h() + pady/2; - need_deinterlace = new CreateDVD_Deinterlace(this, x, y); + x1 = x; int y1 = y; + need_deinterlace = new CreateDVD_Deinterlace(this, x1, y); add_subwindow(need_deinterlace); - x1 = x + 170; - int x2 = x1 + 170; - need_inverse_telecine = new CreateDVD_InverseTelecine(this, x1, y); - add_subwindow(need_inverse_telecine); - need_use_ffmpeg = new CreateDVD_UseFFMpeg(this, x2, y); - add_subwindow(need_use_ffmpeg); y += need_deinterlace->get_h() + pady/2; need_histogram = new CreateDVD_Histogram(this, x, y); add_subwindow(need_histogram); + y = y1; x1 += 170; + need_inverse_telecine = new CreateDVD_InverseTelecine(this, x1, y); + add_subwindow(need_inverse_telecine); + y += need_inverse_telecine->get_h() + pady/2; need_wide_audio = new CreateDVD_WideAudio(this, x1, y); add_subwindow(need_wide_audio); - need_resize_tracks = new CreateDVD_ResizeTracks(this, x2, y); + y += need_wide_audio->get_h() + pady/2; + need_use_ffmpeg = new CreateDVD_UseFFMpeg(this, x1, y); + add_subwindow(need_use_ffmpeg); + y += need_use_ffmpeg->get_h() + pady/2; + need_resize_tracks = new CreateDVD_ResizeTracks(this, x1, y); add_subwindow(need_resize_tracks); - y += need_histogram->get_h() + pady/2; - need_label_chapters = new CreateDVD_LabelChapters(this, x1, y); - add_subwindow(need_label_chapters); + y = y1; x1 += 170; + need_labeled = new CreateDVD_LabelChapters(this, x1, y); + add_subwindow(need_labeled); + y += need_labeled->get_h() + pady/2; + need_farmed = new CreateDVD_UseRenderFarm(this, x1, y); + add_subwindow(need_farmed); ok_w = BC_OKButton::calculate_w(); ok_h = BC_OKButton::calculate_h(); ok_x = 10; @@ -880,7 +973,8 @@ void CreateDVD_GUI::update() need_resize_tracks->set_value(thread->use_resize_tracks); need_histogram->set_value(thread->use_histogram); need_wide_audio->set_value(thread->use_wide_audio); - need_label_chapters->set_value(thread->use_label_chapters); + need_labeled->set_value(thread->use_labeled); + need_farmed->set_value(thread->use_farmed); } int CreateDVD_Thread:: @@ -928,7 +1022,8 @@ option_presets() use_scale = Rescale::none; use_resize_tracks = 0; use_wide_audio = 0; - use_label_chapters = 0; + use_labeled = 0; + use_farmed = 0; if( !mwindow->edl ) return 1; @@ -994,11 +1089,12 @@ option_presets() } if( !has_deinterlace && max_h > 2*dvd_height ) use_deinterlace = 1; Labels *labels = mwindow->edl->labels; - use_label_chapters = labels && labels->first ? 1 : 0; + use_labeled = labels && labels->first ? 1 : 0; if( tracks->recordable_audio_tracks() == DVD_WIDE_CHANNELS ) use_wide_audio = 1; + use_farmed = mwindow->preferences->use_renderfarm; return 0; } diff --git a/cinelerra-5.1/cinelerra/dvdcreate.h b/cinelerra-5.1/cinelerra/dvdcreate.h index cfb9b00b..3c39ea15 100644 --- a/cinelerra-5.1/cinelerra/dvdcreate.h +++ b/cinelerra-5.1/cinelerra/dvdcreate.h @@ -23,6 +23,24 @@ public: MWindow *mwindow; }; +class DVD_BatchRenderJob : public BatchRenderJob +{ + int chapter; + FILE *fp; + EDL *edl; +public: + DVD_BatchRenderJob(Preferences *preferences, + int labeled, int farmed, int standard, int muxed); + void copy_from(DVD_BatchRenderJob *src); + DVD_BatchRenderJob *copy(); + void load(FileXML *file); + void save(FileXML *file); + char *create_script(EDL *edl, ArrayList *idxbls); + void create_chapter(double pos); + + int standard; + int muxed; +}; class CreateDVD_Thread : public BC_DialogThread { @@ -38,6 +56,8 @@ public: void handle_close_event(int result); BC_Window* new_gui(); int option_presets(); + void create_chapter(FILE *fp, double pos); + static int create_dvd_script(BatchRenderJob *job); int create_dvd_jobs(ArrayList *jobs, const char *asset_path); int insert_video_plugin(const char *title, KeyFrame *default_keyframe); int resize_tracks(); @@ -48,8 +68,8 @@ public: char tmp_path[BCTEXTLEN]; int use_deinterlace, use_inverse_telecine; int use_scale, use_resize_tracks; - int use_wide_audio; - int use_histogram, use_label_chapters; + int use_wide_audio, use_farmed; + int use_histogram, use_labeled; int use_ffmpeg, use_standard; int64_t dvd_size; @@ -165,6 +185,15 @@ public: CreateDVD_GUI *gui; }; +class CreateDVD_UseRenderFarm : public BC_CheckBox +{ +public: + CreateDVD_UseRenderFarm(CreateDVD_GUI *gui, int x, int y); + ~CreateDVD_UseRenderFarm(); + + CreateDVD_GUI *gui; +}; + class CreateDVD_WideAudio : public BC_CheckBox { public: @@ -213,7 +242,8 @@ public: CreateDVD_ResizeTracks *need_resize_tracks; CreateDVD_Histogram *need_histogram; CreateDVD_WideAudio *need_wide_audio; - CreateDVD_LabelChapters *need_label_chapters; + CreateDVD_LabelChapters *need_labeled; + CreateDVD_UseRenderFarm *need_farmed; int ok_x, ok_y, ok_w, ok_h; CreateDVD_OK *ok; int cancel_x, cancel_y, cancel_w, cancel_h; diff --git a/cinelerra-5.1/cinelerra/dvdcreate.inc b/cinelerra-5.1/cinelerra/dvdcreate.inc index 79927a6d..0e26dc31 100644 --- a/cinelerra-5.1/cinelerra/dvdcreate.inc +++ b/cinelerra-5.1/cinelerra/dvdcreate.inc @@ -35,6 +35,7 @@ class CreateDVD_Scale; class CreateDVD_ResizeTracks; class CreateDVD_Histogram; class CreateDVD_LabelChapters; +class CreateDVD_UseRenderFarm; class CreateDVD_WideAudio; class CreateDVD_WideAspect; class CreateDVD_UseFFMpeg; diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C index f611b814..ad8cf7fc 100644 --- a/cinelerra-5.1/cinelerra/file.C +++ b/cinelerra-5.1/cinelerra/file.C @@ -657,17 +657,10 @@ void File::delete_temp_frame_buffer() int File::close_file(int ignore_thread) { - const int debug = 0; - - if( debug ) printf("File::close_file file=%p %d\n", file, __LINE__); - if( !ignore_thread ) { stop_audio_thread(); stop_video_thread(); } - - - if( debug ) printf("File::close_file file=%p %d\n", file, __LINE__); if( file ) { // The file's asset is a copy of the argument passed to open_file so the // user must copy lengths from the file's asset. @@ -679,28 +672,18 @@ int File::close_file(int ignore_thread) file->close_file(); delete file; } - if( debug ) printf("File::close_file file=%p %d\n", file, __LINE__); delete_temp_samples_buffer(); delete_temp_frame_buffer(); - if( debug ) printf("File::close_file file=%p %d\n", file, __LINE__); - - if( debug ) printf("File::close_file file=%p %d\n", file, __LINE__); - reset_parameters(); - if( debug ) printf("File::close_file file=%p %d\n", file, __LINE__); return 0; } - - int File::get_index(IndexFile *index_file, MainProgressBar *progress_bar) { return !file ? -1 : file->get_index(index_file, progress_bar); } - - int File::start_audio_thread(int buffer_size, int ring_buffers) { this->audio_ring_buffers = ring_buffers; @@ -713,20 +696,16 @@ int File::start_audio_thread(int buffer_size, int ring_buffers) return 0; } -int File::start_video_thread(int buffer_size, - int color_model, - int ring_buffers, - int compressed) +int File::start_video_thread(int buffer_size, int color_model, + int ring_buffers, int compressed) { this->video_ring_buffers = ring_buffers; this->video_buffer_size = buffer_size; if( !video_thread ) { video_thread = new FileThread(this, 0, 1); - video_thread->start_writing(buffer_size, - color_model, - ring_buffers, - compressed); + video_thread->start_writing(buffer_size, color_model, + ring_buffers, compressed); } return 0; } diff --git a/cinelerra-5.1/cinelerra/main.C b/cinelerra-5.1/cinelerra/main.C index f422092e..6f4ee2e1 100644 --- a/cinelerra-5.1/cinelerra/main.C +++ b/cinelerra-5.1/cinelerra/main.C @@ -310,7 +310,7 @@ int main(int argc, char *argv[]) break; } case DO_BATCHRENDER: { - BatchRenderThread *thread = new BatchRenderThread; + BatchRenderThread *thread = new BatchRenderThread(0); thread->start_rendering(config_path, batch_path); break; } diff --git a/cinelerra-5.1/cinelerra/packagedispatcher.C b/cinelerra-5.1/cinelerra/packagedispatcher.C index 9b5864d8..f6d69734 100644 --- a/cinelerra-5.1/cinelerra/packagedispatcher.C +++ b/cinelerra-5.1/cinelerra/packagedispatcher.C @@ -55,15 +55,11 @@ PackageDispatcher::~PackageDispatcher() delete package_lock; } -int PackageDispatcher::create_packages(MWindow *mwindow, - EDL *edl, - Preferences *preferences, - int strategy, - Asset *default_asset, - double total_start, - double total_end, - int test_overwrite) +int PackageDispatcher::create_packages(MWindow *mwindow, EDL *edl, + Preferences *preferences, int strategy, Asset *default_asset, + double total_start, double total_end, int test_overwrite) { + Label *label; int result = 0; this->mwindow = mwindow; @@ -87,10 +83,8 @@ int PackageDispatcher::create_packages(MWindow *mwindow, // total_end, // default_asset->frame_rate); - - - if(strategy == SINGLE_PASS) - { + switch( strategy ) { + case SINGLE_PASS: total_len = this->total_end - this->total_start; package_len = total_len; min_package_len = total_len; @@ -105,88 +99,63 @@ int PackageDispatcher::create_packages(MWindow *mwindow, packages[0]->audio_do = default_asset->audio_data; packages[0]->video_do = default_asset->video_data; strcpy(packages[0]->path, default_asset->path); - } - else - if(strategy == SINGLE_PASS_FARM) - { + break; + case SINGLE_PASS_FARM: packaging_engine = File::new_packaging_engine(default_asset); - packaging_engine->create_packages_single_farm( - edl, - preferences, - default_asset, - total_start, - total_end); - } - else - if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM) - { - Label *label = edl->labels->first; + packaging_engine->create_packages_single_farm(edl, preferences, + default_asset, total_start, total_end); + break; + case FILE_PER_LABEL: + case FILE_PER_LABEL_FARM: + label = edl->labels->first; total_packages = 0; packages = new RenderPackage*[edl->labels->total() + 2]; Render::get_starting_number(default_asset->path, - current_number, - number_start, - total_digits, - 2); - - while(audio_position < audio_end) - { - RenderPackage *package = - packages[total_packages] = - new RenderPackage; + current_number, number_start, total_digits, 3); + + while( audio_position < audio_end ) { + RenderPackage *package = new RenderPackage; + packages[total_packages++] = package; package->audio_start = audio_position; package->video_start = video_position; package->audio_do = default_asset->audio_data; package->video_do = default_asset->video_data; - - while(label && + while( label && (label->position < (double)audio_position / default_asset->sample_rate || - EQUIV(label->position, (double)audio_position / default_asset->sample_rate))) - { + EQUIV(label->position, (double)audio_position / default_asset->sample_rate)) ) { label = label->next; } - if(!label) - { + if( !label ) { package->audio_end = Units::to_int64(total_end * default_asset->sample_rate); package->video_end = Units::to_int64(total_end * default_asset->frame_rate); } - else - { + else { package->audio_end = Units::to_int64(label->position * default_asset->sample_rate); package->video_end = Units::to_int64(label->position * default_asset->frame_rate); } - if(package->audio_end > audio_end) - { + if( package->audio_end > audio_end ) { package->audio_end = audio_end; } - if(package->video_end > video_end) - { + if( package->video_end > video_end ) { package->video_end = video_end; } audio_position = package->audio_end; video_position = package->video_end; + // Create file number differently if image file sequence - Render::create_filename(package->path, - default_asset->path, - current_number, - total_digits, - number_start); - current_number++; - - total_packages++; + Render::create_filename(package->path, default_asset->path, + current_number++, total_digits, number_start); } total_allocated = total_packages; - } - else - if(strategy == BRENDER_FARM) - { + break; + case BRENDER_FARM: total_len = this->total_end - this->total_start; // Create packages as they're requested. @@ -195,31 +164,24 @@ int PackageDispatcher::create_packages(MWindow *mwindow, packages = 0; Render::get_starting_number(default_asset->path, - current_number, - number_start, - total_digits, - 6); + current_number, number_start, total_digits, 6); // Master node only - if(preferences->renderfarm_nodes.total == 1) - { + if( preferences->renderfarm_nodes.total == 1 ) { package_len = total_len; min_package_len = total_len; } - else - { + else { package_len = preferences->brender_fragment / edl->session->frame_rate; min_package_len = 1.0 / edl->session->frame_rate; } + break; } // Test existence of every output file. // Only if this isn't a background render or non interactive. - if(strategy != BRENDER_FARM && - test_overwrite && - mwindow) - { + if( strategy != BRENDER_FARM && test_overwrite && mwindow ) { ArrayList paths; get_package_paths(&paths); result = ConfirmSave::test_files(mwindow, &paths); @@ -233,9 +195,8 @@ void PackageDispatcher::get_package_paths(ArrayList *path_list) { if (strategy == SINGLE_PASS_FARM) packaging_engine->get_package_paths(path_list); - else - { - for(int i = 0; i < total_allocated; i++) + else { + for( int i=0; iappend(strdup(packages[i]->path)); path_list->set_free(); } @@ -243,72 +204,44 @@ void PackageDispatcher::get_package_paths(ArrayList *path_list) } RenderPackage* PackageDispatcher::get_package(double frames_per_second, - int client_number, - int use_local_rate) + int client_number, int use_local_rate) { - const int debug = 0; package_lock->lock("PackageDispatcher::get_package"); - if(debug) printf("PackageDispatcher::get_package %d %f %d %d\n", - __LINE__, - frames_per_second, - client_number, - use_local_rate); - // Store new frames per second for the node - if(!EQUIV(frames_per_second, 0)) - { + if( !EQUIV(frames_per_second, 0) ) { preferences->set_rate(frames_per_second, client_number); if(mwindow) mwindow->preferences->copy_rates_from(preferences); } - else + else { // Use previous frames per second - { frames_per_second = preferences->get_rate(client_number); } - if(debug) printf("PackageDispatcher::get_package %d %f %d %d\n", - __LINE__, - frames_per_second, - client_number, - use_local_rate); - float avg_frames_per_second = preferences->get_avg_rate(use_local_rate); RenderPackage *result = 0; + switch( strategy ) { //printf("PackageDispatcher::get_package 1 %d\n", strategy); - if(strategy == SINGLE_PASS || - strategy == FILE_PER_LABEL || - strategy == FILE_PER_LABEL_FARM) - { - if(current_package < total_packages) - { - result = packages[current_package]; - current_package++; - } - } - else - if(strategy == SINGLE_PASS_FARM) - { + case SINGLE_PASS: + case FILE_PER_LABEL: + case FILE_PER_LABEL_FARM: + if( current_package < total_packages ) + result = packages[current_package++]; + break; + case SINGLE_PASS_FARM: result = packaging_engine->get_package_single_farm(frames_per_second, - client_number, - use_local_rate); - } - else - if(strategy == BRENDER_FARM) - { + client_number, use_local_rate); + break; + case BRENDER_FARM: //printf("Dispatcher::get_package 1 %d %d\n", video_position, video_end); - if(video_position < video_end) - { + if( video_position < video_end ) { // Allocate new packages - if(total_packages == 0) - { + if( total_packages == 0 ) { total_allocated = 256; packages = new RenderPackage*[total_allocated]; } - else - if(total_packages >= total_allocated) - { + else if( total_packages >= total_allocated ) { RenderPackage **old_packages = packages; total_allocated *= 2; packages = new RenderPackage*[total_allocated]; @@ -323,17 +256,14 @@ RenderPackage* PackageDispatcher::get_package(double frames_per_second, double scaled_len; // No load balancing data exists - if(EQUIV(frames_per_second, 0) || - EQUIV(avg_frames_per_second, 0)) - { + if( EQUIV(frames_per_second, 0) || + EQUIV(avg_frames_per_second, 0)) { scaled_len = package_len; } - else + else { // Load balancing data exists - { scaled_len = package_len * - frames_per_second / - avg_frames_per_second; + frames_per_second / avg_frames_per_second; } scaled_len = MAX(scaled_len, min_package_len); @@ -353,58 +283,43 @@ RenderPackage* PackageDispatcher::get_package(double frames_per_second, // The frame numbers are read from the vframe objects themselves. - Render::create_filename(result->path, - default_asset->path, - 0, - total_digits, - number_start); + Render::create_filename(result->path, default_asset->path, + 0, total_digits, number_start); //printf("PackageDispatcher::get_package 2 %s\n", result->path); - - current_number++; - total_packages++; - current_package++; + ++current_number; + ++total_packages; + ++current_package; } + break; } package_lock->unlock(); - - if(debug && result) printf("PackageDispatcher::get_package %d %ld\n", __LINE__, (long)(result->video_end - result->video_start)); return result; } -ArrayList* PackageDispatcher::get_asset_list() +int PackageDispatcher::get_asset_list(ArrayList &idxbls) { - ArrayList *assets = new ArrayList; - -const int debug = 0; -if(debug) printf("PackageDispatcher::get_asset_list %d\n", __LINE__); -if(debug) default_asset->dump(); - for(int i = 0; i < current_package; i++) - { + if( strategy == SINGLE_PASS_FARM ) + return packaging_engine->get_asset_list(idxbls); + for( int i=0; icopy_from(default_asset, 1); strcpy(asset->path, packages[i]->path); asset->video_length = packages[i]->video_end - packages[i]->video_start; asset->audio_length = packages[i]->audio_end - packages[i]->audio_start; - assets->append(asset); -if(debug) printf("PackageDispatcher::get_asset_list %d\n", __LINE__); -if(debug) asset->dump(); + idxbls.append(asset); } - - return assets; + return current_package; } int64_t PackageDispatcher::get_progress_max() { - if (strategy == SINGLE_PASS_FARM) - return packaging_engine->get_progress_max(); - else - return Units::to_int64(default_asset->sample_rate * - (total_end - total_start)) + + return strategy == SINGLE_PASS_FARM ? + packaging_engine->get_progress_max() : + Units::to_int64(default_asset->sample_rate * (total_end - total_start)) + Units::to_int64(preferences->render_preroll * - total_allocated * - default_asset->sample_rate); + total_allocated * default_asset->sample_rate); } int PackageDispatcher::get_total_packages() @@ -414,7 +329,6 @@ int PackageDispatcher::get_total_packages() int PackageDispatcher::packages_are_done() { - if (packaging_engine) - return packaging_engine->packages_are_done(); - return 0; + return packaging_engine ? packaging_engine->packages_are_done() : 0; } + diff --git a/cinelerra-5.1/cinelerra/packagedispatcher.h b/cinelerra-5.1/cinelerra/packagedispatcher.h index a8bea73b..e548ce5b 100644 --- a/cinelerra-5.1/cinelerra/packagedispatcher.h +++ b/cinelerra-5.1/cinelerra/packagedispatcher.h @@ -56,11 +56,10 @@ public: RenderPackage* get_package(double frames_per_second, int client_number, int use_local_rate); -// Return a new asset list of what was rendered. You must delete the return -// value with Garbage::remove_user for each member of the list & delete for -// the list. - ArrayList* get_asset_list(); +// Return a new path list of what was rendered. void get_package_paths(ArrayList *path_list); +// Return a new asset list of what was rendered. + int get_asset_list(ArrayList &idxbls); RenderPackage* get_package(int number); int get_total_packages(); diff --git a/cinelerra-5.1/cinelerra/packagerenderer.C b/cinelerra-5.1/cinelerra/packagerenderer.C index 59d429cc..d60a5be0 100644 --- a/cinelerra-5.1/cinelerra/packagerenderer.C +++ b/cinelerra-5.1/cinelerra/packagerenderer.C @@ -152,7 +152,7 @@ void PackageRenderer::create_output() FileSystem fs; asset = new Asset(*default_asset); - if(!get_master() && preferences->renderfarm_vfs && preferences->use_renderfarm) + if( !get_master() && preferences->renderfarm_vfs && preferences->use_renderfarm ) snprintf(asset->path, sizeof(asset->path), RENDERFARM_FS_PREFIX "%s", package->path); else @@ -162,8 +162,7 @@ void PackageRenderer::create_output() file->set_processors(preferences->processors); result = file->open_file(preferences, asset, 0, 1); - if(result && mwindow) - { + if( result && mwindow ) { // open failed char string[BCTEXTLEN]; snprintf(string, sizeof(string), _("Couldn't open %s"), asset->path); @@ -174,8 +173,7 @@ void PackageRenderer::create_output() error.run_window(); } else - if(mwindow) - { + if( mwindow ) { mwindow->sighandler->push_file(file); IndexFile::delete_index(preferences, asset); } @@ -196,29 +194,25 @@ void PackageRenderer::create_engine() render_engine->set_vcache(video_cache); render_engine->arm_command(command); - if(package->use_brender) - { + if( package->use_brender ) { audio_preroll = Units::to_int64((double)preferences->brender_preroll / default_asset->frame_rate * default_asset->sample_rate); video_preroll = preferences->brender_preroll; } - else - { + else { audio_preroll = Units::to_int64(preferences->render_preroll * default_asset->sample_rate); video_preroll = Units::to_int64(preferences->render_preroll * default_asset->frame_rate); } audio_position = package->audio_start - audio_preroll; - if( audio_position < 0 ) - { + if( audio_position < 0 ) { audio_preroll += audio_position; audio_position = 0; } video_position = package->video_start - video_preroll; - if( video_position < 0 ) - { + if( video_position < 0 ) { video_preroll += video_position; video_position = 0; } @@ -227,16 +221,14 @@ void PackageRenderer::create_engine() // PRINT_TRACE // Create output buffers - if(asset->audio_data) - { + if( asset->audio_data ) { file->start_audio_thread(audio_read_length, preferences->processors > 1 ? 2 : 1); } // PRINT_TRACE - if(asset->video_data) - { + if( asset->video_data ) { compressed_output = new VFrame; // The write length needs to correlate with the processor count because // it is passed to the file handler which usually processes frames simultaneously. @@ -247,8 +239,7 @@ void PackageRenderer::create_engine() //printf("PackageRenderer::create_engine %d video_write_length=%d\n", __LINE__, video_write_length); // starting frames are corrupted if video_write_length > 2. Work around it, for now. - if(video_write_length > 2) - { + if( video_write_length > 2 ) { video_write_length = 2; } file->start_video_thread(video_write_length, @@ -258,8 +249,7 @@ void PackageRenderer::create_engine() //printf("PackageRenderer::create_engine %d\n", __LINE__); - if(mwindow) - { + if( mwindow ) { video_device = new VideoDevice; video_device->open_output(vconfig, command->get_edl()->session->frame_rate, @@ -287,12 +277,10 @@ void PackageRenderer::do_audio() { //printf("PackageRenderer::do_audio %d\n", __LINE__); // Do audio data - if(asset->audio_data) - { + if( asset->audio_data ) { audio_output = file->get_audio_buffer(); // Zero unused channels in output vector - for(int i = 0; i < MAX_CHANNELS; i++) - { + for( int i = 0; i < MAX_CHANNELS; i++ ) { audio_output_ptr[i] = (i < asset->channels) ? audio_output[i] : 0; @@ -310,20 +298,15 @@ void PackageRenderer::do_audio() // Fix buffers for preroll int64_t output_length = audio_read_length; - if(audio_preroll > 0) - { - if(audio_preroll >= output_length) + if( audio_preroll > 0 ) { + if( audio_preroll >= output_length ) output_length = 0; - else - { + else { output_length -= audio_preroll; - for(int i = 0; i < MAX_CHANNELS; i++) - { - if(audio_output_ptr[i]) - { + for( int i = 0; i < MAX_CHANNELS; i++ ) { + if( audio_output_ptr[i] ) { double *data = audio_output_ptr[i]->get_data(); - for(int j = 0; j < output_length; j++) - { + for( int j = 0; j < output_length; j++ ) { data[j] = data[j + audio_read_length - output_length]; } } @@ -345,29 +328,21 @@ void PackageRenderer::do_audio() void PackageRenderer::do_video() { - const int debug = 0; // Do video data - if(asset->video_data) - { + if( asset->video_data ) { // get the absolute video position from the audio position int64_t video_end = video_position + video_read_length; - if(video_end > package->video_end) + if( video_end > package->video_end ) video_end = package->video_end; - while(video_position < video_end && !result) - { + while( !result && video_position < video_end ) { // Try to copy the compressed frame directly from the input to output files -//printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position); - if(direct_frame_copy(command->get_edl(), - video_position, - file, - result)) - { + if( direct_frame_copy(command->get_edl(), + video_position, file, result) ) { // Direct frame copy failed. // Switch back to background compression - if(direct_frame_copying) - { + if( direct_frame_copying ) { file->start_video_thread(video_write_length, command->get_edl()->session->color_model, @@ -380,37 +355,17 @@ void PackageRenderer::do_video() // Try to use the rendering engine to write the frame. // Get a buffer for background writing. - if(video_write_position == 0) + if( video_write_position == 0 ) video_output = file->get_video_buffer(); - - if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output); - if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output[0]); - - - - // Construct layered output buffer video_output_ptr = video_output[0][video_write_position]; - if(debug) - { - printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output_ptr); - printf("PackageRenderer::do_video %d %d\n", __LINE__, result); - video_output_ptr->dump(); - } - if(!result) + if( !result ) result = render_engine->vrender->process_buffer( - video_output_ptr, - video_position, - 0); - - - if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result); - - if(!result && + video_output_ptr, video_position, 0); + if( !result && mwindow && - video_device->output_visible()) - { + video_device->output_visible() ) { // Vector for video device VFrame *preview_output; @@ -422,58 +377,41 @@ void PackageRenderer::do_video() video_device->write_buffer(preview_output, command->get_edl()); } - - if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result); - - // Don't write to file - if(video_preroll && !result) - { + if( video_preroll && !result ) { video_preroll--; // Keep the write position at 0 until ready to write real frames result = file->write_video_buffer(0); video_write_position = 0; } else - if(!result) - { + if( !result ) { // Set background rendering parameters // Allow us to skip sections of the output file by setting the frame number. // Used by background render and render farm. -//printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position); video_output_ptr->set_number(video_position); video_write_position++; - if(video_write_position >= video_write_length) - { + if( video_write_position >= video_write_length ) { result = file->write_video_buffer(video_write_position); -//printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position); // Update the brender map after writing the files. - if(package->use_brender) - { -//printf("PackageRenderer::do_video 10\n"); - for(int i = 0; i < video_write_position && !result; i++) - { + if( package->use_brender ) { + for( int i = 0; i < video_write_position && !result; i++ ) { result = set_video_map(video_position + 1 - video_write_position + i, BRender::RENDERED); } -//printf("PackageRenderer::do_video 11 %d\n", result); } video_write_position = 0; } } -//printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position); - - } video_position++; - if(!result && get_result()) result = 1; - if(!result && progress_cancelled()) result = 1; + if( !result && get_result() ) result = 1; + if( !result && progress_cancelled() ) result = 1; } } - else - { + else { video_position += video_read_length; } } @@ -489,29 +427,24 @@ void PackageRenderer::stop_engine() void PackageRenderer::stop_output() { int error = 0; - if(asset->audio_data) - { + if( asset->audio_data ) { // stop file I/O file->stop_audio_thread(); } - if(asset->video_data) - { + if( asset->video_data ) { delete compressed_output; - if(video_write_position) + if( video_write_position ) file->write_video_buffer(video_write_position); - if(package->use_brender) - { - for(int i = 0; i < video_write_position && !error; i++) - { + if( package->use_brender ) { + for( int i = 0; i < video_write_position && !error; i++ ) { error = set_video_map(video_position - video_write_position + i, BRender::RENDERED); } } video_write_position = 0; - if(!error) file->stop_video_thread(); - if(mwindow) - { + if( !error ) file->stop_video_thread(); + if( mwindow ) { // video_device->stop_playback(); video_device->close_all(); delete video_device; @@ -522,7 +455,7 @@ void PackageRenderer::stop_output() void PackageRenderer::close_output() { - if(mwindow) + if( mwindow ) mwindow->sighandler->pull_file(file); file->close_file(); delete file; @@ -548,7 +481,7 @@ int PackageRenderer::render_package(RenderPackage *package) // package->video_start, // package->video_end - package->video_start); - if(debug) PRINT_TRACE + if( debug ) PRINT_TRACE if( package->video_do ) default_asset->video_data = 1; if( package->audio_do ) default_asset->audio_data = 1; @@ -560,34 +493,21 @@ int PackageRenderer::render_package(RenderPackage *package) Render::check_asset(edl, *default_asset); create_output(); - if(debug) PRINT_TRACE - if(!asset->video_data) video_done = 1; - if(!asset->audio_data) audio_done = 1; + if( !asset->video_data ) video_done = 1; + if( !asset->audio_data ) audio_done = 1; // Create render engine - if(!result) - { -if(debug) PRINT_TRACE + if( !result ) { create_engine(); -if(debug) PRINT_TRACE - - // Main loop timer->update(); total_samples_rendered = 0; - while((!audio_done || !video_done) && !result) - { + while( !result && (!audio_done || !video_done) ) { int need_audio = 0, need_video = 0; - - - - // Calculate lengths to process. Audio fragment is constant. - if(!audio_done) - { - if(audio_position + audio_read_length >= package->audio_end) - { + if( !audio_done ) { + if( audio_position + audio_read_length >= package->audio_end ) { audio_done = 1; audio_read_length = package->audio_end - audio_position; } @@ -598,19 +518,16 @@ if(debug) PRINT_TRACE //printf("PackageRenderer::render_package 6 %d\n", samples_rendered); - if(!video_done) - { - if(audio_done) - { + if( !video_done ) { + if( audio_done ) { // video_read_length = package->video_end - video_position; // // Packetize video length so progress gets updated // video_read_length = (int)MIN(asset->frame_rate, video_read_length); // video_read_length = MAX(video_read_length, 30); video_read_length = 1; } - else + else { // Guide video with audio - { video_read_length = Units::to_int64( (double)(audio_position + audio_read_length) / asset->sample_rate * @@ -619,37 +536,27 @@ if(debug) PRINT_TRACE } // Clamp length - if(video_position + video_read_length >= package->video_end) - { + if( video_position + video_read_length >= package->video_end ) { video_done = 1; video_read_length = package->video_end - video_position; } // Calculate samples rendered for progress bar. - if(audio_done) + if( audio_done ) samples_rendered = Units::round((double)video_read_length / asset->frame_rate * asset->sample_rate); need_video = 1; } - if(debug) PRINT_TRACE - - if(debug) printf("PackageRenderer::render_package 1 %d %jd %jd\n", - result, audio_read_length, video_read_length); - if(need_video && !result) do_video(); - if(debug) printf("PackageRenderer::render_package %d %d %d\n", - __LINE__, result, samples_rendered); - if(need_audio && !result) do_audio(); + if( need_video && !result ) do_video(); + if( need_audio && !result ) do_audio(); - - if(debug) PRINT_TRACE - if(!result) - { + if( debug ) PRINT_TRACE + if( !result ) { // Calculate frames per second for the renderfarm table. total_samples_rendered += samples_rendered; - if(!video_done && timer->get_difference() > 30000) - { + if( !video_done && timer->get_difference() > 30000 ) { frames_per_second = (double)total_samples_rendered * asset->frame_rate / asset->sample_rate / @@ -657,18 +564,11 @@ if(debug) PRINT_TRACE } set_progress(samples_rendered); } - if(debug) PRINT_TRACE - + if( !result && progress_cancelled() ) result = 1; - - - if(!result && progress_cancelled()) result = 1; - if(debug) PRINT_TRACE - -// printf("PackageRenderer::render_package 10 %d %d %d %d\n", // audio_read_length, video_read_length, samples_rendered, result); - if(result) + if( result ) set_result(result); else result = get_result(); @@ -722,17 +622,14 @@ int PackageRenderer::direct_frame_copy(EDL *edl, Edit *playable_edit = 0; //printf("Render::direct_frame_copy 1\n"); - if(direct_copy_possible(edl, + if( direct_copy_possible(edl, video_position, playable_track, playable_edit, - file)) - { + file) ) { // Switch to direct copying - if(!direct_frame_copying) - { - if(video_write_position) - { + if( !direct_frame_copying ) { + if( video_write_position ) { error |= file->write_video_buffer(video_write_position); video_write_position = 0; } @@ -741,8 +638,7 @@ int PackageRenderer::direct_frame_copy(EDL *edl, } //printf("Render::direct_frame_copy 2\n"); - if(!package->use_brender) - { + if( !package->use_brender ) { error |= ((VEdit*)playable_edit)->read_frame(compressed_output, video_position, PLAY_FORWARD, @@ -754,21 +650,17 @@ int PackageRenderer::direct_frame_copy(EDL *edl, } - if(!error && video_preroll > 0) - { + if( !error && video_preroll > 0 ) { video_preroll--; } else - if(!error) - { - if(package->use_brender) - { + if( !error ) { + if( package->use_brender ) { //printf("PackageRenderer::direct_frame_copy 1\n"); error = set_video_map(video_position, BRender::SCANNED); //printf("PackageRenderer::direct_frame_copy 10 %d\n", error); } - else - { + else { VFrame ***temp_output = new VFrame**[1]; temp_output[0] = new VFrame*[1]; temp_output[0][0] = compressed_output; @@ -794,17 +686,14 @@ int PackageRenderer::direct_copy_possible(EDL *edl, Track* current_track; // Number of playable tracks must equal 1 - for(current_track = edl->tracks->first; + for( current_track = edl->tracks->first; current_track && result; - current_track = current_track->next) - { - if(current_track->data_type == TRACK_VIDEO) - { - if(playable_tracks->is_playable(current_track, + current_track = current_track->next ) { + if( current_track->data_type == TRACK_VIDEO ) { + if( playable_tracks->is_playable(current_track, current_position, PLAY_FORWARD, - 1)) - { + 1) ) { playable_track = current_track; total_playable_tracks++; } @@ -812,35 +701,33 @@ int PackageRenderer::direct_copy_possible(EDL *edl, } //printf("Render::direct_copy_possible 1 %d\n", result); - if(total_playable_tracks != 1) result = 0; + if( total_playable_tracks != 1 ) result = 0; //printf("Render::direct_copy_possible 2 %d\n", result); // Edit must have a source file // TODO: descend into nested EDL's - if(result) - { + if( result ) { //printf("Render::direct_copy_possible 3 %d\n", result); playable_edit = playable_track->edits->get_playable_edit(current_position, 1); //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit); - if(!playable_edit) + if( !playable_edit ) result = 0; } // Source file must be able to copy to destination file. // Source file must be same size as project output. - if(result) - { - if(!file->can_copy_from(playable_edit->asset, + if( result ) { + if( !file->can_copy_from(playable_edit->asset, current_position + playable_track->nudge, edl->session->output_w, - edl->session->output_h)) + edl->session->output_h) ) result = 0; } //printf("Render::direct_copy_possible 6 %d\n", result); // Test conditions mutual between vrender.C and this. - if(result && - !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1)) + if( result && + !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1) ) result = 0; //printf("Render::direct_copy_possible 7 %d\n", result); diff --git a/cinelerra-5.1/cinelerra/packagingengine.C b/cinelerra-5.1/cinelerra/packagingengine.C index 778d4e6e..222f8d30 100644 --- a/cinelerra-5.1/cinelerra/packagingengine.C +++ b/cinelerra-5.1/cinelerra/packagingengine.C @@ -45,12 +45,9 @@ PackagingEngineDefault::~PackagingEngineDefault() } -int PackagingEngineDefault::create_packages_single_farm( - EDL *edl, - Preferences *preferences, - Asset *default_asset, - double total_start, - double total_end) +int PackagingEngineDefault::create_packages_single_farm(EDL *edl, + Preferences *preferences, Asset *default_asset, + double total_start, double total_end) { this->total_start = total_start; this->total_end = total_end; @@ -62,6 +59,7 @@ int PackagingEngineDefault::create_packages_single_farm( audio_end = Units::to_int64(total_end * default_asset->sample_rate); video_end = Units::to_int64(total_end * default_asset->frame_rate); current_package = 0; + current_position = 0; double total_len = total_end - total_start; total_packages = preferences->renderfarm_job_count; @@ -70,146 +68,119 @@ int PackagingEngineDefault::create_packages_single_farm( package_len = total_len / total_packages; min_package_len = 2.0 / edl->session->frame_rate; - -//printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len); int current_number; // The number being injected into the filename. int number_start; // Character in the filename path at which the number begins int total_digits; // Total number of digits including padding the user specified. Render::get_starting_number(default_asset->path, - current_number, - number_start, - total_digits, - 3); + current_number, number_start, total_digits, 3); - for(int i = 0; i < total_allocated; i++) - { + for( int i=0; ipath, - default_asset->path, - current_number, - total_digits, - number_start); + Render::create_filename(package->path, default_asset->path, + current_number, total_digits, number_start); current_number++; } return 0; } RenderPackage* PackagingEngineDefault::get_package_single_farm(double frames_per_second, - int client_number, - int use_local_rate) + int client_number, int use_local_rate) { - -//printf("PackageDispatcher::get_package %ld %ld %ld %ld\n", audio_position, video_position, audio_end, video_end); - - RenderPackage *result = 0; - float avg_frames_per_second = preferences->get_avg_rate(use_local_rate); - - if(audio_position < audio_end || - video_position < video_end) - { + RenderPackage *result = 0; + float avg_frames_per_second = preferences->get_avg_rate(use_local_rate); + double length = package_len; + int scaled_length = 0; + + if( (default_asset->audio_data && + (audio_position < audio_end && !EQUIV(audio_position, audio_end))) || + (default_asset->video_data && + (video_position < video_end && !EQUIV(video_position, video_end))) ) { // Last package - double scaled_len; - result = packages[current_package]; - result->audio_start = audio_position; - result->video_start = video_position; - result->video_do = default_asset->video_data; - result->audio_do = default_asset->audio_data; - - if(current_package >= total_allocated - 1) - { - result->audio_end = audio_end; - result->video_end = video_end; - audio_position = result->audio_end; - video_position = result->video_end; + result = packages[current_package]; + result->audio_start = audio_position; + result->video_start = video_position; + result->video_do = default_asset->video_data; + result->audio_do = default_asset->audio_data; + + if( current_package >= total_allocated-1 ) { + result->audio_end = audio_end; + result->video_end = video_end; + audio_position = result->audio_end; + video_position = result->video_end; + } + else { + if( frames_per_second > 0 && + !EQUIV(frames_per_second, 0) && !EQUIV(avg_frames_per_second, 0) ) { +// package size to fit the requestor. + length *= frames_per_second / avg_frames_per_second; + scaled_length = 1; } - else -// No useful speed data. May get infinity for real fast jobs. - if(frames_per_second > 0x7fffff || frames_per_second < 0 || - EQUIV(frames_per_second, 0) || - EQUIV(avg_frames_per_second, 0)) - { - scaled_len = MAX(package_len, min_package_len); - - result->audio_end = audio_position + - Units::round(scaled_len * default_asset->sample_rate); - result->video_end = video_position + - Units::round(scaled_len * default_asset->frame_rate); - -// If we get here without any useful speed data render the whole thing. - if(current_package >= total_packages - 1) - { - result->audio_end = audio_end; - result->video_end = video_end; - } - else - { - result->audio_end = MIN(audio_end, result->audio_end); - result->video_end = MIN(video_end, result->video_end); - } - - audio_position = result->audio_end; - video_position = result->video_end; + if( length < min_package_len ) + length = min_package_len; + double end_position = current_position + length; + + if( result->video_do ) { + int64_t video_end = end_position * default_asset->frame_rate; + result->video_end = MIN(this->video_end, video_end); + end_position = video_end / default_asset->frame_rate; } - else -// Useful speed data and future packages exist. Scale the -// package size to fit the requestor. - { - scaled_len = package_len * - frames_per_second / - avg_frames_per_second; - scaled_len = MAX(scaled_len, min_package_len); - - result->audio_end = result->audio_start + - Units::to_int64(scaled_len * default_asset->sample_rate); - result->video_end = result->video_start + - Units::to_int64(scaled_len * default_asset->frame_rate); - - result->audio_end = MIN(audio_end, result->audio_end); - result->video_end = MIN(video_end, result->video_end); - - audio_position = result->audio_end; - video_position = result->video_end; + if( result->audio_do ) { + int64_t audio_end = end_position * default_asset->sample_rate; + result->audio_end = MIN(this->audio_end, audio_end); + } + audio_position = result->audio_end; + video_position = result->video_end; + current_position = end_position; // Package size is no longer touched between total_packages and total_allocated - if(current_package < total_packages - 1) - { - package_len = (double)(audio_end - audio_position) / - (double)default_asset->sample_rate / - (double)(total_packages - current_package); + if( scaled_length && current_package < total_packages-1 ) { + double remaining = + result->audio_do ? (double)(audio_end - audio_position) / + default_asset->sample_rate : + result->video_do ? (double)(video_end - video_position) / + default_asset->frame_rate : 0; + if( remaining > 0 ) { + int jobs = total_packages - current_package; + package_len = remaining / jobs; } - } - - current_package++; -//printf("Dispatcher::get_package 50 %lld %lld %lld %lld\n", -//result->audio_start, -//result->video_start, -//result->audio_end, -//result->video_end); } - return result; + current_package++; +//printf("Dispatcher::get_package 50 %lld %lld %lld %lld\n", +// result->audio_start, result->video_start, result->audio_end, result->video_end); + } + return result; } void PackagingEngineDefault::get_package_paths(ArrayList *path_list) { - for(int i = 0; i < total_allocated; i++) - { + for( int i=0; iappend(strdup(packages[i]->path)); } path_list->set_free(); } +int PackagingEngineDefault::get_asset_list(ArrayList &idxbls) +{ + for( int i=0; icopy_from(default_asset, 1); + strcpy(asset->path, packages[i]->path); + asset->video_length = packages[i]->video_end - packages[i]->video_start; + asset->audio_length = packages[i]->audio_end - packages[i]->audio_start; + idxbls.append(asset); + } + return current_package; +} + int64_t PackagingEngineDefault::get_progress_max() { - return Units::to_int64(default_asset->sample_rate * - (total_end - total_start)) + - Units::to_int64(preferences->render_preroll * - 2 * - default_asset->sample_rate); + return Units::to_int64(default_asset->sample_rate * (total_end - total_start)) + + Units::to_int64(preferences->render_preroll * 2 * default_asset->sample_rate); } int PackagingEngineDefault::packages_are_done() @@ -217,6 +188,3 @@ int PackagingEngineDefault::packages_are_done() return 0; } - - - diff --git a/cinelerra-5.1/cinelerra/packagingengine.h b/cinelerra-5.1/cinelerra/packagingengine.h index 89837c1e..217b5667 100644 --- a/cinelerra-5.1/cinelerra/packagingengine.h +++ b/cinelerra-5.1/cinelerra/packagingengine.h @@ -44,6 +44,7 @@ public: int use_local_rate) = 0; virtual int64_t get_progress_max() = 0; virtual void get_package_paths(ArrayList *path_list) = 0; + virtual int get_asset_list(ArrayList &idxbls) = 0; virtual int packages_are_done() = 0; }; @@ -66,6 +67,7 @@ public: int use_local_rate); int64_t get_progress_max(); void get_package_paths(ArrayList *path_list); + int get_asset_list(ArrayList &idxbls); int packages_are_done(); private: RenderPackage **packages; @@ -80,6 +82,7 @@ private: int64_t video_position; int64_t audio_end; int64_t video_end; + double current_position; int current_package; Asset *default_asset; Preferences *preferences; diff --git a/cinelerra-5.1/cinelerra/remotecontrol.C b/cinelerra-5.1/cinelerra/remotecontrol.C index 1fa93d9c..704a7fb6 100644 --- a/cinelerra-5.1/cinelerra/remotecontrol.C +++ b/cinelerra-5.1/cinelerra/remotecontrol.C @@ -58,9 +58,11 @@ int RemoteControl::activate(RemoteHandler *handler) if( !handler ) handler = !mwindow_gui->record->running() ? (RemoteHandler *)mwindow_gui->cwindow_remote_handler : (RemoteHandler *)mwindow_gui->record_remote_handler ; + gui->lock_window("RemoteControl::activate"); gui->set_active(handler); gui->set_color(handler->color); gui->fill_color(handler->color); + gui->unlock_window(); result = 1; } active_lock->unlock(); diff --git a/cinelerra-5.1/cinelerra/render.C b/cinelerra-5.1/cinelerra/render.C index 0398ccf0..ff21962f 100644 --- a/cinelerra-5.1/cinelerra/render.C +++ b/cinelerra-5.1/cinelerra/render.C @@ -1,4 +1,3 @@ - /* * CINELERRA * Copyright (C) 1997-2011 Adam Williams @@ -96,15 +95,6 @@ int RenderItem::handle_event() return 1; } - - - - - - - - - RenderProgress::RenderProgress(MWindow *mwindow, Render *render) : Thread(1, 0, 0) { @@ -124,14 +114,12 @@ RenderProgress::~RenderProgress() void RenderProgress::run() { Thread::disable_cancel(); - while(1) - { - if(render->total_rendered != last_value) - { + for( ;; ) { + if( render->total_rendered != last_value ) { render->progress->update(render->total_rendered); last_value = render->total_rendered; - if(mwindow) mwindow->preferences_thread->update_rates(); + if( mwindow ) mwindow->preferences_thread->update_rates(); } Thread::enable_cancel(); @@ -167,11 +155,8 @@ int MainPackageRenderer::get_result() void MainPackageRenderer::set_result(int value) { - if(value) + if( value ) render->result = value; - - - } void MainPackageRenderer::set_progress(int64_t value) @@ -186,7 +171,7 @@ void MainPackageRenderer::set_progress(int64_t value) //printf("MainPackageRenderer::set_progress %d %ld %f\n", __LINE__, (long)value, frames_per_second); // If non interactive, print progress out - if(!render->progress) + if( !render->progress ) render->show_progress(); render->counter_lock->unlock(); @@ -201,6 +186,18 @@ int MainPackageRenderer::progress_cancelled() render->batch_cancelled; } +void RenderAssets::clear() +{ + for( int i=size(); --i>=0; get(i)->remove_user() ); + remove_all(); +} +RenderAssets::RenderAssets() +{ +} +RenderAssets::~RenderAssets() +{ + clear(); +} Render::Render(MWindow *mwindow) : BC_DialogThread() @@ -256,8 +253,7 @@ void Render::start_interactive() void Render::start_batches(ArrayList *jobs) { - if(!thread->running()) - { + if( !thread->running() ) { mode = Render::BATCH; batch_cancelled = 0; this->jobs = jobs; @@ -297,9 +293,9 @@ BC_Window* Render::new_gui() batch_cancelled = 0; result = 0; - if(mode == Render::INTERACTIVE) { + if( mode == Render::INTERACTIVE ) { // Fix the asset for rendering - if(!asset) asset = new Asset; + if( !asset ) asset = new Asset; load_defaults(asset); check_asset(mwindow->edl, *asset); int px = mwindow->gui->get_pop_cursor_x(1); @@ -314,7 +310,7 @@ BC_Window* Render::new_gui() void Render::handle_done_event(int result) { - if(!result) { + if( !result ) { mwindow->edl->session->render_beep = beep; // add to recentlist only on OK render_window->render_format->path_recent-> @@ -370,7 +366,7 @@ void Render::handle_close_event(int result) error_box.run_window(); } - if(!result) { + if( !result ) { // Check the asset format for errors. FormatCheck format_check(asset); if( format_check.check_format() ) @@ -385,9 +381,9 @@ void Render::handle_close_event(int result) //PRINT_TRACE 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__); + if( debug ) printf("Render::handle_close_event %d\n", __LINE__); + if( !result ) start_render(); + if( debug ) printf("Render::handle_close_event %d\n", __LINE__); } //PRINT_TRACE } @@ -396,8 +392,7 @@ void Render::handle_close_event(int result) void Render::stop_operation() { - if(thread->Thread::running()) - { + if( thread->Thread::running() ) { batch_cancelled = 1; // Wait for completion completion->lock("Render::stop_operation"); @@ -407,38 +402,33 @@ void Render::stop_operation() int Render::check_asset(EDL *edl, Asset &asset) { - if(asset.video_data && + if( asset.video_data && edl->tracks->playable_video_tracks() && - File::renders_video(&asset)) - { + 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; } - else - { + else { asset.video_data = 0; asset.layers = 0; } - if(asset.audio_data && + if( asset.audio_data && edl->tracks->playable_audio_tracks() && - File::renders_audio(&asset)) - { + File::renders_audio(&asset) ) { asset.audio_data = 1; asset.channels = edl->session->audio_channels; } - else - { + else { asset.audio_data = 0; asset.channels = 0; } - if(!asset.audio_data && - !asset.video_data) - { + if( !asset.audio_data && + !asset.video_data ) { return 1; } return 0; @@ -459,15 +449,13 @@ void Render::start_progress() { char filename[BCTEXTLEN]; char string[BCTEXTLEN]; - FileSystem fs; - progress_max = packages->get_progress_max(); progress_timer->update(); last_eta = 0; - if(mwindow) - { + if( mwindow ) { // Generate the progress box + FileSystem fs; fs.extract_name(filename, default_asset->path); sprintf(string, _("Rendering %s..."), filename); @@ -481,8 +469,7 @@ void Render::start_progress() void Render::stop_progress() { - if(progress) - { + if( progress ) { char string[BCTEXTLEN], string2[BCTEXTLEN]; delete render_progress; progress->get_time(string); @@ -503,7 +490,7 @@ void Render::stop_progress() void Render::show_progress() { int64_t current_eta = progress_timer->get_scaled_difference(1000); - if (current_eta - last_eta < 1000 ) return; + 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); @@ -535,8 +522,7 @@ void Render::create_filename(char *path, int len = strlen(default_path); char printf_string[BCTEXTLEN]; - for(i = 0, j = 0; i < number_start; i++, j++) - { + for( i=0, j=0; iget_asset_list(assets); +} static void run_script(const char *script, const char *arg) { @@ -675,12 +662,8 @@ void RenderThread::render_single(int test_overwrite, Asset *asset, EDL *edl, // Total length in seconds double total_length = 0; RenderFarmServer *farm_server = 0; - FileSystem fs; - const int debug = 0; render->in_progress = 1; - - render->default_asset = asset; render->progress = 0; render->result = 0; @@ -725,82 +708,62 @@ void RenderThread::render_single(int test_overwrite, Asset *asset, EDL *edl, render->result = render->check_asset(command->get_edl(), *render->default_asset); - if(!render->result) - { + if( !render->result ) { // Get total range to render render->total_start = command->start_position; render->total_end = command->end_position; total_length = render->total_end - render->total_start; // Nothing to render - if(EQUIV(total_length, 0)) - { + if( EQUIV(total_length, 0) ) { render->result = 1; } } render_frames = render->default_asset->frame_rate * total_length; // Generate packages - if(!render->result) - { + if( !render->result ) { // Stop background rendering - if(mwindow) mwindow->stop_brender(); + if( mwindow ) mwindow->stop_brender(); + FileSystem fs; fs.complete_path(render->default_asset->path); - render->result = render->packages->create_packages(mwindow, - command->get_edl(), - render->preferences, - strategy, - render->default_asset, - render->total_start, - render->total_end, - test_overwrite); + render->result = render->packages->create_packages(mwindow, command->get_edl(), + render->preferences, strategy, render->default_asset, + render->total_start, render->total_end, test_overwrite); } render->total_rendered = 0; - if(!render->result) - { + if( !render->result ) { // Start dispatching external jobs - if(mwindow) - { + if( mwindow ) { mwindow->gui->lock_window("Render::render 1"); mwindow->gui->show_message(_("Starting render farm")); mwindow->gui->start_hourglass(); mwindow->gui->unlock_window(); } - else - { + else { printf("Render::render: starting render farm\n"); } - if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM) - { - farm_server = new RenderFarmServer(mwindow, - render->packages, - render->preferences, - 1, - &render->result, - &render->total_rendered, - render->counter_lock, - render->default_asset, - command->get_edl(), - 0); + if( strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM ) { + farm_server = new RenderFarmServer(mwindow, render->packages, + render->preferences, 1, &render->result, + &render->total_rendered, render->counter_lock, + render->default_asset, command->get_edl(), 0); render->result = farm_server->start_clients(); - if(render->result) - { - if(mwindow) - { + if( render->result ) { + if( mwindow ) { mwindow->gui->lock_window("Render::render 2"); mwindow->gui->show_message(_("Failed to start render farm"), mwindow->theme->message_error); mwindow->gui->stop_hourglass(); mwindow->gui->unlock_window(); } - else - { + else { printf("Render::render: Failed to start render farm\n"); } } @@ -809,8 +772,8 @@ void RenderThread::render_single(int test_overwrite, Asset *asset, EDL *edl, // Perform local rendering - if(!render->result) - { + render->assets.clear(); + if( !render->result ) { render->start_progress(); MainPackageRenderer package_renderer(render); @@ -819,33 +782,16 @@ void RenderThread::render_single(int test_overwrite, Asset *asset, EDL *edl, render->preferences, render->default_asset); - while(!render->result) - { + while( !render->result ) { + int fps = strategy == SINGLE_PASS_FARM ? + package_renderer.frames_per_second : 0; // Get unfinished job - RenderPackage *package; - - if(strategy == SINGLE_PASS_FARM) - { - package = render->packages->get_package( - package_renderer.frames_per_second, - -1, - 1); - } - else - { - package = render->packages->get_package(0, -1, 1); - } - + RenderPackage *package = render->packages->get_package(fps, -1, 1); // Exit point - if(!package) - { - break; - } + if( !package ) break; - if(package_renderer.render_package(package)) + if( package_renderer.render_package(package) ) render->result = 1; - - } // file_number printf("Render::render_single: Session finished.\n"); @@ -862,93 +808,55 @@ printf("Render::render_single: Session finished.\n"); render->result |= render->packages->packages_are_done(); } -if(debug) printf("Render::render %d\n", __LINE__); - // Notify of error - if(render->result && - (!render->progress || !render->progress->is_cancelled()) && - !render->batch_cancelled) - { -if(debug) printf("Render::render %d\n", __LINE__); - if(mwindow) - { -if(debug) printf("Render::render %d\n", __LINE__); + if( render->result && !render->batch_cancelled && + (!render->progress || !render->progress->is_cancelled()) ) { + if( mwindow ) { 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(); -if(debug) printf("Render::render %d\n", __LINE__); } - else - { + else { printf("Render::render: Error rendering data\n"); } } -if(debug) printf("Render::render %d\n", __LINE__); // Delete the progress box render->stop_progress(); -if(debug) printf("Render::render %d\n", __LINE__); + render->update_assets(); } // Paste all packages into timeline if desired - if(!render->result && - render->load_mode != LOADMODE_NOTHING && - mwindow && - render->mode != Render::BATCH) - { -if(debug) printf("Render::render %d\n", __LINE__); + if( !render->result && mwindow && + render->load_mode != LOADMODE_NOTHING && + render->mode != Render::BATCH ) { mwindow->gui->lock_window("Render::render 3"); -if(debug) printf("Render::render %d\n", __LINE__); mwindow->undo->update_undo_before(); - -if(debug) printf("Render::render %d\n", __LINE__); - - - ArrayList *assets = render->packages->get_asset_list(); -if(debug) printf("Render::render %d\n", __LINE__); - if(render->load_mode == LOADMODE_PASTE) + 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(&render->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, 0); // overwrite -if(debug) printf("Render::render %d\n", __LINE__); - for(int i = 0; i < assets->size(); i++) - assets->get(i)->Garbage::remove_user(); - delete assets; -if(debug) printf("Render::render %d\n", __LINE__); - - mwindow->save_backup(); -if(debug) printf("Render::render %d\n", __LINE__); mwindow->undo->update_undo_after(_("render"), LOAD_ALL); -if(debug) printf("Render::render %d\n", __LINE__); mwindow->update_plugin_guis(); -if(debug) printf("Render::render %d\n", __LINE__); mwindow->gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0); -if(debug) printf("Render::render %d\n", __LINE__); mwindow->sync_parameters(CHANGE_ALL); -if(debug) printf("Render::render %d\n", __LINE__); mwindow->gui->unlock_window(); - mwindow->awindow->gui->async_update_assets(); - -if(debug) printf("Render::render %d\n", __LINE__); } -if(debug) printf("Render::render %d\n", __LINE__); - // Disable hourglass - if(mwindow) - { + if( mwindow ) { mwindow->gui->lock_window("Render::render 3"); mwindow->gui->stop_hourglass(); mwindow->gui->unlock_window(); @@ -956,9 +864,9 @@ if(debug) printf("Render::render %d\n", __LINE__); //printf("Render::render 110\n"); // Need to restart because brender always stops before render. - if(mwindow) + if( mwindow ) mwindow->restart_brender(); - if(farm_server) delete farm_server; + if( farm_server ) delete farm_server; delete command; delete audio_cache; delete video_cache; @@ -967,103 +875,80 @@ if(debug) printf("Render::render %d\n", __LINE__); render->packages = 0; render->in_progress = 0; -if(debug) printf("Render::render %d\n", __LINE__); } void RenderThread::run() { + char *script = 0; Timer render_timer; if( mwindow ) render->preferences->copy_from(mwindow->preferences); - if(render->mode == Render::INTERACTIVE) - { + if( render->mode == Render::INTERACTIVE ) { render_single(1, render->asset, mwindow->edl, render->get_strategy(), render->range_type); } else - if(render->mode == Render::BATCH) - { -// PRINT_TRACE -// printf("RenderThread::run %d %d %d\n", -// __LINE__, -// render->jobs->total, -// render->result); - for(int i = 0; i < render->jobs->total && !render->result; i++) - { -//PRINT_TRACE + if( render->mode == Render::BATCH ) { + for( int i=0; ijobs->total && !render->result; ++i ) { BatchRenderJob *job = render->jobs->values[i]; -//PRINT_TRACE - if(job->enabled) - { - if( *job->edl_path == '@' ) - { - run_script(job->edl_path+1, job->asset->path); - } - - if(mwindow) - { - mwindow->batch_render->update_active(i); - } - else - { - printf("Render::run: %s\n", job->edl_path); - } - -//PRINT_TRACE - - FileXML *file = new FileXML; - EDL *edl = new EDL; - 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->get_strategy(), RANGE_BACKCOMPAT); - -//PRINT_TRACE - edl->Garbage::remove_user(); - delete file; - if(!render->result) - { - if(mwindow) - mwindow->batch_render->update_done(i, 1, render->elapsed_time); - else - { - char string[BCTEXTLEN]; - render->elapsed_time = - (double)render->progress_timer->get_scaled_difference(1); - Units::totext(string, - render->elapsed_time, - TIME_HMS2); - printf("Render::run: done in %s\n", string); - } + if( !job->enabled ) continue; + if( mwindow ) + mwindow->batch_render->update_active(i); + else + printf("Render::run: %s\n", job->edl_path); + + FileXML *file = new FileXML; + EDL *edl = new EDL; + edl->create_objects(); + file->read_from_file(job->edl_path); + edl->load_xml(file, LOAD_ALL); + delete file; + + render_single(0, job->asset, edl, job->get_strategy(), RANGE_BACKCOMPAT); + if( !render->result ) { + if( !i ) + script = job->create_script(edl, &render->assets); + if( mwindow ) + mwindow->batch_render->update_done(i, 1, render->elapsed_time); + else { + char string[BCTEXTLEN]; + render->elapsed_time = + (double)render->progress_timer->get_scaled_difference(1); + Units::totext(string, render->elapsed_time, TIME_HMS2); + printf("Render::run: done in %s\n", string); } + } + else { + if( mwindow ) + mwindow->batch_render->update_active(-1); else - { - if(mwindow) - mwindow->batch_render->update_active(-1); - else - printf("Render::run: failed\n"); - } + printf("Render::run: failed\n"); } -//PRINT_TRACE } - - if(mwindow) - { + if( mwindow ) { mwindow->batch_render->update_active(-1); mwindow->batch_render->update_done(-1, 0, 0); } } render->completion->unlock(); - double render_time = render_timer.get_difference() / 1000.0; - double render_rate = render_time > 0 ? render_frames / render_time : 0; - printf("** rendered %jd frames in %0.3f secs, %0.3f fps\n", - render_frames, render_time, render_rate); + + if( !render->result ) { + double render_time = render_timer.get_difference() / 1000.0; + double render_rate = render_time > 0 ? render_frames / render_time : 0; + printf("** rendered %jd frames in %0.3f secs, %0.3f fps\n", + render_frames, render_time, render_rate); + } if( render->mode == Render::INTERACTIVE && render->beep ) mwindow->beep(3000., 1.5, 0.5); + + if( script ) { + if( !render->result ) + run_script(script, 0); + delete [] script; + } } diff --git a/cinelerra-5.1/cinelerra/render.h b/cinelerra-5.1/cinelerra/render.h index d7f57d23..37c2c103 100644 --- a/cinelerra-5.1/cinelerra/render.h +++ b/cinelerra-5.1/cinelerra/render.h @@ -98,6 +98,14 @@ public: class RenderWindow; +class RenderAssets : public ArrayList +{ +public: + RenderAssets(); + ~RenderAssets(); + + void clear(); +}; class Render : public BC_DialogThread { @@ -153,6 +161,7 @@ public: void start_progress(); void stop_progress(); void show_progress(); + void update_assets(); // Procedure the run function should use. int mode; @@ -177,6 +186,7 @@ public: MainProgressBar *progress; RenderProgress *render_progress; RenderThread *thread; + RenderAssets assets; MWindow *mwindow; PlayableTracks *playable_tracks; PackageDispatcher *packages; diff --git a/cinelerra-5.1/cinelerra/track.C b/cinelerra-5.1/cinelerra/track.C index 24de614f..a285f7f0 100644 --- a/cinelerra-5.1/cinelerra/track.C +++ b/cinelerra-5.1/cinelerra/track.C @@ -194,12 +194,9 @@ void Track::copy_from(Track *track) { copy_settings(track); edits->copy_from(track->edits); - for(int i = 0; i < this->plugin_set.total; i++) - delete this->plugin_set.values[i]; this->plugin_set.remove_all_objects(); - for(int i = 0; i < track->plugin_set.total; i++) - { + for( int i=0; iplugin_set.total; ++i ) { PluginSet *new_plugin_set = plugin_set.append(new PluginSet(edl, this)); new_plugin_set->copy_from(track->plugin_set.values[i]); } -- 2.26.2