switch move/swap tracks, add mv trk shortcut, update msg
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / dvdcreate.C
index 1014baf5e2368312a739e01b0d5bac51aedcbc76..4c8ab188aadc2518a88e6c7ff8938e4b7bb2aab6 100644 (file)
@@ -83,9 +83,9 @@ const double CreateDVD_Thread::DVD_KAUDIO_RATE = 224;
 
 
 CreateDVD_MenuItem::CreateDVD_MenuItem(MWindow *mwindow)
- : BC_MenuItem(_("DVD Render..."), _("Shift-D"), 'D')
+ : BC_MenuItem(_("DVD Render..."), _("Alt-d"), 'd')
 {
-       set_shift(1);
+       set_alt(1);
        this->mwindow = mwindow;
 }
 
@@ -96,6 +96,165 @@ 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<Indexable *> *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,"sdir=`dirname $0`\n");
+       fprintf(fp,"dir=`cd \"$sdir\"; pwd`\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.m2v[0-9]*\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 - <<eof\n");
+       fprintf(fp,"<dvdauthor dest=\"$dir/iso\">\n");
+       fprintf(fp,"  <vmgm>\n");
+       fprintf(fp,"    <fpc> jump title 1; </fpc>\n");
+       fprintf(fp,"  </vmgm>\n");
+       fprintf(fp,"  <titleset>\n");
+       fprintf(fp,"    <titles>\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,"    <video format=\"%s\" aspect=\"%d:%d\" resolution=\"%dx%d\"/>\n",
+               std, (int)session->aspect_w, (int)session->aspect_h,
+               session->output_w, session->output_h);
+       fprintf(fp,"    <audio format=\"ac3\" lang=\"en\"/>\n");
+       fprintf(fp,"    <pgc>\n");
+       int total_idxbls = !file_seq ? 1 : idxbls->size();
+       int secs = 0;
+       double vob_pos = 0;
+       double total_length = edl->tracks->total_length();
+       Label *label = edl->labels->first;
+       for( int i=0; i<total_idxbls; ++i ) {
+               Indexable *idxbl = idxbls->get(i);
+               double video_length = idxbl->have_video() && idxbl->get_frame_rate() > 0 ?
+                       (double)idxbl->get_video_frames() / idxbl->get_frame_rate() : 0 ;
+               double audio_length = idxbl->have_audio() && idxbl->get_sample_rate() > 0 ?
+                       (double)idxbl->get_audio_samples() / idxbl->get_sample_rate() : 0 ;
+               double length = idxbl->have_video() && idxbl->have_audio() ?
+                               bmin(video_length, audio_length) :
+                       idxbl->have_video() ? video_length :
+                       idxbl->have_audio() ? audio_length : 0;
+               fprintf(fp,"      <vob file=\"%s", !file_seq ? "$dir/dvd.mpg" : idxbl->path);
+               chapter = 0;
+               double vob_end = i+1>=total_idxbls ? total_length : vob_pos + length;
+               if( labeled ) {
+                       while( label && label->position < vob_end ) {
+                               create_chapter(label->position - vob_pos);
+                               label = label->next;
+                       }
+               }
+               else {
+                       while( secs < vob_end ) {
+                               create_chapter(secs - vob_pos);
+                               secs += 10*60;  // ch every 10 minutes
+                       }
+               }
+               fprintf(fp,"\"/>\n");
+               vob_pos = vob_end;
+       }
+       fprintf(fp,"    </pgc>\n");
+       fprintf(fp,"    </titles>\n");
+       fprintf(fp,"  </titleset>\n");
+       fprintf(fp,"</dvdauthor>\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 +267,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 +297,6 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *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 +327,6 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *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 - <<eof\n");
-       fprintf(fp,"<dvdauthor dest=\"$1/iso\">\n");
-       fprintf(fp,"  <vmgm>\n");
-       fprintf(fp,"    <fpc> jump title 1; </fpc>\n");
-       fprintf(fp,"  </vmgm>\n");
-       fprintf(fp,"  <titleset>\n");
-       fprintf(fp,"    <titles>\n");
-       char std[BCSTRLEN], *cp = std;
-       for( const char *np=name; *np!=0; ++cp,++np) *cp = *np + 'a'-'A';
-       *cp = 0;
-       fprintf(fp,"    <video format=\"%s\" aspect=\"%d:%d\" resolution=\"%dx%d\"/>\n",
-               std, (int)session->aspect_w, (int)session->aspect_h,
-               session->output_w, session->output_h);
-       fprintf(fp,"    <audio format=\"ac3\" lang=\"en\"/>\n");
-       fprintf(fp,"    <pgc>\n");
-       fprintf(fp,"      <vob file=\"$1/dvd.mpg\" chapters=\"");
-       if( use_label_chapters && edl->labels ) {
-               Label *label = edl->labels->first;
-               while( label ) {
-                       int secs = label->position;
-                       int mins = secs / 60;
-                       int frms = (label->position-secs) * session->frame_rate;
-                       fprintf(fp,"%d:%02d:%02d.%d", mins/60, mins%60, secs%60, frms);
-                       if( (label=label->next) != 0 ) fprintf(fp, ",");
-               }
-       }
-       else {
-               int mins = 0;
-               for( int secs=0 ; secs<total_length; secs+=10*60 ) {
-                       mins = secs / 60;
-                       fprintf(fp,"%d:%02d:00,", mins/60, mins%60);
-               }
-               fprintf(fp,"%d:%02d:00", mins/60, mins%60);
-       }
-       fprintf(fp,"\"/>\n");
-       fprintf(fp,"    </pgc>\n");
-       fprintf(fp,"    </titles>\n");
-       fprintf(fp,"  </titleset>\n");
-       fprintf(fp,"</dvdauthor>\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<MAX_CHANNELS; ++i )
@@ -284,7 +361,8 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *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, 0);// use_ffmpeg);
        jobs->append(job);
        strcpy(&job->edl_path[0], xml_filename);
        Asset *asset = job->asset;
