nested clips, big rework and cleanup, sams new icons, leaks and tweaks
[goodguy/history.git] / cinelerra-5.1 / cinelerra / dvdcreate.C
index f6a6bc699868017a6af2632e06934be592e8806b..1014baf5e2368312a739e01b0d5bac51aedcbc76 100644 (file)
@@ -1,4 +1,5 @@
 #include "asset.h"
+#include "bchash.h"
 #include "clip.h"
 #include "dvdcreate.h"
 #include "edl.h"
@@ -15,6 +16,7 @@
 #include "mwindowgui.h"
 #include "plugin.h"
 #include "pluginset.h"
+#include "preferences.h"
 #include "rescale.h"
 #include "track.h"
 #include "tracks.h"
@@ -83,7 +85,7 @@ const double CreateDVD_Thread::DVD_KAUDIO_RATE = 224;
 CreateDVD_MenuItem::CreateDVD_MenuItem(MWindow *mwindow)
  : BC_MenuItem(_("DVD Render..."), _("Shift-D"), 'D')
 {
-       set_shift(1); 
+       set_shift(1);
        this->mwindow = mwindow;
 }
 
@@ -125,8 +127,7 @@ CreateDVD_Thread::~CreateDVD_Thread()
        close_window();
 }
 
-int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
-       const char *tmp_path, const char *asset_title)
+int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs, const char *asset_dir)
 {
        EDL *edl = mwindow->edl;
        if( !edl || !edl->session ) {
@@ -145,9 +146,6 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
                return 1;
        }
 
-       char asset_dir[BCTEXTLEN];
-       sprintf(asset_dir, "%s/%s", tmp_path, asset_title);
-
        if( mkdir(asset_dir, 0777) ) {
                char err[BCTEXTLEN], msg[BCTEXTLEN];
                strerror_r(errno, err, sizeof(err));
@@ -186,10 +184,18 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
        fprintf(fp,"\n");
        const char *exec_path = File::get_cinlib_path();
        fprintf(fp,"PATH=$PATH:%s\n",exec_path);
-       if( !use_ffmpeg ) {
-               fprintf(fp,"mplex -f 8 -o $1/dvd.mpg $1/dvd.m2v $1/dvd.ac3\n");
-               fprintf(fp,"\n");
+       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");
@@ -240,30 +246,21 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
        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);
 
-       if( use_wide_audio ) {
-               session->audio_channels = session->audio_tracks = DVD_WIDE_CHANNELS;
-               session->achannel_positions[0] = 90;
-               session->achannel_positions[1] = 150;
-               session->achannel_positions[2] = 30;
-               session->achannel_positions[3] = 210;
-               session->achannel_positions[4] = 330;
-               session->achannel_positions[5] = 270;
-               if( edl->tracks->recordable_audio_tracks() == DVD_WIDE_CHANNELS )
-                       mwindow->remap_audio(MWindow::AUDIO_1_TO_1);
-       }
-       else {
-               session->audio_channels = session->audio_tracks = DVD_CHANNELS;
-               session->achannel_positions[0] = 180;
-               session->achannel_positions[1] = 0;
-               if( edl->tracks->recordable_audio_tracks() == DVD_WIDE_CHANNELS )
-                       mwindow->remap_audio(MWindow::AUDIO_5_1_TO_2);
-       }
+       session->audio_channels = session->audio_tracks =
+               !use_wide_audio ? DVD_CHANNELS : DVD_WIDE_CHANNELS;
+       for( int i=0; i<MAX_CHANNELS; ++i )
+               session->achannel_positions[i] = default_audio_channel_position(i, session->audio_channels);
+       int audio_mapping = edl->tracks->recordable_audio_tracks() == DVD_WIDE_CHANNELS &&
+               !use_wide_audio ? MWindow::AUDIO_5_1_TO_2 : MWindow::AUDIO_1_TO_1;
+       mwindow->remap_audio(audio_mapping);
 
        double new_samplerate = session->sample_rate;
        double new_framerate = session->frame_rate;
+       edl->retrack();
        edl->rechannel();
        edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
        edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
@@ -278,7 +275,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
        char xml_filename[BCTEXTLEN];
        sprintf(xml_filename, "%s/dvd.xml", asset_dir);
        FileXML xml_file;
-       edl->save_xml(&xml_file, xml_filename, 0, 0);
+       edl->save_xml(&xml_file, xml_filename);
        xml_file.terminate_string();
        if( xml_file.write_to_file(xml_filename) ) {
                char msg[BCTEXTLEN];
@@ -287,7 +284,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
                return 1;
        }
 
-       BatchRenderJob *job = new BatchRenderJob(mwindow->preferences);
+       BatchRenderJob *job = new BatchRenderJob(mwindow->preferences, use_label_chapters);
        jobs->append(job);
        strcpy(&job->edl_path[0], xml_filename);
        Asset *asset = job->asset;
@@ -317,7 +314,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
                FFMPEG::load_options(option_path, asset->ff_video_options,
                         sizeof(asset->ff_video_options));
                asset->ff_video_bitrate = vid_bitrate;
-               asset->ff_video_quality = 0;
+               asset->ff_video_quality = -1;
        }
        else {
                sprintf(&asset->path[0],"%s/dvd.m2v", asset_dir);
@@ -335,11 +332,11 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
                asset->vmpeg_preset = 8;
                asset->vmpeg_field_order = 0;
                asset->vmpeg_pframe_distance = 0;
-               job = new BatchRenderJob(mwindow->preferences);
+               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->audio_data = 1;
                asset->format = FILE_AC3;
@@ -353,7 +350,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
                asset->ac3_bitrate = dvd_kaudio_rate;
        }
 
-       job = new BatchRenderJob(mwindow->preferences);
+       job = new BatchRenderJob(mwindow->preferences, 0, 0);
        jobs->append(job);
        job->edl_path[0] = '@';
        strcpy(&job->edl_path[1], script_filename);
@@ -365,6 +362,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
 void CreateDVD_Thread::handle_close_event(int result)
 {
        if( result ) return;
+       mwindow->defaults->update("WORK_DIRECTORY", tmp_path);
        mwindow->batch_render->load_defaults(mwindow->defaults);
        mwindow->undo->update_undo_before();
        KeyFrame keyframe;  char data[BCTEXTLEN];
@@ -409,6 +407,7 @@ void CreateDVD_Thread::handle_close_event(int result)
                                        edit->startproject, edit->length,
                                        PLUGIN_STANDALONE, 0, &keyframe, 0);
                        }
