From 198530fac4797a9338e91f342939468efffa4eb2 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Thu, 28 Apr 2016 17:40:10 -0600 Subject: [PATCH] BD/DVD render setup upgrades --- cinelerra-5.1/cinelerra/bdcreate.C | 225 +++++++++++++++++++--- cinelerra-5.1/cinelerra/bdcreate.h | 51 ++++- cinelerra-5.1/cinelerra/bdcreate.inc | 16 ++ cinelerra-5.1/cinelerra/defaultformats.h | 26 +-- cinelerra-5.1/cinelerra/dvdcreate.C | 235 ++++++++++++++++++++--- cinelerra-5.1/cinelerra/dvdcreate.h | 51 ++++- cinelerra-5.1/cinelerra/dvdcreate.inc | 17 ++ cinelerra-5.1/cinelerra/interlacemodes.C | 2 +- cinelerra-5.1/cinelerra/mwindow.C | 51 +++-- cinelerra-5.1/cinelerra/mwindow.inc | 5 - cinelerra-5.1/cinelerra/mwindowgui.inc | 5 + cinelerra-5.1/guicast/bootstrap.c | 1 + 12 files changed, 571 insertions(+), 114 deletions(-) diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C index f7453803..279449e0 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.C +++ b/cinelerra-5.1/cinelerra/bdcreate.C @@ -1,5 +1,6 @@ #include "asset.h" #include "bdcreate.h" +#include "clip.h" #include "edl.h" #include "edit.h" #include "edits.h" @@ -25,6 +26,34 @@ // BD Creation +#define BD_1920x1080_2997i 0 +#define BD_1920x1080_2500i 1 +#define BD_1920x1080_2400p 2 +#define BD_1920x1080_23976p 3 +#define BD_1280x720_5997p 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 + +static struct bd_format { + const char *name; + int w, h; + double framerate; +} bd_formats[] = { + { "1920x1080 29.97i", 1920,1080, 29.97 }, + { "1920x1080 25i", 1920,1080, 25 }, + { "1920x1080 24p", 1920,1080, 24 }, + { "1920x1080 23.976p", 1920,1080, 23.976 }, + { "1280x720 59.97p", 1280,720, 59.97 }, + { "1280x720 50p", 1280,720, 50 }, + { "1280x720 23.976p", 1280,720, 23.976 }, + { "1280x720 24p", 1280,720, 24 }, + { "720x576 25i (PAL)", 720,576, 25 }, + { "720x480 29.97i (NTSC)", 720,480, 29.97 }, +}; + const int64_t CreateBD_Thread::BD_SIZE = 25000000000; const int CreateBD_Thread::BD_STREAMS = 1; const int CreateBD_Thread::BD_WIDTH = 1920; @@ -62,12 +91,12 @@ CreateBD_Thread::CreateBD_Thread(MWindow *mwindow) this->mwindow = mwindow; this->gui = 0; this->use_deinterlace = 0; - this->use_inverse_telecine = 0; this->use_scale = 0; - this->use_resize_tracks = 0; this->use_histogram = 0; + this->use_inverse_telecine = 0; this->use_wide_audio = 0; this->use_wide_aspect = 0; + this->use_resize_tracks = 0; this->use_label_chapters = 0; } @@ -112,13 +141,12 @@ int CreateBD_Thread::create_bd_jobs(ArrayList *jobs, session->video_channels = BD_STREAMS; session->video_tracks = BD_STREAMS; -// use session framerate -// session->frame_rate = BD_FRAMERATE; - session->output_w = BD_WIDTH; - session->output_h = BD_HEIGHT; - session->aspect_w = use_wide_aspect ? BD_WIDE_ASPECT_WIDTH : BD_ASPECT_WIDTH; - session->aspect_h = use_wide_aspect ? BD_WIDE_ASPECT_HEIGHT : BD_ASPECT_HEIGHT; - session->sample_rate = BD_SAMPLERATE; + session->frame_rate = bd_framerate; + session->output_w = bd_width; + session->output_h = bd_height; + session->aspect_w = bd_aspect_width; + session->aspect_h = bd_aspect_height; + session->sample_rate = bd_samplerate; session->audio_channels = session->audio_tracks = use_wide_audio ? BD_WIDE_CHANNELS : BD_CHANNELS; @@ -174,11 +202,11 @@ int CreateBD_Thread::create_bd_jobs(ArrayList *jobs, edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO); edl->resample(old_framerate, new_framerate, TRACK_VIDEO); - int64_t aud_size = ((BD_KAUDIO_RATE * total_length)/8 + 1000-1) * 1000; - int64_t vid_size = BD_SIZE*0.96 - aud_size; + int64_t aud_size = ((bd_kaudio_rate * total_length)/8 + 1000-1) * 1000; + int64_t vid_size = bd_size*0.96 - aud_size; int64_t vid_bitrate = (vid_size * 8) / total_length; vid_bitrate /= 1000; vid_bitrate *= 1000; - if( vid_bitrate > BD_MAX_BITRATE ) vid_bitrate = BD_MAX_BITRATE; + if( vid_bitrate > bd_max_bitrate ) vid_bitrate = bd_max_bitrate; char xml_filename[BCTEXTLEN]; sprintf(xml_filename, "%s/bd.xml", asset_dir); @@ -213,7 +241,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList *jobs, FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec); FFMPEG::load_options(option_path, asset->ff_audio_options, sizeof(asset->ff_audio_options)); - asset->ff_audio_bitrate = BD_KAUDIO_RATE * 1000; + asset->ff_audio_bitrate = bd_kaudio_rate * 1000; asset->video_data = 1; strcpy(asset->vcodec, "bluray.m2ts"); @@ -251,7 +279,7 @@ void CreateBD_Thread::handle_close_event(int result) } if( use_scale ) { sprintf(data,"", BD_WIDTH, BD_HEIGHT); + " WIDTH=%d HEIGHT=%d CONSTRAIN=0>", bd_width, bd_height); keyframe.set_data(data); insert_video_plugin("Scale", &keyframe); } @@ -299,18 +327,43 @@ BC_Window* CreateBD_Thread::new_gui() dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, dtm.tm_hour, dtm.tm_min, dtm.tm_sec); use_deinterlace = 0; - use_inverse_telecine = 0; use_scale = 0; - use_resize_tracks = 0; use_histogram = 0; + use_inverse_telecine = 0; use_wide_audio = 0; use_wide_aspect = 0; + use_resize_tracks = 0; use_label_chapters = 0; + use_standard = BD_1920x1080_2997i; + + bd_size = BD_SIZE; + bd_width = BD_WIDTH; + bd_height = BD_HEIGHT; + bd_aspect_width = BD_ASPECT_WIDTH; + bd_aspect_height = BD_ASPECT_HEIGHT; + bd_framerate = BD_FRAMERATE; + bd_samplerate = BD_SAMPLERATE; + bd_max_bitrate = BD_MAX_BITRATE; + bd_kaudio_rate = BD_KAUDIO_RATE; + + int has_standard = -1; + if( mwindow->edl ) { + EDLSession *session = mwindow->edl->session; +// match the session to any known standard + for( int i=0; i<(int)(sizeof(bd_formats)/sizeof(bd_formats[0])); ++i ) { + if( !EQUIV(session->frame_rate, bd_formats[i].framerate) ) continue; + if( session->output_w != bd_formats[i].w ) continue; + if( session->output_h != bd_formats[i].h ) continue; + has_standard = i; break; + } + } + use_standard = has_standard >= 0 ? has_standard : BD_1920x1080_2400p; + option_presets(); int scr_x = mwindow->gui->get_screen_x(0, -1); int scr_w = mwindow->gui->get_screen_w(0, -1); int scr_h = mwindow->gui->get_screen_h(0, -1); - int w = 500, h = 250; + int w = 500, h = 280; int x = scr_x + scr_w/2 - w/2, y = scr_h/2 - h/2; gui = new CreateBD_GUI(this, x, y, w, h); @@ -386,10 +439,17 @@ int64_t CreateBD_DiskSpace::tmp_path_space() void CreateBD_DiskSpace::update() { -// gui->disk_space->set_color(get_bg_color()); - int64_t disk_space = tmp_path_space(); - int color = disk_spaceneeded_disk_space ? RED : GREEN; static const char *suffix[] = { "", "KB", "MB", "GB", "TB", "PB" }; + int64_t disk_space = tmp_path_space(); + double media_size = 100e9, msz = 0, m = 1; + char sfx[BCSTRLEN]; + if( sscanf(gui->media_size->get_text(), "%lf%s", &msz, sfx) == 2 ) { + int i = sizeof(suffix)/sizeof(suffix[0]); + while( --i >= 0 && strcmp(sfx, suffix[i]) ); + while( --i >= 0 ) m *= 1000; + media_size = msz * m; + } + int color = disk_space < media_size*2 ? RED : GREEN; int i = 0; for( int64_t space=disk_space; i<5 && (space/=1000)>0; disk_space=space, ++i ); char text[BCTEXTLEN]; @@ -541,7 +601,6 @@ CreateBD_GUI::CreateBD_GUI(CreateBD_Thread *thread, int x, int y, int w, int h) asset_title = 0; tmp_path = 0; disk_space = 0; - needed_disk_space = 100e9; need_deinterlace = 0; need_inverse_telecine = 0; need_scale = 0; @@ -578,8 +637,26 @@ void CreateBD_GUI::create_objects() y += title->get_h() + pady/2; disk_space = new CreateBD_DiskSpace(this, x, y); add_subwindow(disk_space); + int x0 = get_w() - 170; + title = new BC_Title(x0, y, _("Media:"), MEDIUMFONT, YELLOW); + add_subwindow(title); + x0 += title->get_w() + padx; + media_size = new CreateBD_MediaSize(this, x0, y); + media_size->create_objects(); + media_sizes.append(new BC_ListBoxItem("25GB")); + media_sizes.append(new BC_ListBoxItem("50GB")); + media_size->update_list(&media_sizes); + media_size->update(media_sizes[0]->get_text()); disk_space->update(); + x0 = x; y += disk_space->get_h() + pady/2; + title = new BC_Title(x0, y, _("Format:"), MEDIUMFONT, YELLOW); + add_subwindow(title); + x0 += title->get_w() + padx; + standard = new CreateBD_Format(this, x0, y); + add_subwindow(standard); + standard->create_objects(); + y += standard->get_h() + pady/2; need_deinterlace = new CreateBD_Deinterlace(this, x, y); add_subwindow(need_deinterlace); int x1 = x + 150, x2 = x1 + 150; @@ -638,6 +715,18 @@ int CreateBD_GUI::close_event() return 1; } +void CreateBD_GUI::update() +{ + need_deinterlace->set_value(thread->use_deinterlace); + need_inverse_telecine->set_value(thread->use_inverse_telecine); + need_scale->set_value(thread->use_scale); + 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_wide_aspect->set_value(thread->use_wide_aspect); +// need_label_chapters->set_value(thread->use_label_chapters); +} + int CreateBD_Thread:: insert_video_plugin(const char *title, KeyFrame *default_keyframe) { @@ -689,7 +778,20 @@ resize_tracks() int CreateBD_Thread:: option_presets() { +// reset only probed options + use_deinterlace = 0; + use_scale = 0; + use_resize_tracks = 0; + use_wide_audio = 0; + use_wide_aspect = 0; + use_label_chapters = 0; + if( !mwindow->edl ) return 1; + + bd_width = bd_formats[use_standard].w; + bd_height = bd_formats[use_standard].h; + bd_framerate = bd_formats[use_standard].framerate; + Tracks *tracks = mwindow->edl->tracks; int max_w = 0, max_h = 0; int has_deinterlace = 0, has_scale = 0; @@ -703,10 +805,10 @@ option_presets() Indexable *indexable = edit->get_source(); int w = indexable->get_w(); if( w > max_w ) max_w = w; - if( w != BD_WIDTH ) use_scale = 1; + if( w != bd_width ) use_scale = 1; int h = indexable->get_h(); if( h > max_h ) max_h = h; - if( h != BD_HEIGHT ) use_scale = 1; + if( h != bd_height ) use_scale = 1; } for( int i=0; iplugin_set.size(); ++i ) { for(Plugin *plugin = (Plugin*)trk->plugin_set[i]->first; @@ -725,8 +827,8 @@ option_presets() if( has_scale ) use_scale = 0; if( use_scale ) { - if( max_w != BD_WIDTH ) use_resize_tracks = 1; - if( max_h != BD_HEIGHT ) use_resize_tracks = 1; + if( max_w != bd_width ) use_resize_tracks = 1; + if( max_h != bd_height ) use_resize_tracks = 1; } for( Track *trk=tracks->first; trk && !use_resize_tracks; trk=trk->next ) { if( !trk->record ) continue; @@ -737,15 +839,80 @@ option_presets() break; } } - if( !has_deinterlace && max_h > 2*BD_HEIGHT ) use_deinterlace = 1; + if( !has_deinterlace && max_h > 2*bd_height ) use_deinterlace = 1; // Labels *labels = mwindow->edl->labels; // use_label_chapters = labels && labels->first ? 1 : 0; - float w, h; - MWindow::create_aspect_ratio(w, h, max_w, max_h); - if( w == BD_WIDE_ASPECT_WIDTH && h == BD_WIDE_ASPECT_HEIGHT ) + float aw, ah; + MWindow::create_aspect_ratio(aw, ah, max_w, max_h); + if( aw == BD_WIDE_ASPECT_WIDTH && ah == BD_WIDE_ASPECT_HEIGHT ) use_wide_aspect = 1; + bd_aspect_width = use_wide_aspect ? BD_WIDE_ASPECT_WIDTH : BD_ASPECT_WIDTH; + bd_aspect_height = use_wide_aspect ? BD_WIDE_ASPECT_HEIGHT : BD_ASPECT_HEIGHT; + if( tracks->recordable_audio_tracks() == BD_WIDE_CHANNELS ) use_wide_audio = 1; + return 0; } + +CreateBD_FormatItem::CreateBD_FormatItem(CreateBD_Format *popup, + int standard, const char *name) + : BC_MenuItem(name) +{ + this->popup = popup; + this->standard = standard; +} + +CreateBD_FormatItem::~CreateBD_FormatItem() +{ +} + +int CreateBD_FormatItem::handle_event() +{ + popup->set_text(get_text()); + popup->gui->thread->use_standard = standard; + return popup->handle_event(); +} + + +CreateBD_Format::CreateBD_Format(CreateBD_GUI *gui, int x, int y) + : BC_PopupMenu(x, y, 180, bd_formats[gui->thread->use_standard].name, 1) +{ + this->gui = gui; +} + +CreateBD_Format::~CreateBD_Format() +{ +} + +void CreateBD_Format::create_objects() +{ + 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)); + } +} + +int CreateBD_Format::handle_event() +{ + gui->thread->option_presets(); + gui->update(); + return 1; +} + +CreateBD_MediaSize::CreateBD_MediaSize(CreateBD_GUI *gui, int x, int y) + : BC_PopupTextBox(gui, 0, 0, x, y, 70,50) +{ + this->gui = gui; +} + +CreateBD_MediaSize::~CreateBD_MediaSize() +{ +} + +int CreateBD_MediaSize::handle_event() +{ + gui->disk_space->update(); + return 1; +} + diff --git a/cinelerra-5.1/cinelerra/bdcreate.h b/cinelerra-5.1/cinelerra/bdcreate.h index cdea0665..289c3026 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.h +++ b/cinelerra-5.1/cinelerra/bdcreate.h @@ -6,6 +6,7 @@ #include "bcwindowbase.h" #include "bcbutton.h" #include "bcdialog.h" +#include "bclistboxitem.inc" #include "bcmenuitem.h" #include "bctextbox.h" #include "mwindow.h" @@ -13,8 +14,6 @@ #include "bdcreate.inc" - - class CreateBD_MenuItem : public BC_MenuItem { public: @@ -51,6 +50,17 @@ public: int use_scale, use_resize_tracks; int use_wide_audio, use_wide_aspect; int use_histogram, use_label_chapters; + int use_standard; + + int64_t bd_size; + int bd_width; + int bd_height; + double bd_aspect_width; + double bd_aspect_height; + double bd_framerate; + int bd_samplerate; + int bd_max_bitrate; + double bd_kaudio_rate; }; class CreateBD_OK : public BC_OKButton @@ -191,14 +201,17 @@ public: int resize_event(int w, int h); int translation_event(); int close_event(); + void update(); - int64_t needed_disk_space; CreateBD_Thread *thread; int at_x, at_y; CreateBD_AssetTitle *asset_title; int tmp_x, tmp_y; CreateBD_TmpPath *tmp_path; CreateBD_DiskSpace *disk_space; + CreateBD_Format *standard; + ArrayList media_sizes; + CreateBD_MediaSize *media_size; CreateBD_Deinterlace *need_deinterlace; CreateBD_InverseTelecine *need_inverse_telecine; CreateBD_Scale *need_scale; @@ -213,4 +226,36 @@ public: CreateBD_Cancel *cancel; }; +class CreateBD_FormatItem : public BC_MenuItem +{ +public: + int handle_event(); + CreateBD_FormatItem(CreateBD_Format *popup, int standard, const char *name); + ~CreateBD_FormatItem(); + + CreateBD_Format *popup; + int standard; +}; + +class CreateBD_Format : public BC_PopupMenu +{ +public: + void create_objects(); + int handle_event(); + CreateBD_Format(CreateBD_GUI *gui, int x, int y); + ~CreateBD_Format(); + + CreateBD_GUI *gui; +}; + +class CreateBD_MediaSize : public BC_PopupTextBox +{ +public: + CreateBD_MediaSize(CreateBD_GUI *gui, int x, int y); + ~CreateBD_MediaSize(); + int handle_event(); + + CreateBD_GUI *gui; +}; + #endif diff --git a/cinelerra-5.1/cinelerra/bdcreate.inc b/cinelerra-5.1/cinelerra/bdcreate.inc index 77bb2546..765c2478 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.inc +++ b/cinelerra-5.1/cinelerra/bdcreate.inc @@ -24,6 +24,22 @@ class CreateBD_MenuItem; class CreateBD_Thread; +class CreateBD_OK; +class CreateBD_Cancel; +class CreateBD_DiskSpace; +class CreateBD_TmpPath; +class CreateBD_AssetTitle; +class CreateBD_Deinterlace; +class CreateBD_InverseTelecine; +class CreateBD_Scale; +class CreateBD_ResizeTracks; +class CreateBD_Histogram; +class CreateBD_LabelChapters; +class CreateBD_WideAudio; +class CreateBD_WideAspect; class CreateBD_GUI; +class CreateBD_FormatItem; +class CreateBD_Format; +class CreateBD_MediaSize; #endif diff --git a/cinelerra-5.1/cinelerra/defaultformats.h b/cinelerra-5.1/cinelerra/defaultformats.h index 787197d6..a68a7b32 100644 --- a/cinelerra-5.1/cinelerra/defaultformats.h +++ b/cinelerra-5.1/cinelerra/defaultformats.h @@ -39,31 +39,31 @@ struct formatpresets }; static struct formatpresets format_presets[] = { - { "1080P/60", 2, 2, 48000, 1, 1, 60000.0 / 1001, + { N_("1080P/60"), 2, 2, 48000, 1, 1, 60000.0 / 1001, 1920,1080, 16,9, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "1080P/24", 6, 6, 48000, 1, 1, 24, + { N_("1080P/24"), 6, 6, 48000, 1, 1, 24, 1920,1080, 16,9, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "1080I", 2, 2, 48000, 1, 1, 30000.0 / 1001, + { N_("1080I"), 2, 2, 48000, 1, 1, 30000.0 / 1001, 1920,1080, 16,9, BC_ILACE_MODE_BOTTOM_FIRST, BC_YUVA8888 }, - { "720P/60", 2, 2, 48000, 1, 1, 60000.0 / 1001, + { N_("720P/60"), 2, 2, 48000, 1, 1, 60000.0 / 1001, 1280,720, 16,9, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "PAL 576I - DV(D)", 2, 2, 48000, 1, 1, 25, + { N_("PAL 576I - DV(D)"), 2, 2, 48000, 1, 1, 25, 720,576, 4,3, BC_ILACE_MODE_BOTTOM_FIRST, BC_YUVA8888 }, - { "NTSC 480P - DV(D)", 2, 2, 48000, 1, 1, 60000.0 / 1001, + { N_("NTSC 480P - DV(D)"), 2, 2, 48000, 1, 1, 60000.0 / 1001, 720,480, 4,3, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "NTSC 480I - DV(D)", 2, 2, 48000, 1, 1, 30000.0 / 1001, + { N_("NTSC 480I - DV(D)"), 2, 2, 48000, 1, 1, 30000.0 / 1001, 720,480, 4,3, BC_ILACE_MODE_BOTTOM_FIRST, BC_YUVA8888 }, - { "YouTube", 1, 1, 48000, 1, 1, 30000.0 / 1001, + { N_("YouTube"), 1, 1, 48000, 1, 1, 30000.0 / 1001, 424,318, 4,3, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "Half D-1 PAL", 2, 2, 48000, 1, 1, 25, + { N_("Half D-1 PAL"), 2, 2, 48000, 1, 1, 25, 360,288, 4,3, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "NTSC Half D-1", 2, 2, 48000, 1, 1, 30000.0 / 1001, + { N_("NTSC Half D-1"), 2, 2, 48000, 1, 1, 30000.0 / 1001, 360,240, 4,3, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "Internet", 1, 1, 22050, 1, 1, 15, + { N_("Internet"), 1, 1, 22050, 1, 1, 15, 320,240, 4,3, BC_ILACE_MODE_NOTINTERLACED, BC_YUVA8888 }, - { "CD Audio", 2, 2, 44100, 1, 0, 30000.0 / 1001, + { N_("CD Audio"), 2, 2, 44100, 1, 0, 30000.0 / 1001, 720,480, 4,3, BC_ILACE_MODE_NOTINTERLACED, BC_RGBA8888 }, - { "DAT Audio", 2, 2, 48000, 1, 0, 30000.0 / 1001, + { N_("DAT Audio"), 2, 2, 48000, 1, 0, 30000.0 / 1001, 720,480, 4,3, BC_ILACE_MODE_NOTINTERLACED, BC_RGBA8888 }, { 0 } }; diff --git a/cinelerra-5.1/cinelerra/dvdcreate.C b/cinelerra-5.1/cinelerra/dvdcreate.C index 05dde68b..89f6d0ab 100644 --- a/cinelerra-5.1/cinelerra/dvdcreate.C +++ b/cinelerra-5.1/cinelerra/dvdcreate.C @@ -1,4 +1,5 @@ #include "asset.h" +#include "clip.h" #include "dvdcreate.h" #include "edl.h" #include "edit.h" @@ -24,6 +25,29 @@ // DVD Creation +#define HD_1920x1080_2997 0 +#define HD_1920x1080_2500 1 +#define HD_1280x720_5994p 2 +#define HD_1280x720_5000p 3 +#define HD_720x576_5000p 4 +#define HD_720x576_2500 5 +#define HD_720x480_5994p 6 +#define HD_720x480_2997 7 + +static struct hd_format { + const char *name; + int w, h; + double framerate; +} hd_formats[] = { + { "1920x1080 29.97", 1920,1080, 29.97 }, + { "1920x1080 25", 1920,1080, 25 }, + { "1280x720 59.94p", 1280,720, 59.94 }, + { "1280x720 50p", 1280,720, 50 }, + { "720x576 50p(PAL)", 720,576, 50 }, + { "720x576 25 (PAL)", 720,576, 25 }, + { "720x480 59.94p(NTSC)", 720,480, 59.94 }, + { "720x480 29.97 (NTSC)", 720,480, 29.97 }, +}; const int64_t CreateDVD_Thread::DVD_SIZE = 4700000000; const int CreateDVD_Thread::DVD_STREAMS = 1; @@ -61,14 +85,14 @@ CreateDVD_Thread::CreateDVD_Thread(MWindow *mwindow) this->mwindow = mwindow; this->gui = 0; this->use_deinterlace = 0; - this->use_inverse_telecine = 0; this->use_scale = 0; - this->use_resize_tracks = 0; this->use_histogram = 0; + this->use_inverse_telecine = 0; this->use_wide_audio = 0; this->use_wide_aspect = 0; - this->use_label_chapters = 0; this->use_ffmpeg = 0; + this->use_resize_tracks = 0; + this->use_label_chapters = 0; } CreateDVD_Thread::~CreateDVD_Thread() @@ -112,12 +136,12 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, session->video_channels = DVD_STREAMS; session->video_tracks = DVD_STREAMS; - session->frame_rate = DVD_FRAMERATE; - session->output_w = DVD_WIDTH; - session->output_h = DVD_HEIGHT; - session->aspect_w = use_wide_aspect ? DVD_WIDE_ASPECT_WIDTH : DVD_ASPECT_WIDTH; - session->aspect_h = use_wide_aspect ? DVD_WIDE_ASPECT_HEIGHT : DVD_ASPECT_HEIGHT; - session->sample_rate = DVD_SAMPLERATE; + session->frame_rate = dvd_framerate; + session->output_w = dvd_width; + session->output_h = dvd_height; + session->aspect_w = dvd_aspect_width; + session->aspect_h = dvd_aspect_height; + session->sample_rate = dvd_samplerate; session->audio_channels = session->audio_tracks = use_wide_audio ? DVD_WIDE_CHANNELS : DVD_CHANNELS; @@ -213,11 +237,12 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO); edl->resample(old_framerate, new_framerate, TRACK_VIDEO); - int64_t aud_size = ((DVD_KAUDIO_RATE * total_length)/8 + 1000-1) * 1000; - int64_t vid_size = DVD_SIZE*0.96 - aud_size; + int64_t aud_size = ((dvd_kaudio_rate * total_length)/8 + 1000-1) * 1000; + int64_t vid_size = dvd_size*0.96 - aud_size; int64_t vid_bitrate = (vid_size * 8) / total_length; vid_bitrate /= 1000; vid_bitrate *= 1000; - if( vid_bitrate > DVD_MAX_BITRATE ) vid_bitrate = DVD_MAX_BITRATE; + if( vid_bitrate > dvd_max_bitrate ) + vid_bitrate = dvd_max_bitrate; char xml_filename[BCTEXTLEN]; sprintf(xml_filename, "%s/dvd.xml", asset_dir); @@ -253,7 +278,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec); FFMPEG::load_options(option_path, asset->ff_audio_options, sizeof(asset->ff_audio_options)); - asset->ff_audio_bitrate = DVD_KAUDIO_RATE * 1000; + asset->ff_audio_bitrate = dvd_kaudio_rate * 1000; asset->video_data = 1; strcpy(asset->vcodec, "dvd.dvd"); @@ -294,7 +319,7 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList *jobs, asset->signed_ = 1; asset->header = 0; asset->dither = 0; - asset->ac3_bitrate = DVD_KAUDIO_RATE; + asset->ac3_bitrate = dvd_kaudio_rate; } job = new BatchRenderJob(mwindow->preferences); @@ -325,7 +350,7 @@ void CreateDVD_Thread::handle_close_event(int result) } if( use_scale ) { sprintf(data,"", DVD_WIDTH, DVD_HEIGHT); + "WIDTH=%d HEIGHT=%d CONSTRAIN=0>", dvd_width, dvd_height); keyframe.set_data(data); insert_video_plugin("Scale", &keyframe); } @@ -373,19 +398,49 @@ BC_Window* CreateDVD_Thread::new_gui() dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, dtm.tm_hour, dtm.tm_min, dtm.tm_sec); use_deinterlace = 0; - use_inverse_telecine = 0; use_scale = 0; - use_resize_tracks = 0; use_histogram = 0; + use_inverse_telecine = 0; use_wide_audio = 0; use_wide_aspect = 0; - use_label_chapters = 0; use_ffmpeg = 0; + use_resize_tracks = 0; + use_label_chapters = 0; + use_standard = HD_720x480_2997; + + dvd_size = DVD_SIZE; + dvd_width = DVD_WIDTH; + dvd_height = DVD_HEIGHT; + dvd_aspect_width = DVD_ASPECT_WIDTH; + dvd_aspect_height = DVD_ASPECT_HEIGHT; + dvd_framerate = DVD_FRAMERATE; + dvd_samplerate = DVD_SAMPLERATE; + dvd_max_bitrate = DVD_MAX_BITRATE; + dvd_kaudio_rate = DVD_KAUDIO_RATE; + + int has_standard = -1; + if( mwindow->edl ) { + EDLSession *session = mwindow->edl->session; +// match the session to any known standard + for( int i=0; i<(int)(sizeof(hd_formats)/sizeof(hd_formats[0])); ++i ) { + if( !EQUIV(session->frame_rate, hd_formats[i].framerate) ) continue; + if( session->output_w != hd_formats[i].w ) continue; + if( session->output_h != hd_formats[i].h ) continue; + has_standard = i; break; + } + if( has_standard < 0 ) { +// or use the default standard + if( !strcmp(mwindow->default_standard, "NTSC") ) has_standard = HD_720x480_2997; + else if( !strcmp(mwindow->default_standard, "PAL") ) has_standard = HD_720x576_2500; + } + } + use_standard = has_standard >= 0 ? has_standard : HD_720x480_2997; + option_presets(); int scr_x = mwindow->gui->get_screen_x(0, -1); int scr_w = mwindow->gui->get_screen_w(0, -1); int scr_h = mwindow->gui->get_screen_h(0, -1); - int w = 500, h = 250; + int w = 500, h = 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); @@ -461,10 +516,18 @@ int64_t CreateDVD_DiskSpace::tmp_path_space() void CreateDVD_DiskSpace::update() { -// gui->disk_space->set_color(get_bg_color()); - int64_t disk_space = tmp_path_space(); - int color = disk_spaceneeded_disk_space ? RED : GREEN; static const char *suffix[] = { "", "KB", "MB", "GB", "TB", "PB" }; + int64_t disk_space = tmp_path_space(); + double media_size = 15e9, msz = 0, m = 1; + char sfx[BCSTRLEN]; + if( sscanf(gui->media_size->get_text(), "%lf%s", &msz, sfx) == 2 ) { + int i = sizeof(suffix)/sizeof(suffix[0]); + while( --i >= 0 && strcmp(sfx, suffix[i]) ); + while( --i >= 0 ) m *= 1000; + media_size = msz * m; + } + m = gui->thread->use_ffmpeg ? 2 : 3; + int color = disk_space < media_size*m ? RED : GREEN; int i = 0; for( int64_t space=disk_space; i<5 && (space/=1000)>0; disk_space=space, ++i ); char text[BCTEXTLEN]; @@ -627,7 +690,6 @@ CreateDVD_GUI::CreateDVD_GUI(CreateDVD_Thread *thread, int x, int y, int w, int asset_title = 0; tmp_path = 0; disk_space = 0; - needed_disk_space = 15e9; need_deinterlace = 0; need_inverse_telecine = 0; need_scale = 0; @@ -664,8 +726,26 @@ 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; + title = new BC_Title(x0, y, _("Media:"), MEDIUMFONT, YELLOW); + add_subwindow(title); + x0 += title->get_w() + padx; + media_size = new CreateDVD_MediaSize(this, x0, y); + media_size->create_objects(); + media_sizes.append(new BC_ListBoxItem("4.7GB")); + media_sizes.append(new BC_ListBoxItem("8.3GB")); + media_size->update_list(&media_sizes); + media_size->update(media_sizes[0]->get_text()); disk_space->update(); + x0 = x; y += disk_space->get_h() + pady/2; + title = new BC_Title(x0, y, _("Format:"), MEDIUMFONT, YELLOW); + add_subwindow(title); + x0 += title->get_w() + padx; + standard = new CreateDVD_Format(this, x0, y); + add_subwindow(standard); + standard->create_objects(); + y += standard->get_h() + pady/2; need_deinterlace = new CreateDVD_Deinterlace(this, x, y); add_subwindow(need_deinterlace); int x1 = x + 150, x2 = x1 + 150; @@ -726,6 +806,19 @@ int CreateDVD_GUI::close_event() return 1; } +void CreateDVD_GUI::update() +{ + need_deinterlace->set_value(thread->use_deinterlace); + need_inverse_telecine->set_value(thread->use_inverse_telecine); + need_scale->set_value(thread->use_scale); + need_use_ffmpeg->set_value(thread->use_ffmpeg); + 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_wide_aspect->set_value(thread->use_wide_aspect); + need_label_chapters->set_value(thread->use_label_chapters); +} + int CreateDVD_Thread:: insert_video_plugin(const char *title, KeyFrame *default_keyframe) { @@ -777,7 +870,20 @@ resize_tracks() int CreateDVD_Thread:: option_presets() { +// reset only probed options + use_deinterlace = 0; + use_scale = 0; + use_resize_tracks = 0; + use_wide_audio = 0; + use_wide_aspect = 0; + use_label_chapters = 0; + if( !mwindow->edl ) return 1; + + dvd_width = hd_formats[use_standard].w; + dvd_height = hd_formats[use_standard].h; + dvd_framerate = hd_formats[use_standard].framerate; + Tracks *tracks = mwindow->edl->tracks; int max_w = 0, max_h = 0; int has_deinterlace = 0, has_scale = 0; @@ -791,10 +897,10 @@ option_presets() Indexable *indexable = edit->get_source(); int w = indexable->get_w(); if( w > max_w ) max_w = w; - if( w != DVD_WIDTH ) use_scale = 1; + if( w != dvd_width ) use_scale = 1; int h = indexable->get_h(); if( h > max_h ) max_h = h; - if( h != DVD_HEIGHT ) use_scale = 1; + if( h != dvd_height ) use_scale = 1; } for( int i=0; iplugin_set.size(); ++i ) { for(Plugin *plugin = (Plugin*)trk->plugin_set[i]->first; @@ -813,8 +919,8 @@ option_presets() if( has_scale ) use_scale = 0; if( use_scale ) { - if( max_w != DVD_WIDTH ) use_resize_tracks = 1; - if( max_h != DVD_HEIGHT ) use_resize_tracks = 1; + if( max_w != dvd_width ) use_resize_tracks = 1; + 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; @@ -825,15 +931,82 @@ option_presets() break; } } - if( !has_deinterlace && max_h > 2*DVD_HEIGHT ) use_deinterlace = 1; + if( !has_deinterlace && max_h > 2*dvd_height ) use_deinterlace = 1; Labels *labels = mwindow->edl->labels; use_label_chapters = labels && labels->first ? 1 : 0; - float w, h; - MWindow::create_aspect_ratio(w, h, max_w, max_h); - if( w == DVD_WIDE_ASPECT_WIDTH && h == DVD_WIDE_ASPECT_HEIGHT ) + + float aw, ah; + MWindow::create_aspect_ratio(aw, ah, max_w, max_h); + if( aw == DVD_WIDE_ASPECT_WIDTH && ah == DVD_WIDE_ASPECT_HEIGHT ) use_wide_aspect = 1; + dvd_aspect_width = use_wide_aspect ? DVD_WIDE_ASPECT_WIDTH : DVD_ASPECT_WIDTH; + dvd_aspect_height = use_wide_aspect ? DVD_WIDE_ASPECT_HEIGHT : DVD_ASPECT_HEIGHT; + if( tracks->recordable_audio_tracks() == DVD_WIDE_CHANNELS ) use_wide_audio = 1; + return 0; } + + +CreateDVD_FormatItem::CreateDVD_FormatItem(CreateDVD_Format *popup, + int standard, const char *name) + : BC_MenuItem(name) +{ + this->popup = popup; + this->standard = standard; +} + +CreateDVD_FormatItem::~CreateDVD_FormatItem() +{ +} + +int CreateDVD_FormatItem::handle_event() +{ + popup->set_text(get_text()); + popup->gui->thread->use_standard = standard; + return popup->handle_event(); +} + + +CreateDVD_Format::CreateDVD_Format(CreateDVD_GUI *gui, int x, int y) + : BC_PopupMenu(x, y, 180, hd_formats[gui->thread->use_standard].name, 1) +{ + this->gui = gui; +} + +CreateDVD_Format::~CreateDVD_Format() +{ +} + +void CreateDVD_Format::create_objects() +{ + for( int i=0; i<(int)(sizeof(hd_formats)/sizeof(hd_formats[0])); ++i ) { + add_item(new CreateDVD_FormatItem(this, i, hd_formats[i].name)); + } +} + +int CreateDVD_Format::handle_event() +{ + gui->thread->option_presets(); + gui->update(); + return 1; +} + +CreateDVD_MediaSize::CreateDVD_MediaSize(CreateDVD_GUI *gui, int x, int y) + : BC_PopupTextBox(gui, 0, 0, x, y, 70,50) +{ + this->gui = gui; +} + +CreateDVD_MediaSize::~CreateDVD_MediaSize() +{ +} + +int CreateDVD_MediaSize::handle_event() +{ + gui->disk_space->update(); + return 1; +} + diff --git a/cinelerra-5.1/cinelerra/dvdcreate.h b/cinelerra-5.1/cinelerra/dvdcreate.h index a0d331f7..aea3efa6 100644 --- a/cinelerra-5.1/cinelerra/dvdcreate.h +++ b/cinelerra-5.1/cinelerra/dvdcreate.h @@ -6,13 +6,13 @@ #include "bcwindowbase.h" #include "bcbutton.h" #include "bcdialog.h" +#include "bclistboxitem.inc" #include "bcmenuitem.h" #include "bctextbox.h" #include "mwindow.h" #include "dvdcreate.inc" - class CreateDVD_MenuItem : public BC_MenuItem { public: @@ -49,7 +49,17 @@ public: int use_scale, use_resize_tracks; int use_wide_audio, use_wide_aspect; int use_histogram, use_label_chapters; - int use_ffmpeg; + int use_ffmpeg, use_standard; + + int64_t dvd_size; + int dvd_width; + int dvd_height; + double dvd_aspect_width; + double dvd_aspect_height; + double dvd_framerate; + int dvd_samplerate; + int dvd_max_bitrate; + double dvd_kaudio_rate; }; class CreateDVD_OK : public BC_OKButton @@ -199,14 +209,17 @@ public: int resize_event(int w, int h); int translation_event(); int close_event(); + void update(); - int64_t needed_disk_space; CreateDVD_Thread *thread; int at_x, at_y; CreateDVD_AssetTitle *asset_title; int tmp_x, tmp_y; CreateDVD_TmpPath *tmp_path; CreateDVD_DiskSpace *disk_space; + CreateDVD_Format *standard; + ArrayList media_sizes; + CreateDVD_MediaSize *media_size; CreateDVD_Deinterlace *need_deinterlace; CreateDVD_InverseTelecine *need_inverse_telecine; CreateDVD_Scale *need_scale; @@ -222,4 +235,36 @@ public: CreateDVD_Cancel *cancel; }; +class CreateDVD_FormatItem : public BC_MenuItem +{ +public: + int handle_event(); + CreateDVD_FormatItem(CreateDVD_Format *popup, int standard, const char *name); + ~CreateDVD_FormatItem(); + + CreateDVD_Format *popup; + int standard; +}; + +class CreateDVD_Format : public BC_PopupMenu +{ +public: + void create_objects(); + int handle_event(); + CreateDVD_Format(CreateDVD_GUI *gui, int x, int y); + ~CreateDVD_Format(); + + CreateDVD_GUI *gui; +}; + +class CreateDVD_MediaSize : public BC_PopupTextBox +{ +public: + CreateDVD_MediaSize(CreateDVD_GUI *gui, int x, int y); + ~CreateDVD_MediaSize(); + int handle_event(); + + CreateDVD_GUI *gui; +}; + #endif diff --git a/cinelerra-5.1/cinelerra/dvdcreate.inc b/cinelerra-5.1/cinelerra/dvdcreate.inc index 041404fc..c8fde195 100644 --- a/cinelerra-5.1/cinelerra/dvdcreate.inc +++ b/cinelerra-5.1/cinelerra/dvdcreate.inc @@ -24,6 +24,23 @@ class CreateDVD_MenuItem; class CreateDVD_Thread; +class CreateDVD_OK; +class CreateDVD_Cancel; +class CreateDVD_DiskSpace; +class CreateDVD_TmpPath; +class CreateDVD_AssetTitle; +class CreateDVD_Deinterlace; +class CreateDVD_InverseTelecine; +class CreateDVD_Scale; +class CreateDVD_ResizeTracks; +class CreateDVD_Histogram; +class CreateDVD_LabelChapters; +class CreateDVD_WideAudio; +class CreateDVD_WideAspect; +class CreateDVD_UseFFMpeg; class CreateDVD_GUI; +class CreateDVD_FormatItem; +class CreateDVD_Format; +class CreateDVD_MediaSize; #endif diff --git a/cinelerra-5.1/cinelerra/interlacemodes.C b/cinelerra-5.1/cinelerra/interlacemodes.C index 5098f776..58dc042a 100644 --- a/cinelerra-5.1/cinelerra/interlacemodes.C +++ b/cinelerra-5.1/cinelerra/interlacemodes.C @@ -23,7 +23,7 @@ #define HAVE_STDINT_H #endif /* HAVE_STDINT_H */ -#include +#include "mjpegtools/yuv4mpeg.h" #include "interlacemodes.h" // AUTO FIX METHOD ==================== diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 890aaac6..ec483617 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -379,43 +379,36 @@ void MWindow::create_defaults_path(char *string, const char *config_file) } const char *MWindow::default_std() { - int fd, i, l = 0; - char buf[BCTEXTLEN]; - char *p; + char buf[BCTEXTLEN], *p = 0; - if((fd = open(TIMEZONE_NAME, O_RDONLY)) >= 0) - { - l = read(fd, buf, BCTEXTLEN); + int fd = open(TIMEZONE_NAME, O_RDONLY); + if( fd >= 0 ) { + int l = read(fd, buf, sizeof(buf)-1); close(fd); - if(l > 0) - { + if( l > 0 ) { + if( buf[l-1] == '\n' ) --l; buf[l] = 0; - if(buf[l - 1] == '\n') - buf[--l] = 0; + p = buf; } - p = buf; } - if(l < 1) - { - if((l = readlink(LOCALTIME_LINK, buf, BCTEXTLEN)) > 0) - { + if( !p ) { + int l = readlink(LOCALTIME_LINK, buf, sizeof(buf)-1); + if( l > 0 ) { buf[l] = 0; - if( (p=strstr(buf, ZONEINFO_STR)) != 0 ) - { - p += strlen(ZONEINFO_STR); - l = strlen(p); - } - else - l = 0; + if( !(p=strstr(buf, ZONEINFO_STR)) != 0 ) return "PAL"; + p += strlen(ZONEINFO_STR); } } - if(l) - { - for(i = 0; ntsc_zones[i]; i++) - if(strcmp(ntsc_zones[i], p) == 0) + + for( int i=0; ntsc_zones[i]; ++i ) { + if( !strcmp(ntsc_zones[i], p) ) return "NTSC"; } - return "PAL"; + +//__timezone: Seconds west of UTC. 240sec/deg + double tz_deg = __timezone / 240.; +// from Honolulu = -10, to New York = -5, 15deg/hr lat -150..-75 + return tz_deg >= -10*15 && tz_deg <= -5*15 ? "NTSC" : "PAL"; } void MWindow::fill_preset_defaults(const char *preset, EDLSession *session) @@ -424,7 +417,7 @@ void MWindow::fill_preset_defaults(const char *preset, EDLSession *session) for(fpr = &format_presets[0]; fpr->name; fpr++) { - if(strcmp(fpr->name, preset) == 0) + if(strcmp(_(fpr->name), preset) == 0) { session->audio_channels = fpr->audio_channels; session->audio_tracks = fpr->audio_tracks; @@ -447,7 +440,7 @@ const char *MWindow::get_preset_name(int index) { if(index < 0 || index >= (int)MAX_NUM_PRESETS) return "Error"; - return format_presets[index].name; + return _(format_presets[index].name); } diff --git a/cinelerra-5.1/cinelerra/mwindow.inc b/cinelerra-5.1/cinelerra/mwindow.inc index 2ad6a095..d3f890b7 100644 --- a/cinelerra-5.1/cinelerra/mwindow.inc +++ b/cinelerra-5.1/cinelerra/mwindow.inc @@ -44,11 +44,6 @@ // Index of vwindow that always exists #define DEFAULT_VWINDOW 0 -// keyframe reticle -#define HAIRLINE_NEVER 0 -#define HAIRLINE_DRAGGING 1 -#define HAIRLINE_ALWAYS 2 - class MWindow; #if 0 diff --git a/cinelerra-5.1/cinelerra/mwindowgui.inc b/cinelerra-5.1/cinelerra/mwindowgui.inc index e31de9b5..c22319ce 100644 --- a/cinelerra-5.1/cinelerra/mwindowgui.inc +++ b/cinelerra-5.1/cinelerra/mwindowgui.inc @@ -32,6 +32,11 @@ #define BOTTOM_LEFT_PANE 2 #define BOTTOM_RIGHT_PANE 3 +// keyframe reticle +#define HAIRLINE_NEVER 0 +#define HAIRLINE_DRAGGING 1 +#define HAIRLINE_ALWAYS 2 + class MWindowGUI; #endif diff --git a/cinelerra-5.1/guicast/bootstrap.c b/cinelerra-5.1/guicast/bootstrap.c index c70dd0b6..3757d9e8 100644 --- a/cinelerra-5.1/guicast/bootstrap.c +++ b/cinelerra-5.1/guicast/bootstrap.c @@ -196,6 +196,7 @@ int main(int argc, char *argv[]) // Run system command on it sprintf(system_command, "%s %s %s", BOOTSTRAP, temp_path, out_path); int temp = system(system_command); + return 0; } -- 2.26.2