@@ -300,8 +378,15 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs, const ch
                sprintf(&asset->path[0],"%s/dvd.mpg", asset_dir);
                asset->format = FILE_FFMPEG;
                strcpy(asset->fformat, "dvd");
-
+// if there are many renderfarm jobs, then there are small audio fragments of
+// silence that are used at the end of a render to fill the last audio "block".
+// this extra data gradually skews the audio/video sync.  Therefore, the audio
+// is not rendered muxed for ffmpeg, and is remuxed as with mjpeg rendering.
+// since this audio is in one file, the only fragment is at the end and is ok.
+#if 0
                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 +400,29 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs, const ch
                         sizeof(asset->ff_video_options));
                asset->ff_video_bitrate = vid_bitrate;
                asset->ff_video_quality = -1;
+               use_farmed = job->farmed;
+#else
+               asset->video_data = 1;
+               strcpy(asset->vcodec, "raw.dvd");
+               sprintf(&asset->path[0],"%s/dvd.m2v", asset_dir);
+               FFMPEG::set_option_path(option_path, "video/%s", asset->vcodec);
+               FFMPEG::load_options(option_path, asset->ff_video_options,
+                        sizeof(asset->ff_video_options));
+               asset->ff_video_bitrate = vid_bitrate;
+               asset->ff_video_quality = -1;
+               use_farmed = job->farmed;
+
+               job = new BatchRenderJob(mwindow->preferences, 0, 0);
+               jobs->append(job);
+               strcpy(&job->edl_path[0], xml_filename);
+               asset = job->asset;
+               sprintf(&asset->path[0],"%s/dvd.ac3", asset_dir);
+               asset->format = FILE_AC3;
+               asset->audio_data = 1;
+               asset->channels = session->audio_channels;
+               asset->sample_rate = session->sample_rate;
+               asset->ac3_bitrate = dvd_kaudio_rate;
+#endif
        }
        else {
                sprintf(&asset->path[0],"%s/dvd.m2v", asset_dir);
@@ -332,6 +440,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *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 +459,6 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *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;
 }
 