+                       vtrk->optimize();
                }
        }
 
@@ -436,19 +435,22 @@ void CreateDVD_Thread::handle_close_event(int result)
                keyframe.set_data(data);
                insert_video_plugin("Histogram", &keyframe);
        }
-       mwindow->batch_render->reset(1);
-       create_dvd_jobs(&mwindow->batch_render->jobs, tmp_path, asset_title);
-       mwindow->save_backup();
+       char asset_dir[BCTEXTLEN], jobs_path[BCTEXTLEN];
+       snprintf(asset_dir, sizeof(asset_dir), "%s/%s", tmp_path, asset_title);
+       snprintf(jobs_path, sizeof(jobs_path), "%s/dvd.jobs", asset_dir);
+       mwindow->batch_render->reset(jobs_path);
+       int ret = create_dvd_jobs(&mwindow->batch_render->jobs, asset_dir);
        mwindow->undo->update_undo_after(_("create dvd"), LOAD_ALL);
        mwindow->resync_guis();
-       mwindow->batch_render->handle_close_event(0);
+       if( ret ) return;
+       mwindow->batch_render->save_jobs();
        mwindow->batch_render->start();
 }
 
 BC_Window* CreateDVD_Thread::new_gui()
 {
-       memset(tmp_path,0,sizeof(tmp_path));
        strcpy(tmp_path,"/tmp");
+       mwindow->defaults->get("WORK_DIRECTORY", tmp_path);
        memset(asset_title,0,sizeof(asset_title));
        time_t dt;  time(&dt);
        struct tm dtm;  localtime_r(&dt, &dtm);
@@ -491,7 +493,7 @@ BC_Window* CreateDVD_Thread::new_gui()
                        if( output_h != dvd_norms[norm].h ) continue;
                        int aspect = dvd_formats[i].aspect;
                        double dvd_aspect_ratio =
-                               (double)dvd_aspects[aspect].w / dvd_aspects[aspect].h; 
+                               (double)dvd_aspects[aspect].w / dvd_aspects[aspect].h;
                        if( !EQUIV(aspect_ratio, dvd_aspect_ratio) ) continue;
                        has_standard = i;  break;
                }
