bd/dvd create upgrades, record quit segv, big trace bug
authorGood Guy <good1.2guy@gmail.com>
Wed, 21 Dec 2016 23:19:18 +0000 (16:19 -0700)
committerGood Guy <good1.2guy@gmail.com>
Wed, 21 Dec 2016 23:19:18 +0000 (16:19 -0700)
cinelerra-5.1/cinelerra/batchrender.C
cinelerra-5.1/cinelerra/batchrender.h
cinelerra-5.1/cinelerra/bdcreate.C
cinelerra-5.1/cinelerra/bdcreate.h
cinelerra-5.1/cinelerra/bdwrite.C
cinelerra-5.1/cinelerra/dvdcreate.C
cinelerra-5.1/cinelerra/record.C
cinelerra-5.1/cinelerra/record.h
cinelerra-5.1/ffmpeg/video/bluray.m2ts
cinelerra-5.1/guicast/bctrace.C

index d0714452cdfd640b4b4a24f73d8ecb682de35c09..19f370e558cf2e8824485b8fd4e25c398d26cfd6 100644 (file)
@@ -140,12 +140,7 @@ void BatchRenderJob::load(FileXML *file)
                        BC_Hash defaults;
                        defaults.load_string(file->read_text());
                        asset->load_defaults(&defaults,
-                               "",
-                               0,
-                               1,
-                               0,
-                               0,
-                               0);
+                               "", 0, 1, 0, 0, 0);
                }
        }
 }
@@ -209,6 +204,7 @@ BatchRenderThread::BatchRenderThread(MWindow *mwindow)
        warn = 1;
        render = 0;
        file_entries = 0;
+       batch_path[0] = 0;
 }
 
 BatchRenderThread::BatchRenderThread()
@@ -224,6 +220,7 @@ BatchRenderThread::BatchRenderThread()
        warn = 1;
        render = 0;
        file_entries = 0;
+       batch_path[0] = 0;
 }
 
 BatchRenderThread::~BatchRenderThread()
@@ -238,9 +235,12 @@ BatchRenderThread::~BatchRenderThread()
        }
 }
 
-void BatchRenderThread::reset(int warn)
+void BatchRenderThread::reset(const char *path)
 {
-       if( warn ) this->warn = 1;
+       if( path ) {
+               strcpy(batch_path, path);
+               warn = 1;
+       }
        current_job = 0;
        rendering_job = -1;
        delete default_job;  default_job = 0;
@@ -254,9 +254,7 @@ void BatchRenderThread::reset(int warn)
 void BatchRenderThread::handle_close_event(int result)
 {
 // Save settings
-       char path[BCTEXTLEN];
-       path[0] = 0;
-       save_jobs(path);
+       save_jobs(batch_path);
        save_defaults(mwindow->defaults);
        reset();
 }
@@ -283,9 +281,7 @@ BC_Window* BatchRenderThread::new_gui()
                }
        }
 
