From ddabb22a495f457ece1d845fe2c32ddf2fc27b58 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 21 Dec 2016 16:19:18 -0700 Subject: [PATCH] bd/dvd create upgrades, record quit segv, big trace bug --- cinelerra-5.1/cinelerra/batchrender.C | 108 ++++++++++------------ cinelerra-5.1/cinelerra/batchrender.h | 6 +- cinelerra-5.1/cinelerra/bdcreate.C | 118 +++++++++++++++++-------- cinelerra-5.1/cinelerra/bdcreate.h | 3 + cinelerra-5.1/cinelerra/bdwrite.C | 63 +++++++++++-- cinelerra-5.1/cinelerra/dvdcreate.C | 20 +++-- cinelerra-5.1/cinelerra/record.C | 10 ++- cinelerra-5.1/cinelerra/record.h | 2 +- cinelerra-5.1/ffmpeg/video/bluray.m2ts | 3 +- cinelerra-5.1/guicast/bctrace.C | 4 +- 10 files changed, 214 insertions(+), 123 deletions(-) diff --git a/cinelerra-5.1/cinelerra/batchrender.C b/cinelerra-5.1/cinelerra/batchrender.C index d0714452..19f370e5 100644 --- a/cinelerra-5.1/cinelerra/batchrender.C +++ b/cinelerra-5.1/cinelerra/batchrender.C @@ -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(); diff --git a/cinelerra-5.1/cinelerra/batchrender.h b/cinelerra-5.1/cinelerra/batchrender.h index c24eb088..09d98052 100644 --- a/cinelerra-5.1/cinelerra/batchrender.h +++ b/cinelerra-5.1/cinelerra/batchrender.h @@ -92,11 +92,11 @@ public: int test_edl_files(); void calculate_dest_paths(ArrayList *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; diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C index fbbd7ee8..1bf6dac8 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.C +++ b/cinelerra-5.1/cinelerra/bdcreate.C @@ -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" @@ -27,34 +29,35 @@ // 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 *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 *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 *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 *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 *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 *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 *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); } diff --git a/cinelerra-5.1/cinelerra/bdcreate.h b/cinelerra-5.1/cinelerra/bdcreate.h index 7efb2421..29a08db8 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.h +++ b/cinelerra-5.1/cinelerra/bdcreate.h @@ -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; diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C index 6d25a52a..e2bab71d 100644 --- a/cinelerra-5.1/cinelerra/bdwrite.C +++ b/cinelerra-5.1/cinelerra/bdwrite.C @@ -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, diff --git a/cinelerra-5.1/cinelerra/dvdcreate.C b/cinelerra-5.1/cinelerra/dvdcreate.C index 6b7bccd3..f3c817a3 100644 --- a/cinelerra-5.1/cinelerra/dvdcreate.C +++ b/cinelerra-5.1/cinelerra/dvdcreate.C @@ -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 *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 *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 *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); diff --git a/cinelerra-5.1/cinelerra/record.C b/cinelerra-5.1/cinelerra/record.C index 1c9f6ecd..50cfb741 100644 --- a/cinelerra-5.1/cinelerra/record.C +++ b/cinelerra-5.1/cinelerra/record.C @@ -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(); } diff --git a/cinelerra-5.1/cinelerra/record.h b/cinelerra-5.1/cinelerra/record.h index eb4eefed..423b4b09 100644 --- a/cinelerra-5.1/cinelerra/record.h +++ b/cinelerra-5.1/cinelerra/record.h @@ -98,7 +98,7 @@ public: ~Record(); void run(); - void stop(); + void stop(int wait=1); int load_defaults(); int save_defaults(); Batch* new_batch(); diff --git a/cinelerra-5.1/ffmpeg/video/bluray.m2ts b/cinelerra-5.1/ffmpeg/video/bluray.m2ts index 90de1b93..d484e8ec 100644 --- a/cinelerra-5.1/ffmpeg/video/bluray.m2ts +++ b/cinelerra-5.1/ffmpeg/video/bluray.m2ts @@ -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 diff --git a/cinelerra-5.1/guicast/bctrace.C b/cinelerra-5.1/guicast/bctrace.C index 9a0061fe..47638fe9 100644 --- a/cinelerra-5.1/guicast/bctrace.C +++ b/cinelerra-5.1/guicast/bctrace.C @@ -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(); } -- 2.26.2