@@ -575,7 +577,7 @@ CreateDVD_DiskSpace::~CreateDVD_DiskSpace()
 
 int64_t CreateDVD_DiskSpace::tmp_path_space()
 {
-       const char *path = gui->tmp_path->get_text();
+       const char *path = gui->thread->tmp_path;
        if( access(path,R_OK+W_OK) ) return 0;
        struct statfs sfs;
        if( statfs(path, &sfs) ) return 0;
@@ -617,13 +619,15 @@ CreateDVD_TmpPath::~CreateDVD_TmpPath()
 
 int CreateDVD_TmpPath::handle_event()
 {
+       get_text();
        gui->disk_space->update();
        return 1;
 }
 
 
 CreateDVD_AssetTitle::CreateDVD_AssetTitle(CreateDVD_GUI *gui, int x, int y, int w)
- : BC_TextBox(x, y, w, 1, 0, gui->thread->asset_title, 1, MEDIUMFONT)
+ : BC_TextBox(x, y, w, 1, -(int)sizeof(gui->thread->asset_title),
+               gui->thread->asset_title, 1, MEDIUMFONT)
 {
        this->gui = gui;
 }
@@ -632,6 +636,12 @@ CreateDVD_AssetTitle::~CreateDVD_AssetTitle()
 {
 }
 
+int CreateDVD_AssetTitle::handle_event()
+{
+       get_text();
+       return 1;
+}
+
 
 CreateDVD_Deinterlace::CreateDVD_Deinterlace(CreateDVD_GUI *gui, int x, int y)
  : BC_CheckBox(x, y, &gui->thread->use_deinterlace, _("Deinterlace"))
@@ -889,6 +899,7 @@ insert_video_plugin(const char *title, KeyFrame *default_keyframe)
                                edit->startproject, edit->length,
                                PLUGIN_STANDALONE, 0, default_keyframe, 0);
                }
+               vtrk->optimize();
        }
        return 0;
 }
@@ -953,14 +964,13 @@ option_presets()
                                if( !EQUIV(aspect, dvd_aspect) ) use_scale = Rescale::scaled;
                        }
                        for( int i=0; i<trk->plugin_set.size(); ++i ) {
-                               for(Plugin *plugin = (Plugin*)trk->plugin_set[i]->first;
-                                               plugin;
-                                               plugin = (Plugin*)plugin->next) {
-                                       if( !strcmp(plugin->title, _("Deinterlace")) )
+                               for( Plugin *plugin = (Plugin*)trk->plugin_set[i]->first;
+                                               plugin; plugin=(Plugin*)plugin->next ) {
+                                       if( !strcmp(plugin->title, "Deinterlace") )
                                                has_deinterlace = 1;
-                                       if( !strcmp(plugin->title, _("Auto Scale")) ||
-                                           !strcmp(plugin->title, _("Scale Ratio")) ||
-                                           !strcmp(plugin->title, _("Scale")) )
+                                       if( !strcmp(plugin->title, "Auto Scale") ||
+                                           !strcmp(plugin->title, "Scale Ratio") ||
+                                           !strcmp(plugin->title, "Scale") )
                                                has_scale = 1;
                                }
                        }