-       char path[BCTEXTLEN];
-       path[0] = 0;
-       load_jobs(path, mwindow->preferences);
+       load_jobs(batch_path, mwindow->preferences);
        load_defaults(mwindow->defaults);
        this->gui = new BatchRenderGUI(mwindow,
                this,
@@ -304,10 +300,9 @@ void BatchRenderThread::load_jobs(char *path, Preferences *preferences)
        int result = 0;
 
        jobs.remove_all_objects();
-       if(path[0])
-               file.read_from_file(path);
-       else
-               file.read_from_file(create_path(path));
+       if( !path ) path = batch_path;
+       if( !path[0] ) create_path(path);
+       file.read_from_file(path);
 
        while(!result)
        {
@@ -344,10 +339,9 @@ void BatchRenderThread::save_jobs(char *path)
        file.append_tag();
        file.append_newline();
 
-       if(path[0])
-               file.write_to_file(path);
-       else
-               file.write_to_file(create_path(path));
+       if( !path ) path = batch_path;
+       if( !path[0] ) create_path(path);
+       file.write_to_file(path);
 }
 
 void BatchRenderThread::load_defaults(BC_Hash *defaults)
@@ -618,6 +612,7 @@ void BatchRenderThread::start_rendering(char *config_path,
        BC_WindowBase::get_resources()->vframe_shm = 1;
 
 //PRINT_TRACE
+       strcpy(this->batch_path, batch_path);
        load_jobs(batch_path, preferences);
        save_jobs(batch_path);
        save_defaults(boot_defaults);
@@ -651,11 +646,9 @@ void BatchRenderThread::start_rendering(char *config_path,
 void BatchRenderThread::start_rendering()
 {
        if(is_rendering) return;
-
        is_rendering = 1;
-       char path[BCTEXTLEN];
-       path[0] = 0;
-       save_jobs(path);
+
+       save_jobs(batch_path);
        save_defaults(mwindow->defaults);
        gui->button_disable();
 
@@ -759,7 +752,7 @@ void BatchRenderThread::trap_hook(FILE *fp, void *vp)
 BatchRenderGUI::BatchRenderGUI(MWindow *mwindow,
        BatchRenderThread *thread, int x, int y, int w, int h)
  : BC_Window(_(PROGRAM_NAME ": Batch Render"),
-       x, y, w, h, 50, 50, 1, 0, 1)
+       x, y, w, h, 730, 400, 1, 0, 1)
 {
        this->mwindow = mwindow;
        this->thread = thread;
@@ -816,6 +809,7 @@ void BatchRenderGUI::create_objects()
        x += new_batch->get_w() + mwindow->theme->widget_border;
        add_subwindow(delete_batch = new BatchRenderDelete(thread, x, y));
        x = x2;  y += delete_batch->get_h() + mwindow->theme->widget_border;
+       y += mwindow->theme->widget_border;
        add_subwindow(savelist_batch = new BatchRenderSaveList(thread, x, y));
        x += savelist_batch->get_w() + mwindow->theme->widget_border;
        add_subwindow(loadlist_batch = new BatchRenderLoadList(thread, x, y));
@@ -826,6 +820,8 @@ void BatchRenderGUI::create_objects()
        x = mwindow->theme->batchrender_x1, y = y1;
 
        add_subwindow(list_title = new BC_Title(x, y, _("Batches to render:")));
+       x1 = x + list_title->get_w() + mwindow->theme->widget_border;;
+       add_subwindow(batch_path = new BC_Title(x1, y, thread->batch_path, MEDIUMFONT, YELLOW));
        y += list_title->get_h() + mwindow->theme->widget_border;
        y1 = get_h();
        y1 -= 15 + BC_GenericButton::calculate_h() + mwindow->theme->widget_border;
@@ -899,6 +895,7 @@ int BatchRenderGUI::resize_event(int w, int h)
        x += savelist_batch->get_w() + mwindow->theme->widget_border;
        loadlist_batch->reposition_window(x, y);
        y += loadlist_batch->get_h() + mwindow->theme->widget_border;
+       warning->reposition_window(x, y);
 
        y1 = 15 + BC_GenericButton::calculate_h() + mwindow->theme->widget_border;
        y2 = get_h() - y1 - batch_list->get_h();
@@ -1100,7 +1097,7 @@ int BatchRenderDelete::handle_event()
 BatchRenderSaveList::BatchRenderSaveList(BatchRenderThread *thread,
        int x,
        int y)
- : BC_GenericButton(x, y, _("Save List"))
+ : BC_GenericButton(x, y, _("Save Jobs"))
 {
        this->thread = thread;
        set_tooltip(_("Save a Batch Render List"));
@@ -1145,9 +1142,9 @@ void BatchRenderSaveList::run()
 {
        char default_path[BCTEXTLEN];
        sprintf(default_path, "~");
-       BC_FileBox filewindow(100, 100,
-                       this->thread->mwindow->defaults->get("DEFAULT_BATCHLOADPATH", default_path),
-                       _("Save Batch Render List"), _("Enter a Batch Render filename to save as:"),
+       thread->mwindow->defaults->get("DEFAULT_BATCHLOADPATH", default_path);
+       BC_FileBox filewindow(100, 100, default_path, _("Save Batch Render List"),
+                       _("Enter a Batch Render filename to save as:"),
                        0, 0, 0, 0);
        gui = &filewindow;
 
@@ -1155,11 +1152,11 @@ void BatchRenderSaveList::run()
        filewindow.create_objects();
 
        int result2 = filewindow.run_window();
-
-       if(!result2)
-       {
-               this->thread->save_jobs(filewindow.get_submitted_path());
-               this->thread->mwindow->defaults->update("DEFAULT_BATCHLOADPATH", filewindow.get_submitted_path());
+       if(!result2) {
+               strcpy(thread->batch_path, filewindow.get_submitted_path());
+               thread->gui->batch_path->update(thread->batch_path);
+               thread->mwindow->defaults->update("DEFAULT_BATCHLOADPATH", thread->batch_path);
+               thread->save_jobs(thread->batch_path);
        }
 
        this->thread->gui->flush();
@@ -1180,7 +1177,7 @@ int BatchRenderSaveList::keypress_event() {
 BatchRenderLoadList::BatchRenderLoadList(BatchRenderThread *thread,
        int x,
        int y)
-  : BC_GenericButton(x, y, _("Load List")),
+  : BC_GenericButton(x, y, _("Load Jobs")),
     Thread()
 {
        this->thread = thread;
@@ -1192,8 +1189,7 @@ BatchRenderLoadList::BatchRenderLoadList(BatchRenderThread *thread,
 BatchRenderLoadList::~BatchRenderLoadList()
 {
        startup_lock->lock("BatchRenderLoadList::~BrowseButton");
-       if(gui)
-       {
+       if(gui) {
                gui->lock_window();
                gui->set_done(1);
                gui->unlock_window();
@@ -1205,10 +1201,8 @@ BatchRenderLoadList::~BatchRenderLoadList()
 
 int BatchRenderLoadList::handle_event()
 {
-       if(Thread::running())
-       {
-               if(gui)
-               {
+       if(Thread::running()) {
+               if(gui) {
                        gui->lock_window();
                        gui->raise_window();
                        gui->unlock_window();
@@ -1226,31 +1220,25 @@ void BatchRenderLoadList::run()
 {
        char default_path[BCTEXTLEN];
        sprintf(default_path, "~");
-       BC_FileBox filewindow(100,
-                             100,
-                             this->thread->mwindow->defaults->get("DEFAULT_BATCHLOADPATH", default_path),
-                             _("Load Batch Render List"),
-                             _("Enter a Batch Render filename to load from:"),
-                             0,
-                             0,
-                             0,
-                             0);
-
+       thread->mwindow->defaults->get("DEFAULT_BATCHLOADPATH", default_path);
+       BC_FileBox filewindow(100, 100, default_path, _("Load Batch Render List"),
+                       _("Enter a Batch Render filename to load from:"),
+                       0, 0, 0, 0);
        gui = &filewindow;
 
        startup_lock->unlock();
        filewindow.create_objects();
 
        int result2 = filewindow.run_window();
-
-       if(!result2)
-       {
-               this->thread->load_jobs(filewindow.get_submitted_path(),this->thread->mwindow->preferences);
-               this->thread->gui->create_list(1);
-               this->thread->mwindow->defaults->update("DEFAULT_BATCHLOADPATH", filewindow.get_submitted_path());
+       if(!result2) {
+               strcpy(thread->batch_path, filewindow.get_submitted_path());
+               thread->gui->batch_path->update(thread->batch_path);
+               thread->mwindow->defaults->update("DEFAULT_BATCHLOADPATH", thread->batch_path);
+               thread->load_jobs(thread->batch_path, thread->mwindow->preferences);
+               thread->gui->create_list(1);
        }
 
-       this->thread->gui->flush();
+       thread->gui->flush();
        startup_lock->lock("BatchRenderLoadList::run");
        gui = 0;
        startup_lock->unlock();
index c24eb088c909690ced7df74cb8c1453c883e5898..09d98052b3b62eeea61066f2767458826d0a94c0 100644 (file)
@@ -92,11 +92,11 @@ public:
        int test_edl_files();
        void calculate_dest_paths(ArrayList<char*> *paths,
                Preferences *preferences);
-       void reset(int warn=0);
+       void reset(const char *path=0);
 // Load batch rendering jobs
        void load_jobs(char *path, Preferences *preferences);
 // Not applicable to western civilizations
-       void save_jobs(char *path);
+       void save_jobs(char *path=0);
        void load_defaults(BC_Hash *defaults);
        void save_defaults(BC_Hash *defaults);
 // Create path for persistent storage functions
@@ -121,6 +121,7 @@ public:
        static void trap_hook(FILE *fp, void *vp);
 
        MWindow *mwindow;
+       char batch_path[BCTEXTLEN];
        double current_start;
        double current_end;
        BatchRenderJob *default_job;
@@ -308,6 +309,7 @@ public:
 //     BC_Title *status_text;
 //     BC_ProgressBar *progress_bar;
        BC_Title *list_title;
+       BC_Title *batch_path;
        BatchRenderNew *new_batch;
        BatchRenderDelete *delete_batch;
        BatchRenderSaveList *savelist_batch;
index fbbd7ee8dd4aabb741ed7c3bef7200f5d0b19929..1bf6dac843d2adff54b09224112ed671a84dc510 100644 (file)
@@ -1,4 +1,5 @@
 #include "asset.h"
+#include "bchash.h"
 #include "bdcreate.h"
 #include "clip.h"
 #include "edl.h"
@@ -7,6 +8,7 @@
 #include "edlsession.h"
 #include "file.h"
 #include "filexml.h"
+#include "interlacemodes.h"
 #include "keyframe.h"
 #include "labels.h"
 #include "mainerror.h"
 
 // BD Creation
 
+// selected by timezone
 #define BD_1920x1080_2997i     0
-#define BD_1920x1080_2500i     1
-#define BD_1920x1080_2400p     2
-#define BD_1920x1080_23976p    3
-#define BD_1280x720_5994p      4
-#define BD_1280x720_5000p      5
-#define BD_1280x720_23976p     6
-#define BD_1280x720_2400p      7
-#define BD_720x576_2500i       8
-#define BD_720x480_2997i       9
+#define BD_1920x1080_25i       3
 
 static struct bd_format {
        const char *name;
        int w, h;
        double framerate;
-       int interlaced, wide;
+       int wide, interlaced;
 } bd_formats[] = {
-       { "1920x1080 29.97i",   1920,1080, 29.97,  1, 1 },
-       { "1920x1080 25i",      1920,1080, 25.,    1, 1 },
-       { "1920x1080 24p",      1920,1080, 24.,    0, 1 },
-       { "1920x1080 23.976p",  1920,1080, 23.976, 0, 1 },
-       { "1440x1080 50i",      1920,1080, 50.,    1, 0 },
-       { "1280x720  59.94p",   1280,720,  59.94,  0, 1 },
-       { "1280x720  50p",      1280,720,  50.,    0, 1 },
-       { "1280x720  23.976p",  1280,720,  23.976, 0, 1 },
-       { "1280x720  24p",      1280,720,  24.,    0, 1 },
-       { "720x576   25i",       720,576,  25.,    1, 0 },
-       { "720x480   29.97i",    720,480,  29.97,  1, 0 },
+// framerates are frames, not fields, per second, *=not standard
+       { "1920x1080 29.97i",   1920,1080, 29.97,  1, ILACE_MODE_TOP_FIRST },
+       { "1920x1080 29.97p*",  1920,1080, 29.97,  1, ILACE_MODE_NOTINTERLACED },
+       { "1920x1080 24p",      1920,1080, 50.,    1, ILACE_MODE_NOTINTERLACED },
+       { "1920x1080 25i",      1920,1080, 25.,    1, ILACE_MODE_TOP_FIRST },
+       { "1920x1080 24p",      1920,1080, 24.,    1, ILACE_MODE_NOTINTERLACED },
+       { "1920x1080 23.976p",  1920,1080, 23.976, 1, ILACE_MODE_NOTINTERLACED },
+       { "1440x1080 29.97i",   1440,1080, 59.94,  0, ILACE_MODE_TOP_FIRST },
+       { "1440x1080 25i",      1440,1080, 50.,    0, ILACE_MODE_TOP_FIRST },
+       { "1440x1080 24p",      1440,1080, 24.,    0, ILACE_MODE_NOTINTERLACED },
+       { "1440x1080 23.976p",  1440,1080, 23.976, 0, ILACE_MODE_NOTINTERLACED },
+       { "1280x720  29.97p",   1280,720,  59.94,  1, ILACE_MODE_NOTINTERLACED },
+       { "1280x720  50p",      1280,720,  50.,    1, ILACE_MODE_NOTINTERLACED },
+       { "1280x720  23.976p",  1280,720,  23.976, 1, ILACE_MODE_NOTINTERLACED },
+       { "1280x720  24p",      1280,720,  24.,    1, ILACE_MODE_NOTINTERLACED },
+       { "720x576   25p*",      720,576,  25.,    0, ILACE_MODE_NOTINTERLACED },
+       { "720x576   25i",       720,576,  25.,    0, ILACE_MODE_BOTTOM_FIRST },
+       { "720x480   29.97p*",   720,480,  29.97,  0, ILACE_MODE_NOTINTERLACED },
+       { "720x480   29.97i",    720,480,  29.97,  0, ILACE_MODE_BOTTOM_FIRST },
 };
 
 const int64_t CreateBD_Thread::BD_SIZE = 25000000000;
@@ -72,6 +75,7 @@ const int CreateBD_Thread::BD_CHANNELS = 2;
 const int CreateBD_Thread::BD_WIDE_CHANNELS = 6;
 const double CreateBD_Thread::BD_SAMPLERATE = 48000;
 const double CreateBD_Thread::BD_KAUDIO_RATE = 224;
+const int CreateBD_Thread::BD_INTERLACE_MODE = ILACE_MODE_NOTINTERLACED;
 
 CreateBD_MenuItem::CreateBD_MenuItem(MWindow *mwindow)
  : BC_MenuItem(_("BD Render..."), _("Ctrl-d"), 'd')
@@ -118,7 +122,7 @@ CreateBD_Thread::~CreateBD_Thread()
 }
 
 int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs,
-       const char *tmp_path, const char *asset_title)
+       const char *asset_dir, const char *asset_title)
 {
        EDL *edl = mwindow->edl;
        if( !edl || !edl->session ) {
@@ -137,9 +141,6 @@ int CreateBD_Thread::create_bd_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));
@@ -161,6 +162,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs,
        session->sample_rate = bd_samplerate;
        session->audio_channels = session->audio_tracks =
                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);
@@ -242,6 +244,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs,
        asset->width = session->output_w;
        asset->height = session->output_h;
        asset->aspect_ratio = session->aspect_w / session->aspect_h;
+       asset->interlace_mode = session->interlace_mode;
 
        char option_path[BCTEXTLEN];
        sprintf(&asset->path[0],"%s/bd.m2ts", asset_dir);
@@ -250,6 +253,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs,
 
        asset->audio_data = 1;
        strcpy(asset->acodec, "bluray.m2ts");
+       //mwindow->defaults->get("DEFAULT_BLURAY_ACODEC", asset->acodec);
        FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec);
        FFMPEG::load_options(option_path, asset->ff_audio_options,
                         sizeof(asset->ff_audio_options));
@@ -257,9 +261,20 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs,
 
        asset->video_data = 1;
        strcpy(asset->vcodec, "bluray.m2ts");
+       //mwindow->defaults->get("DEFAULT_BLURAY_VCODEC", asset->vcodec);
        FFMPEG::set_option_path(option_path, "video/%s", asset->vcodec);
        FFMPEG::load_options(option_path, asset->ff_video_options,
                 sizeof(asset->ff_video_options));
+       const char *opts = 0;
+       switch( asset->interlace_mode ) {
+       case ILACE_MODE_TOP_FIRST:    opts = ":tff\n";  break;
+       case ILACE_MODE_BOTTOM_FIRST: opts = ":bff\n";  break;
+       }
+       if( opts ) {
+               int len = strlen(asset->ff_video_options);
+               char *cp = asset->ff_video_options + len-1;
+               strncpy(cp, opts, sizeof(asset->ff_video_options)-len);
+       }
        asset->ff_video_bitrate = vid_bitrate;
        asset->ff_video_quality = 0;
 
@@ -275,6 +290,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs,
 void CreateBD_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];
@@ -345,19 +361,23 @@ void CreateBD_Thread::handle_close_event(int result)
                keyframe.set_data(data);
                insert_video_plugin("Histogram", &keyframe);
        }
-       mwindow->batch_render->reset(1);
-       create_bd_jobs(&mwindow->batch_render->jobs, tmp_path, asset_title);
-       mwindow->save_backup();
+
+       char asset_dir[BCTEXTLEN], jobs_path[BCTEXTLEN];
+       sprintf(asset_dir, "%s/%s", tmp_path, asset_title);
+       sprintf(jobs_path, "%s/bd.jobs", asset_dir);
+       mwindow->batch_render->reset(jobs_path);
+       int ret = create_bd_jobs(&mwindow->batch_render->jobs, asset_dir, asset_title);
        mwindow->undo->update_undo_after(_("create bd"), 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* CreateBD_Thread::new_gui()
 {
-       memset(tmp_path,0,sizeof(tmp_path));
-       strcpy(tmp_path,"/tmp");
+       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);
@@ -371,8 +391,8 @@ BC_Window* CreateBD_Thread::new_gui()
        use_wide_audio = 0;
        use_resize_tracks = 0;
        use_label_chapters = 0;
-       use_standard = BD_1920x1080_2997i;
-
+       use_standard = !strcmp(mwindow->default_std(),"NTSC") ?
+                BD_1920x1080_2997i : BD_1920x1080_25i;
        bd_size = BD_SIZE;
        bd_width = BD_WIDTH;
        bd_height = BD_HEIGHT;
@@ -382,6 +402,7 @@ BC_Window* CreateBD_Thread::new_gui()
        bd_samplerate = BD_SAMPLERATE;
        bd_max_bitrate = BD_MAX_BITRATE;
        bd_kaudio_rate = BD_KAUDIO_RATE;
+       bd_interlace_mode = BD_INTERLACE_MODE;
        max_w = 0; max_h = 0;
 
        int has_standard = -1;
@@ -625,6 +646,7 @@ CreateBD_GUI::CreateBD_GUI(CreateBD_Thread *thread, int x, int y, int w, int h)
        need_inverse_telecine = 0;
        need_resize_tracks = 0;
        need_histogram = 0;
+       non_standard = 0;
        need_wide_audio = 0;
        need_label_chapters = 0;
        ok = 0;
@@ -676,6 +698,7 @@ void CreateBD_GUI::create_objects()
        standard = new CreateBD_Format(this, title->get_w() + padx, y);
        add_subwindow(standard);
        standard->create_objects();
+       standard->set_text(bd_formats[thread->use_standard].name);
        x0 -= 30;
        title = new BC_Title(x0, y, _("Scale:"), MEDIUMFONT, YELLOW);
        add_subwindow(title);
@@ -695,6 +718,8 @@ void CreateBD_GUI::create_objects()
        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);
+       add_subwindow(non_standard);
        need_resize_tracks = new CreateBD_ResizeTracks(this, x1, y);
        add_subwindow(need_resize_tracks);
 //     need_label_chapters = new CreateBD_LabelChapters(this, x2, y);
@@ -805,6 +830,7 @@ option_presets()
                BD_WIDE_ASPECT_WIDTH : BD_ASPECT_WIDTH;
        bd_aspect_height = bd_formats[use_standard].wide ?
                BD_WIDE_ASPECT_HEIGHT : BD_ASPECT_HEIGHT;
+       bd_interlace_mode = bd_formats[use_standard].interlaced;
        double bd_aspect = bd_aspect_width / bd_aspect_height;
 
        Tracks *tracks = mwindow->edl->tracks;
@@ -884,8 +910,20 @@ CreateBD_FormatItem::~CreateBD_FormatItem()
 
 int CreateBD_FormatItem::handle_event()
 {
-       popup->set_text(get_text());
+       const char *text = get_text();
+       int standard = this->standard;
+       if( standard < 0 ) {
+               BC_SubMenu *submenu = get_submenu();
+               CreateBD_FormatItem *sub_item0 =
+                       (CreateBD_FormatItem *)submenu->get_item(0);
+               standard = sub_item0->standard;
+               text = sub_item0->get_text();
+       }
        popup->gui->thread->use_standard = standard;
+       popup->set_text(text);
+       int n = strlen(text)-1;
+       int not_standard = n >= 0 && text[n] == '*' ? 1 : 0;
+       popup->gui->non_standard->update(not_standard ? _("* non-standard format") : "", 0);
        return popup->handle_event();
 }
 
@@ -902,8 +940,18 @@ CreateBD_Format::~CreateBD_Format()
 
 void CreateBD_Format::create_objects()
 {
+       BC_SubMenu *submenu = 0;
+       CreateBD_FormatItem *item = 0;
+       int ww = 0, hh = 0;
        for( int i=0; i<(int)(sizeof(bd_formats)/sizeof(bd_formats[0])); ++i ) {
-               add_item(new CreateBD_FormatItem(this, i, bd_formats[i].name));
+               if( ww != bd_formats[i].w || hh != bd_formats[i].h ) {
+                       ww = bd_formats[i].w;  hh = bd_formats[i].h;
+                       char string[BCSTRLEN];
+                       sprintf(string, "%dx%d", ww,hh);
+                       add_item(item = new CreateBD_FormatItem(this, -1, string));
+                       item->add_submenu(submenu = new BC_SubMenu());
+               }
+               submenu->add_submenuitem(new CreateBD_FormatItem(this, i, bd_formats[i].name));
        }
        set_value(gui->thread->use_standard);
 }
index 7efb242169ef25483ee767f9e5ec3cf6bfc3f7e3..29a08db85f6e1939db8182aa06371ff107595bcd 100644 (file)
@@ -33,6 +33,7 @@ class CreateBD_Thread : public BC_DialogThread
        static const double BD_WIDE_ASPECT_WIDTH, BD_WIDE_ASPECT_HEIGHT;
        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;
 public:
        CreateBD_Thread(MWindow *mwindow);
        ~CreateBD_Thread();
@@ -63,6 +64,7 @@ public:
        int bd_samplerate;
        int bd_max_bitrate;
        double bd_kaudio_rate;
+       int bd_interlace_mode;
        int max_w, max_h;
 };
 
@@ -203,6 +205,7 @@ public:
        CreateBD_InverseTelecine *need_inverse_telecine;
        CreateBD_ResizeTracks *need_resize_tracks;
        CreateBD_Histogram *need_histogram;
+       BC_Title *non_standard;
        CreateBD_WideAudio *need_wide_audio;
        CreateBD_LabelChapters *need_label_chapters;
        int ok_x, ok_y, ok_w, ok_h;
index 6d25a52a3e747d1b91788693975984ebb61403d0..e2bab71dc9a628107098cd7941dac124c5c4af60 100644 (file)
@@ -2424,13 +2424,14 @@ static int bd_audio_rate(int rate)
 
 static int bd_video_format(int w, int h, int ilace)
 {
-  if( w == 720 && h == 480 && ilace ) return BLURAY_VIDEO_FORMAT_480I;
-  if( w == 720 && h == 576 && ilace ) return BLURAY_VIDEO_FORMAT_576I;
-  if( w == 720 && h == 480 && !ilace ) return BLURAY_VIDEO_FORMAT_480P;
-  if( w == 1440 && h == 1080 && ilace ) return BLURAY_VIDEO_FORMAT_1080I;
-  if( w == 1280 && h == 720 && !ilace ) return BLURAY_VIDEO_FORMAT_720P;
-  if( w == 1920 && h == 1080 && !ilace ) return BLURAY_VIDEO_FORMAT_1080P;
-  if( w == 720 && h == 576 && !ilace ) return BLURAY_VIDEO_FORMAT_576P;
+  if( w ==  720 && h ==  480    &&  ilace   ) return BLURAY_VIDEO_FORMAT_480I;
+  if( w ==  720 && h ==  576    &&  ilace   ) return BLURAY_VIDEO_FORMAT_576I;
+  if( w ==  720 && h ==  480    && !ilace   ) return BLURAY_VIDEO_FORMAT_480P;
+  if( w ==  720 && h ==  576    && !ilace   ) return BLURAY_VIDEO_FORMAT_576P;
+// this seems to be overly restrictive
+  if( w == 1280 && h ==  720 /* && !ilace*/ ) return BLURAY_VIDEO_FORMAT_720P;
+  if( w == 1440 && h == 1080 /* &&  ilace*/ ) return BLURAY_VIDEO_FORMAT_1080I;
+  if( w == 1920 && h == 1080 /* && !ilace*/ ) return BLURAY_VIDEO_FORMAT_1080P;
   fprintf(stderr, "unknown bluray video format %dx%d %silace\n",
     w, h, !ilace ? "not " : "");
   exit(1);
@@ -2458,6 +2459,46 @@ static int bd_aspect_ratio(int w, int h, double ratio)
   exit(1);
 }
 
+static int field_probe(AVFormatContext *fmt_ctx, AVStream *st)
+{
+  AVDictionary *copts = 0;
+  //av_dict_copy(&copts, opts, 0);
+  AVCodecID codec_id = st->codec->codec_id;
+  AVCodec *decoder = avcodec_find_decoder(codec_id);
+  if( avcodec_open2(st->codec, decoder, &copts) < 0 ) {
+    fprintf(stderr,"codec open failed\n");
+    return -1;
+  }
+  av_dict_free(&copts);
+
+  AVFrame *ipic = av_frame_alloc();
+  AVPacket ipkt;
+  av_init_packet(&ipkt);
+  int ilaced = -1;
+  for( int retrys=100; --retrys>=0 && ilaced<0; ) {
+    av_packet_unref(&ipkt);
+    int ret = av_read_frame(fmt_ctx, &ipkt);
+    if( ret == AVERROR_EOF ) break;
+    if( ret != 0 ) continue;
+    if( !ipkt.data ) continue;
+    if( ipkt.stream_index != st->index ) continue;
+    while( ipkt.size > 0 ) {
+      int got_frame = 0;
+      ret = avcodec_decode_video2(st->codec, ipic, &got_frame, &ipkt);
+      if( ret <= 0 ) break;
+      if( got_frame ) {
+        ilaced = ipic->interlaced_frame ? 1 : 0;
+        break;
+      }
+      ipkt.data += ret;
+      ipkt.size -= ret;
+    }
+  }
+  av_packet_unref(&ipkt);
+  av_frame_free(&ipic);
+  return ilaced;
+}
+
 int media_info::scan()
 {
   struct stat st;
@@ -2492,8 +2533,12 @@ int media_info::scan()
     case AVMEDIA_TYPE_VIDEO: {
       if( ep_pid < 0 ) ep_pid = st->id;
       s->coding_type = bd_stream_type(codec_id);
-      s->format = bd_video_format(st->codec->width, st->codec->height,
-               st->codec->flags & CODEC_FLAG_INTERLACED_ME);
+      int ilace = field_probe(fmt_ctx, st);
+      if( ilace < 0 ) {
+        fprintf(stderr, "interlace probe failed\n");
+        exit(1);
+      }
+      s->format = bd_video_format(st->codec->width, st->codec->height, ilace);
       s->rate = bd_video_rate(!st->codec->framerate.den ? 0 :
                (double)st->codec->framerate.num / st->codec->framerate.den);
       s->aspect = bd_aspect_ratio(st->codec->width, st->codec->height,
index 6b7bccd31f4307464af6d1fd2ca4dd8167b761d6..f3c817a38a87ce6d81f6849b51d201dff7c86005 100644 (file)
@@ -1,4 +1,5 @@
 #include "asset.h"
+#include "bchash.h"
 #include "clip.h"
 #include "dvdcreate.h"
 #include "edl.h"
@@ -126,7 +127,7 @@ CreateDVD_Thread::~CreateDVD_Thread()
 }
 
 int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
-       const char *tmp_path, const char *asset_title)
+       const char *asset_dir, const char *asset_title)
 {
        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));
@@ -365,6 +363,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];
@@ -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];
+       sprintf(asset_dir, "%s/%s", tmp_path, asset_title);
+       sprintf(jobs_path, "%s/dvd.jobs", asset_dir);
+       mwindow->batch_render->reset(jobs_path);
+       int ret = create_dvd_jobs(&mwindow->batch_render->jobs, asset_dir, asset_title);
        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);
index 1c9f6ecd1376e80e6b14c54effa3f427ea982ce9..50cfb74136e5107ec9f8604838e85b4890bb05ce 100644 (file)
@@ -163,7 +163,7 @@ Record::Record(MWindow *mwindow, RecordMenuItem *menu_item)
 Record::~Record()
 {
        mwindow->gui->record = 0;
-       stop();  join();
+       stop();
        delete blink_status;
        delete cutads_status;
        stop_skimming();
@@ -369,7 +369,7 @@ void Record::run()
                if( channel )
                        video_stream = channel->video_stream;
        }
-       stop();
+       stop(0);
        edl->Garbage::remove_user();
 
        if( mwindow->gui->remote_control->deactivate() )
@@ -433,9 +433,12 @@ void Record::run()
        default_asset->Garbage::remove_user();
 }
 
-void Record::stop()
+void Record::stop(int wait)
 {
        stop_operation();
+       if( wait && running() )
+               record_gui->set_done(1);
+       join();
        window_lock->lock("Record::stop");
        delete record_thread;   record_thread = 0;
        delete record_monitor;  record_monitor = 0;
@@ -588,7 +591,6 @@ void Record::start()
                window_lock->unlock();
        }
        else {
-               stop();  join();
                init_lock->reset();
                Thread::start();
        }
index eb4eefed85f4c57bd7b78e3de45978fd654b641e..423b4b09de07831e65994325406fa0ccc91720b6 100644 (file)
@@ -98,7 +98,7 @@ public:
        ~Record();
 
        void run();
-       void stop();
+       void stop(int wait=1);
        int load_defaults();
        int save_defaults();
        Batch* new_batch();
index 90de1b93317e6a96d1ff8bb5c0bf559947a8f6fa..d484e8ec8358671a8342d21314260764df19d485 100644 (file)
@@ -1,7 +1,8 @@
 mpegts libx264
 id=0x1011
-profile=baseline
+profile=high
 level=3.0
 preset=medium
 bluray-compat=1
+# must be last for bdcreate.C
 x264opts keyint=25:min-keyint=4:qpmin=3:qpmax=33:qp_step=4:merange=8
index 9a0061fe331b7f9de68677163adb58b325d62848..47638fe9a6955f21b473016aa958b1035959bd13 100644 (file)
@@ -185,7 +185,7 @@ void BC_Trace::unset_all_locks(trace_info *info)
        while( p ) {
                lock_item *lp = p;  p = (lock_item*)p->next;
                if( lp->info != info ) continue;
-               lock_table.remove_pointer(p);  lock_free.append(p);
+               lock_table.remove_pointer(lp);  lock_free.append(lp);
        }
        lock_table.unlock();
 }
@@ -198,7 +198,7 @@ void BC_Trace::clear_locks_tid(pthread_t tid)
        while( p ) {
                lock_item *lp = p;  p = (lock_item*)p->next;
                if( lp->tid != tid ) continue;
-               lock_table.remove_pointer(p);  lock_free.append(p);
+               lock_table.remove_pointer(lp);  lock_free.append(lp);
        }
        lock_table.unlock();
 }