@@ -383,7 +486,7 @@ void CreateDVD_Thread::handle_close_event(int result)
                Tracks *tracks = mwindow->edl->tracks;
                for( Track *vtrk=tracks->first; vtrk; vtrk=vtrk->next ) {
                        if( vtrk->data_type != TRACK_VIDEO ) continue;
-                       if( !vtrk->record ) continue;
+                       if( !vtrk->is_armed() ) continue;
                        vtrk->expand_view = 1;
                        PluginSet *plugin_set = new PluginSet(mwindow->edl, vtrk);
                        vtrk->plugin_set.append(plugin_set);
@@ -444,7 +547,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 +567,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;
@@ -510,7 +614,7 @@ BC_Window* CreateDVD_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 = 520, h = 280;
+       int w = xS(560), h = yS(280);
        int x = scr_x + scr_w/2 - w/2, y = scr_h/2 - h/2;
 
        gui = new CreateDVD_GUI(this, x, y, w, h);
@@ -705,7 +809,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 +818,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"))
 {
@@ -738,7 +852,7 @@ CreateDVD_UseFFMpeg::~CreateDVD_UseFFMpeg()
 
 
 CreateDVD_GUI::CreateDVD_GUI(CreateDVD_Thread *thread, int x, int y, int w, int h)
- : BC_Window(_(PROGRAM_NAME ": Create DVD"), x, y, w, h, 50, 50, 1, 0, 1)
+ : BC_Window(_(PROGRAM_NAME ": Create DVD"), x, y, w, h, xS(50), yS(50), 1, 0, 1)
 {
        this->thread = thread;
        at_x = at_y = tmp_x = tmp_y = 0;
@@ -755,7 +869,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;
 }
@@ -766,20 +881,22 @@ CreateDVD_GUI::~CreateDVD_GUI()
 
 void CreateDVD_GUI::create_objects()
 {
+       int xs10 = xS(10), xs35 = xS(35), xs170 = xS(170);
+       int ys5 = yS(5), ys10 = yS(10);
        lock_window("CreateDVD_GUI::create_objects");
-       int pady = BC_TextBox::calculate_h(this, MEDIUMFONT, 0, 1) + 5;
+       int pady = BC_TextBox::calculate_h(this, MEDIUMFONT, 0, 1) + ys5;
        int padx = BC_Title::calculate_w(this, (char*)"X", MEDIUMFONT);
        int x = padx/2, y = pady/2;
        BC_Title *title = new BC_Title(x, y, _("Title:"), MEDIUMFONT, YELLOW);
        add_subwindow(title);
        at_x = x + title->get_w();  at_y = y;
-       asset_title = new CreateDVD_AssetTitle(this, at_x, at_y, get_w()-at_x-10);
+       asset_title = new CreateDVD_AssetTitle(this, at_x, at_y, get_w()-at_x-xs10);
        add_subwindow(asset_title);
        y += title->get_h() + pady/2;
        title = new BC_Title(x, y, _("Work path:"), MEDIUMFONT, YELLOW);
        add_subwindow(title);
        tmp_x = x + title->get_w();  tmp_y = y;
-       tmp_path = new CreateDVD_TmpPath(this, tmp_x, tmp_y,  get_w()-tmp_x-35);
+       tmp_path = new CreateDVD_TmpPath(this, tmp_x, tmp_y,  get_w()-tmp_x-xs35);
        add_subwindow(tmp_path);
        btmp_path = new BrowseButton(thread->mwindow->theme, this, tmp_path,
                tmp_x+tmp_path->get_w(), tmp_y, "/tmp",
@@ -788,7 +905,7 @@ void CreateDVD_GUI::create_objects()
        y += title->get_h() + pady/2;
        disk_space = new CreateDVD_DiskSpace(this, x, y);
        add_subwindow(disk_space);
-       int x0 = get_w() - 170;
+       int x0 = get_w() - xs170;
        title = new BC_Title(x0, y, _("Media:"), MEDIUMFONT, YELLOW);
        add_subwindow(title);
        int x1 = x0+title->get_w()+padx;
@@ -805,7 +922,7 @@ void CreateDVD_GUI::create_objects()
        standard = new CreateDVD_Format(this, title->get_w() + padx, y);
        add_subwindow(standard);
        standard->create_objects();
-       x0 -= 30;
+       x0 -= xS(60);
        title = new BC_Title(x0, y, _("Scale:"), MEDIUMFONT, YELLOW);
        add_subwindow(title);
        x1 = x0+title->get_w()+padx;
@@ -813,34 +930,40 @@ 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 += xs170;
+       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 += xs170;
+       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;
-       ok_y = get_h() - ok_h - 10;
+       ok_x = xs10;
+       ok_y = get_h() - ok_h - ys10;
        ok = new CreateDVD_OK(this, ok_x, ok_y);
        add_subwindow(ok);
        cancel_w = BC_CancelButton::calculate_w();
        cancel_h = BC_CancelButton::calculate_h();
-       cancel_x = get_w() - cancel_w - 10,
-       cancel_y = get_h() - cancel_h - 10;
+       cancel_x = get_w() - cancel_w - xs10,
+       cancel_y = get_h() - cancel_h - ys10;
        cancel = new CreateDVD_Cancel(this, cancel_x, cancel_y);
        add_subwindow(cancel);
        show_window();
@@ -849,13 +972,15 @@ void CreateDVD_GUI::create_objects()
 
 int CreateDVD_GUI::resize_event(int w, int h)
 {
-       asset_title->reposition_window(at_x, at_y, get_w()-at_x-10);
-       tmp_path->reposition_window(tmp_x, tmp_y,  get_w()-tmp_x-35);
+       int xs10 = xS(10), xs35 = xS(35);
+       int ys10 = yS(10);
+       asset_title->reposition_window(at_x, at_y, get_w()-at_x-xs10);
+       tmp_path->reposition_window(tmp_x, tmp_y,  get_w()-tmp_x-xs35);
        btmp_path->reposition_window(tmp_x+tmp_path->get_w(), tmp_y);
-       ok_y = h - ok_h - 10;
+       ok_y = h - ok_h - ys10;
        ok->reposition_window(ok_x, ok_y);
-       cancel_x = w - cancel_w - 10,
-       cancel_y = h - cancel_h - 10;
+       cancel_x = w - cancel_w - xs10,
+       cancel_y = h - cancel_h - ys10;
        cancel->reposition_window(cancel_x, cancel_y);
        return 0;
 }
@@ -880,7 +1005,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::
@@ -889,7 +1015,7 @@ insert_video_plugin(const char *title, KeyFrame *default_keyframe)
        Tracks *tracks = mwindow->edl->tracks;
        for( Track *vtrk=tracks->first; vtrk; vtrk=vtrk->next ) {
                if( vtrk->data_type != TRACK_VIDEO ) continue;
-               if( !vtrk->record ) continue;
+               if( !vtrk->is_armed() ) continue;
                vtrk->expand_view = 1;
                PluginSet *plugin_set = new PluginSet(mwindow->edl, vtrk);
                vtrk->plugin_set.append(plugin_set);
@@ -913,7 +1039,7 @@ resize_tracks()
        if( trk_h < dvd_height ) trk_h = dvd_height;
        for( Track *vtrk=tracks->first; vtrk; vtrk=vtrk->next ) {
                if( vtrk->data_type != TRACK_VIDEO ) continue;
-               if( !vtrk->record ) continue;
+               if( !vtrk->is_armed() ) continue;
                vtrk->track_w = trk_w;
                vtrk->track_h = trk_h;
        }
@@ -928,7 +1054,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;
 
@@ -945,7 +1072,7 @@ option_presets()
        max_w = 0;  max_h = 0;
        int has_deinterlace = 0, has_scale = 0;
        for( Track *trk=tracks->first; trk; trk=trk->next ) {
-               if( !trk->record ) continue;
+               if( !trk->is_armed() ) continue;
                Edits *edits = trk->edits;
                switch( trk->data_type ) {
                case TRACK_VIDEO:
@@ -984,7 +1111,7 @@ option_presets()
                if( max_h != dvd_height ) use_resize_tracks = 1;
        }
        for( Track *trk=tracks->first; trk && !use_resize_tracks; trk=trk->next ) {
-               if( !trk->record ) continue;
+               if( !trk->is_armed() ) continue;
                switch( trk->data_type ) {
                case TRACK_VIDEO:
                        if( trk->track_w != max_w ) use_resize_tracks = 1;
@@ -994,11 +1121,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;
 }
 
@@ -1025,7 +1153,7 @@ int CreateDVD_FormatItem::handle_event()
 
 
 CreateDVD_Format::CreateDVD_Format(CreateDVD_GUI *gui, int x, int y)
- : BC_PopupMenu(x, y, 180, "", 1)
+ : BC_PopupMenu(x, y, xS(180), "", 1)
 {
        this->gui = gui;
 }
@@ -1077,7 +1205,7 @@ int CreateDVD_ScaleItem::handle_event()
 
 
 CreateDVD_Scale::CreateDVD_Scale(CreateDVD_GUI *gui, int x, int y)
- : BC_PopupMenu(x, y, 100, "", 1)
+ : BC_PopupMenu(x, y, xS(140), "", 1)
 {
        this->gui = gui;
 }
@@ -1103,7 +1231,7 @@ int CreateDVD_Scale::handle_event()
 
 
 CreateDVD_MediaSize::CreateDVD_MediaSize(CreateDVD_GUI *gui, int x, int y)
- : BC_PopupTextBox(gui, 0, 0, x, y, 70,50)
+ : BC_PopupTextBox(gui, 0, 0, x, y, xS(70), 50)
 {
        this->gui = gui;
 }