From 9f917bc27389ebc36568a1f465b42208f7e8e46a Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 27 Jul 2016 16:39:15 -0600 Subject: [PATCH] add dvd chroma 420pi colormodel, misc fixes --- cinelerra-5.1/cinelerra/assetedit.C | 34 ++++++----- cinelerra-5.1/cinelerra/filedv.C | 30 +++++----- cinelerra-5.1/cinelerra/fileexr.C | 1 + cinelerra-5.1/cinelerra/filempeg.C | 62 +++++++------------- cinelerra-5.1/cinelerra/filepng.C | 1 + cinelerra-5.1/cinelerra/indexable.C | 1 + cinelerra-5.1/cinelerra/performanceprefs.C | 31 +++++++--- cinelerra-5.1/cinelerra/performanceprefs.h | 22 +++++-- cinelerra-5.1/cinelerra/performanceprefs.inc | 1 + cinelerra-5.1/cinelerra/preferences.C | 4 ++ cinelerra-5.1/cinelerra/preferences.h | 2 + cinelerra-5.1/cinelerra/tracks.C | 3 +- cinelerra-5.1/guicast/bccmdl.py | 15 ++++- cinelerra-5.1/guicast/bccmodels.C | 4 ++ cinelerra-5.1/guicast/bccmodels.h | 1 + cinelerra-5.1/guicast/test4.C | 4 +- cinelerra-5.1/guicast/vframe.C | 4 ++ cinelerra-5.1/guicast/xfer.C | 6 +- cinelerra-5.1/guicast/xfer.h | 30 +++++++++- cinelerra-5.1/plugins/titler/title.C | 4 +- 20 files changed, 165 insertions(+), 95 deletions(-) diff --git a/cinelerra-5.1/cinelerra/assetedit.C b/cinelerra-5.1/cinelerra/assetedit.C index 9d878072..c2102d2b 100644 --- a/cinelerra-5.1/cinelerra/assetedit.C +++ b/cinelerra-5.1/cinelerra/assetedit.C @@ -95,14 +95,14 @@ void AssetEdit::edit_asset(Indexable *indexable) { EDL *nested_edl = (EDL*)indexable; - strcpy(changed_params->path, nested_edl->path); + strcpy(changed_params->path, nested_edl->path); changed_params->sample_rate = nested_edl->session->sample_rate; - changed_params->channels = nested_edl->session->audio_channels; + changed_params->channels = nested_edl->session->audio_channels; //printf("AssetEdit::edit_asset %d %f\n", __LINE__, nested_edl->session->frame_rate); changed_params->frame_rate = nested_edl->session->frame_rate; - changed_params->width = nested_edl->session->output_w; - changed_params->height = nested_edl->session->output_h; + changed_params->width = nested_edl->session->output_w; + changed_params->height = nested_edl->session->output_h; } BC_DialogThread::start(); @@ -581,7 +581,7 @@ void AssetEditWindow::create_objects() ilacefixoption_chkboxw->ilacemode_textbox = textboxw; add_subwindow(listboxw = new AssetEditInterlacemodePulldown(mwindow, textboxw, - &asset->interlace_mode, + &asset_edit->changed_params->interlace_mode, (ArrayList*)&mwindow->interlace_asset_modes, ilacefixoption_chkboxw, x2 + textboxw->get_w(), @@ -595,7 +595,7 @@ void AssetEditWindow::create_objects() ilacefixoption_chkboxw->ilacefixmethod_textbox = textboxw; add_subwindow(listboxw = new InterlacefixmethodPulldown(mwindow, textboxw, - &asset->interlace_fixmethod, + &asset_edit->changed_params->interlace_fixmethod, (ArrayList*)&mwindow->interlace_asset_fixmethods, x2 + textboxw->get_w(), y)); @@ -621,8 +621,11 @@ void AssetEditWindow::create_objects() // Calculate values to enter into textboxes char text[32], *tc = text; - Units::totext(tc, asset->tcstart / asset->frame_rate, - TIME_HMSF, asset->sample_rate, asset->frame_rate); + if( asset ) + Units::totext(tc, asset->tcstart / asset->frame_rate, + TIME_HMSF, asset->sample_rate, asset->frame_rate); + else + strcpy(tc, "0:00:00:00"); const char *tc_hours = tc, *tc_minutes, *tc_seconds, *tc_rest; tc = strchr(tc, ':'); *tc++ = 0; tc_minutes = tc; @@ -704,7 +707,7 @@ int AssetEditFRate::handle_event() Interlaceautofix::Interlaceautofix(MWindow *mwindow,AssetEditWindow *fwindow, int x, int y) : BC_CheckBox(x, y, - ((Asset *)fwindow->asset_edit->indexable)->interlace_autofixoption, + fwindow->asset_edit->changed_params->interlace_autofixoption, _("Automatically Fix Interlacing")) { this->fwindow = fwindow; @@ -717,7 +720,7 @@ Interlaceautofix::~Interlaceautofix() int Interlaceautofix::handle_event() { - Asset *asset = (Asset *)fwindow->asset_edit->indexable; + Asset *asset = fwindow->asset_edit->changed_params; asset->interlace_autofixoption = get_value(); showhideotherwidgets(); return 1; @@ -727,7 +730,7 @@ void Interlaceautofix::showhideotherwidgets() { int thevalue = get_value(); - Asset *asset = (Asset *)fwindow->asset_edit->indexable; + Asset *asset = fwindow->asset_edit->changed_params; if (thevalue == BC_ILACE_AUTOFIXOPTION_AUTO) { this->ilacemode_textbox->enable(); @@ -788,7 +791,7 @@ AssetEditILaceautofixoption::AssetEditILaceautofixoption(AssetEditWindow *fwindo int AssetEditILaceautofixoption::handle_event() { - Asset *asset = (Asset *)fwindow->asset_edit->indexable; + Asset *asset = fwindow->asset_edit->changed_params; asset->interlace_autofixoption = ilaceautofixoption_from_text(get_text(), this->thedefault); return 1; } @@ -803,7 +806,7 @@ AssetEditILacemode::AssetEditILacemode(AssetEditWindow *fwindow, const char *tex int AssetEditILacemode::handle_event() { - Asset *asset = (Asset *)fwindow->asset_edit->indexable; + Asset *asset = fwindow->asset_edit->changed_params; asset->interlace_mode = ilacemode_from_text(get_text(),this->thedefault); return 1; } @@ -1086,8 +1089,7 @@ void DetailAssetThread::run() AssetEditReelName::AssetEditReelName(AssetEditWindow *fwindow, int x, int y) - : BC_TextBox(x, y, 220, 1, - ((Asset *)fwindow->asset_edit->indexable)->reel_name, + : BC_TextBox(x, y, 220, 1, fwindow->asset_edit->changed_params->reel_name, 1, MEDIUMFONT, 1) { this->fwindow = fwindow; @@ -1107,7 +1109,7 @@ int AssetEditReelName::handle_event() AssetEditReelNumber::AssetEditReelNumber(AssetEditWindow *fwindow, int x, int y) - : BC_TextBox(x, y, 200, 1, ((Asset *)fwindow->asset_edit->indexable)->reel_number) + : BC_TextBox(x, y, 200, 1, fwindow->asset_edit->changed_params->reel_number) { this->fwindow = fwindow; } diff --git a/cinelerra-5.1/cinelerra/filedv.C b/cinelerra-5.1/cinelerra/filedv.C index d731582b..2ec80d8d 100644 --- a/cinelerra-5.1/cinelerra/filedv.C +++ b/cinelerra-5.1/cinelerra/filedv.C @@ -29,6 +29,7 @@ #include "file.h" #include "filedv.h" #include "guicast.h" +#include "interlacemodes.h" #include "language.h" #include "mutex.h" #include "mwindow.inc" @@ -288,6 +289,12 @@ TRACE("FileDV::open_file 60") asset->width = decoder->width; asset->height = decoder->height; + + if(dv_is_progressive(decoder) > 0) + asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED; + else + asset->interlace_mode = BC_ILACE_MODE_BOTTOM_FIRST; + isPAL = dv_is_PAL(decoder); output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE); @@ -489,12 +496,6 @@ TRACE("FileDV::write_samples 200") video_position_lock->unlock(); -TRACE("FileDV::write_samples 210") - - int16_t **tmp_buf = new int16_t*[asset->channels]; - for(int a = 0; a < asset->channels; a++) - tmp_buf[a] = new int16_t[asset->sample_rate]; - TRACE("FileDV::write_samples 220") for(int i = 0; i < nFrames; i++) @@ -526,6 +527,11 @@ TRACE("FileDV::write_samples 230") if(samples > audio_sample_buffer_maxsize - 1 - audio_sample_buffer_start) { +TRACE("FileDV::write_samples 210") + int16_t *tmp_buf[asset->channels]; + for(int a = 0; a < asset->channels; a++) + tmp_buf[a] = new int16_t[asset->sample_rate]; + TRACE("FileDV::write_samples 240") int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_start - 1; @@ -543,6 +549,10 @@ TRACE("FileDV::write_samples 250") { eprintf(_("ERROR: unable to encode audio frame %d\n"), audio_frames_written); } +TRACE("FileDV::write_samples 280") + + for(int a = 0; a < asset->channels; a++) + delete[] tmp_buf[a]; } else { @@ -584,16 +594,8 @@ TRACE("FileDV::write_samples 270") if(audio_sample_buffer_start >= audio_sample_buffer_maxsize) audio_sample_buffer_start -= audio_sample_buffer_maxsize; } - -TRACE("FileDV::write_samples 280") - - for(int a = 0; a < asset->channels; a++) - delete[] tmp_buf[a]; - delete[] tmp_buf; - TRACE("FileDV::write_samples 290") - UNTRACE return 0; diff --git a/cinelerra-5.1/cinelerra/fileexr.C b/cinelerra-5.1/cinelerra/fileexr.C index 1beb3a7c..2589a006 100644 --- a/cinelerra-5.1/cinelerra/fileexr.C +++ b/cinelerra-5.1/cinelerra/fileexr.C @@ -313,6 +313,7 @@ int FileEXR::read_frame_header(char *path) native_cmodel = BC_RGBA_FLOAT; else native_cmodel = BC_RGB_FLOAT; + asset->exr_use_alpha = BC_CModels::has_alpha(native_cmodel) ? 1 : 0; if(channels.findChannel("Y")) is_yuv = 1; diff --git a/cinelerra-5.1/cinelerra/filempeg.C b/cinelerra-5.1/cinelerra/filempeg.C index fc188a14..54b006fc 100644 --- a/cinelerra-5.1/cinelerra/filempeg.C +++ b/cinelerra-5.1/cinelerra/filempeg.C @@ -451,7 +451,11 @@ int FileMPEG::open_file(int rd, int wr) asset->video_data = mpeg3_has_video(fd); if( !result && asset->video_data ) { - asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; +//TODO: this is not as easy as just looking at headers. +//most interlaced media is rendered as FRM, not TOP/BOT in coding ext hdrs. +//currently, just using the assetedit menu to set the required result as needed. +// if( asset->interlace_mode == BC_ILACE_MODE_UNDETECTED ) +// asset->interlace_mode = mpeg3_detect_interlace(fd, 0); if( !asset->layers ) { asset->layers = mpeg3_total_vstreams(fd); } @@ -551,9 +555,6 @@ int FileMPEG::open_file(int rd, int wr) case 2: asset->vmpeg_progressive = 1; break; } -// Be quiet - strcat(mjpeg_command, " -v0"); - char string[BCTEXTLEN]; // The current usage of mpeg2enc requires bitrate of 0 when quantization is fixed and // quantization of 1 when bitrate is fixed. Perfectly intuitive. @@ -1271,6 +1272,10 @@ int FileMPEG::write_frames(VFrame ***frames, int len) // verify colormodel supported in MPEG output switch( output_cmodel ) { case BC_YUV420P: + if( file->preferences->dvd_yuv420p_interlace && + ( asset->interlace_mode == BC_ILACE_MODE_TOP_FIRST || + asset->interlace_mode == BC_ILACE_MODE_BOTTOM_FIRST ) ) + output_cmodel = BC_YUV420PI; case BC_YUV422P: break; default: @@ -1388,27 +1393,7 @@ int FileMPEG::write_frames(VFrame ***frames, int len) // frame->get_h(), // temp_frame->get_color_model(), // frame->get_color_model()); sleep(1); - BC_CModels::transfer(temp_frame->get_rows(), - frame->get_rows(), - temp_frame->get_y(), - temp_frame->get_u(), - temp_frame->get_v(), - frame->get_y(), - frame->get_u(), - frame->get_v(), - 0, - 0, - frame->get_w(), - frame->get_h(), - 0, - 0, - temp_frame->get_w(), - temp_frame->get_h(), - frame->get_color_model(), - temp_frame->get_color_model(), - 0, - frame->get_w(), - temp_frame->get_w()); + temp_frame->transfer_from(frame); //printf("FileMPEG::write_frames %d\n", __LINE__);sleep(1); mjpeg_y = temp_frame->get_y(); @@ -1515,12 +1500,13 @@ int FileMPEG::read_frame(VFrame *frame) int stream_cmdl = mpeg3_colormodel(fd,file->current_layer); int stream_color_model = bc_colormodel(stream_cmdl); int frame_color_model = frame->get_color_model(); - int frame_cmdl = zmpeg3_cmdl(frame_color_model); + int frame_cmdl = asset->interlace_mode == BC_ILACE_MODE_NOTINTERLACED ? + zmpeg3_cmdl(frame_color_model) : -1; mpeg3_show_subtitle(fd, file->current_layer, file->playback_subtitle); - switch( frame_color_model ) { // check for direct copy case BC_YUV420P: + if( frame_cmdl < 0 ) break; case BC_YUV422P: if( stream_color_model == frame_color_model && width == frame->get_w() && height == frame->get_h() ) { @@ -1574,20 +1560,16 @@ int FileMPEG::read_frame(VFrame *frame) char *y, *u, *v; mpeg3_read_yuvframe_ptr(fd, &y, &u, &v, file->current_layer); if( y && u && v ) { + if( stream_color_model == BC_YUV420P && + file->preferences->dvd_yuv420p_interlace && ( + asset->interlace_mode == BC_ILACE_MODE_TOP_FIRST || + asset->interlace_mode == BC_ILACE_MODE_BOTTOM_FIRST ) ) + stream_color_model = BC_YUV420PI; BC_CModels::transfer(frame->get_rows(), 0, - frame->get_y(), - frame->get_u(), - frame->get_v(), - (unsigned char*)y, - (unsigned char*)u, - (unsigned char*)v, - 0, 0, width, height, - 0, 0, frame->get_w(), frame->get_h(), - stream_color_model, - frame_color_model, - 0, - width, - frame->get_w()); + frame->get_y(), frame->get_u(), frame->get_v(), + (unsigned char*)y, (unsigned char*)u, (unsigned char*)v, + 0,0, width,height, 0,0, frame->get_w(),frame->get_h(), + stream_color_model, frame_color_model, 0, width, frame->get_w()); } return result; diff --git a/cinelerra-5.1/cinelerra/filepng.C b/cinelerra-5.1/cinelerra/filepng.C index d84fcda9..6ccbf288 100644 --- a/cinelerra-5.1/cinelerra/filepng.C +++ b/cinelerra-5.1/cinelerra/filepng.C @@ -191,6 +191,7 @@ int FilePNG::read_frame_header(char *path) native_cmodel = BC_RGB888; } + asset->png_use_alpha = BC_CModels::has_alpha(native_cmodel) ? 1 : 0; png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(stream); diff --git a/cinelerra-5.1/cinelerra/indexable.C b/cinelerra-5.1/cinelerra/indexable.C index fa86e313..fad92e7b 100644 --- a/cinelerra-5.1/cinelerra/indexable.C +++ b/cinelerra-5.1/cinelerra/indexable.C @@ -60,6 +60,7 @@ void Indexable::update_path(char *new_path) void Indexable::update_index(Indexable *src) { + if( index_state == src->index_state ) return; index_state->remove_user(); index_state = src->index_state; index_state->add_user(); diff --git a/cinelerra-5.1/cinelerra/performanceprefs.C b/cinelerra-5.1/cinelerra/performanceprefs.C index 1404ea8c..99268702 100644 --- a/cinelerra-5.1/cinelerra/performanceprefs.C +++ b/cinelerra-5.1/cinelerra/performanceprefs.C @@ -104,7 +104,7 @@ void PerformancePrefs::create_objects() PrefsForceUniprocessor *force_1cpu = new PrefsForceUniprocessor(pwindow, x, y); add_subwindow(force_1cpu); - int x1 = force_1cpu->get_x() + force_1cpu->get_w() + 50; + int x1 = force_1cpu->get_x() + force_1cpu->get_w() + 100; PrefsTrapSigSEGV *trap_segv = new PrefsTrapSigSEGV(this, x1, y); add_subwindow(trap_segv); @@ -121,10 +121,10 @@ void PerformancePrefs::create_objects() ffmpeg_early_probe = new PrefsFFMPEGEarlyProbe(this, x, y); add_subwindow(ffmpeg_early_probe); - y += 30; - - + yuv420p_dvdlace = new PrefsYUV420P_DVDlace(pwindow, this, x1, y); + add_subwindow(yuv420p_dvdlace); + y += 30; // Background rendering add_subwindow(new BC_Bar(5, y, get_w() - 10)); @@ -914,10 +914,9 @@ int PrefsRenderFarmMountpoint::handle_event() PrefsRenderFarmVFS::PrefsRenderFarmVFS(PreferencesWindow *pwindow, - PerformancePrefs *subwindow, - int x, - int y) - : BC_CheckBox(x, y, pwindow->thread->preferences->renderfarm_vfs, _("Use virtual filesystem")) + PerformancePrefs *subwindow, int x, int y) + : BC_CheckBox(x, y, pwindow->thread->preferences->renderfarm_vfs, + _("Use virtual filesystem")) { this->pwindow = pwindow; this->subwindow = subwindow; @@ -929,3 +928,19 @@ int PrefsRenderFarmVFS::handle_event() return 1; } + +PrefsYUV420P_DVDlace::PrefsYUV420P_DVDlace(PreferencesWindow *pwindow, + PerformancePrefs *subwindow, int x, int y) + : BC_CheckBox(x, y, pwindow->thread->preferences->dvd_yuv420p_interlace, + _("Use yuv420p dvd interlace format")) +{ + this->pwindow = pwindow; + this->subwindow = subwindow; +} + +int PrefsYUV420P_DVDlace::handle_event() +{ + pwindow->thread->preferences->dvd_yuv420p_interlace = get_value(); + return 1; +} + diff --git a/cinelerra-5.1/cinelerra/performanceprefs.h b/cinelerra-5.1/cinelerra/performanceprefs.h index 29ae9727..dc02a214 100644 --- a/cinelerra-5.1/cinelerra/performanceprefs.h +++ b/cinelerra-5.1/cinelerra/performanceprefs.h @@ -61,6 +61,7 @@ public: FormatTools *brender_tools; BC_Title *master_rate; PrefsFFMPEGEarlyProbe *ffmpeg_early_probe; + PrefsYUV420P_DVDlace *yuv420p_dvdlace; PrefsFFMPEGMarkerIndecies *ffmpeg_marker_indexes; }; @@ -335,8 +336,7 @@ class PrefsRenderFarmReset : public BC_GenericButton public: PrefsRenderFarmReset(PreferencesWindow *pwindow, PerformancePrefs *subwindow, - int x, - int y); + int x, int y); int handle_event(); @@ -345,6 +345,20 @@ public: }; +class PrefsYUV420P_DVDlace : public BC_CheckBox +{ +public: + PrefsYUV420P_DVDlace(PreferencesWindow *pwindow, + PerformancePrefs *subwindow, + int x, int y); + + int handle_event(); + + PerformancePrefs *subwindow; + PreferencesWindow *pwindow; +}; + + class CICacheSize : public BC_TumbleTextBox { @@ -357,8 +371,4 @@ public: PreferencesWindow *pwindow; }; - - - - #endif diff --git a/cinelerra-5.1/cinelerra/performanceprefs.inc b/cinelerra-5.1/cinelerra/performanceprefs.inc index e300a7e0..75131e5c 100644 --- a/cinelerra-5.1/cinelerra/performanceprefs.inc +++ b/cinelerra-5.1/cinelerra/performanceprefs.inc @@ -45,6 +45,7 @@ class PrefsRenderFarmReplaceNode; class PrefsRenderFarmDelNode; class PrefsRenderFarmSortNodes; class PrefsRenderFarmReset; +class PrefsYUV420P_DVDlace; class CICacheSize; #endif diff --git a/cinelerra-5.1/cinelerra/preferences.C b/cinelerra-5.1/cinelerra/preferences.C index cbdf27cd..6c20a53a 100644 --- a/cinelerra-5.1/cinelerra/preferences.C +++ b/cinelerra-5.1/cinelerra/preferences.C @@ -80,6 +80,7 @@ Preferences::Preferences() ffmpeg_early_probe = 0; ffmpeg_marker_indexes = 1; warn_indexes = 1; + dvd_yuv420p_interlace = 0; // Default brender asset brender_asset = new Asset; @@ -184,6 +185,7 @@ void Preferences::copy_from(Preferences *that) ffmpeg_early_probe = that->ffmpeg_early_probe; ffmpeg_marker_indexes = that->ffmpeg_marker_indexes; warn_indexes = that->warn_indexes; + dvd_yuv420p_interlace = that->dvd_yuv420p_interlace; renderfarm_nodes.remove_all_objects(); renderfarm_ports.remove_all(); renderfarm_enabled.remove_all(); @@ -330,6 +332,7 @@ int Preferences::load_defaults(BC_Hash *defaults) ffmpeg_early_probe = defaults->get("FFMPEG_EARLY_PROBE", ffmpeg_early_probe); ffmpeg_marker_indexes = defaults->get("FFMPEG_MARKER_INDEXES", ffmpeg_marker_indexes); warn_indexes = defaults->get("WARN_INDEXES", warn_indexes); + dvd_yuv420p_interlace = defaults->get("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace); use_brender = defaults->get("USE_BRENDER", use_brender); brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment); cache_size = defaults->get("CACHE_SIZE", cache_size); @@ -430,6 +433,7 @@ int Preferences::save_defaults(BC_Hash *defaults) defaults->update("FFMPEG_EARLY_PROBE", ffmpeg_early_probe); defaults->update("FFMPEG_MARKER_INDEXES", ffmpeg_marker_indexes); defaults->update("WARN_INDEXES", warn_indexes); + defaults->update("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace); brender_asset->save_defaults(defaults, "BRENDER_", 1, diff --git a/cinelerra-5.1/cinelerra/preferences.h b/cinelerra-5.1/cinelerra/preferences.h index 412d5721..889624ab 100644 --- a/cinelerra-5.1/cinelerra/preferences.h +++ b/cinelerra-5.1/cinelerra/preferences.h @@ -104,6 +104,8 @@ public: int ffmpeg_marker_indexes; // warning int warn_indexes; +// use dvd yuv420p interlace format + int dvd_yuv420p_interlace; // Default positions for channels int channel_positions[MAXCHANNELS * MAXCHANNELS]; diff --git a/cinelerra-5.1/cinelerra/tracks.C b/cinelerra-5.1/cinelerra/tracks.C index e2abde91..8db132bc 100644 --- a/cinelerra-5.1/cinelerra/tracks.C +++ b/cinelerra-5.1/cinelerra/tracks.C @@ -406,7 +406,8 @@ int Tracks::total_of(int type) for(Track *current = first; current; current = NEXT) { long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0); - Auto *mute_keyframe = current->automation->autos[AUTOMATION_MUTE]-> + Auto *mute_keyframe = 0; + current->automation->autos[AUTOMATION_MUTE]-> get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe); IntAuto *mute_auto = (IntAuto *)mute_keyframe; diff --git a/cinelerra-5.1/guicast/bccmdl.py b/cinelerra-5.1/guicast/bccmdl.py index 0c730de0..a8d8d0a7 100755 --- a/cinelerra-5.1/guicast/bccmdl.py +++ b/cinelerra-5.1/guicast/bccmdl.py @@ -252,6 +252,16 @@ base = { "w": " yop[j] = y>>8; uop[j/2] = u>>8; vop[j/2] = v>>8;", }, }, + "yuv420pi": { + "i8": { + "r": " int32_t y = *yip*0x010101u, u = *uip, v = *vip;", + "w": " yop[j] = y; uop[j/2] = u; vop[j/2] = v;", + }, + "i16": { + "r": " int32_t y = *yip*0x010101u, u = *uip<<8, v = *vip<<8;", + "w": " yop[j] = y>>8; uop[j/2] = u>>8; vop[j/2] = v>>8;", + }, + }, "yuv422p": { "i8": { @@ -448,6 +458,7 @@ add_cmodel(17, "bc_yuv411p", "i8", "yuv411p") add_cmodel(28, "bc_yuv410p", "i8", "yuv410p") add_cmodel(32, "bc_rgb_floatp", "fp", "rgbfltp") add_cmodel(33, "bc_rgba_floatp", "fp", "rgbfltp", "afpp") +add_cmodel(34, "bc_yuv420pi", "i8", "yuv420pi") specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency") @@ -487,11 +498,11 @@ def is_rgb(nm): def is_yuv(nm): return nm in [ "bc_yuv888", "bc_yuva8888", "bc_yuv161616", \ "bc_yuva16161616", "bc_yuv422", "bc_uvy422", "bc_yuv101010", \ - "bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv422p", \ + "bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", \ "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", ] def is_planar(nm): - return nm in [ "bc_yuv420p", "bc_yuv422p", "bc_yuv444p", \ + return nm in [ "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", "bc_yuv444p", \ "bc_yuv411p", "bc_yuv410p", "bc_rgb_floatp", "bc_rgba_floatp", ] def is_float(nm): diff --git a/cinelerra-5.1/guicast/bccmodels.C b/cinelerra-5.1/guicast/bccmodels.C index 88ed1acd..48315260 100644 --- a/cinelerra-5.1/guicast/bccmodels.C +++ b/cinelerra-5.1/guicast/bccmodels.C @@ -26,6 +26,7 @@ int BC_CModels::is_planar(int colormodel) { switch(colormodel) { case BC_YUV420P: + case BC_YUV420PI: case BC_YUV422P: case BC_YUV444P: case BC_YUV411P: @@ -90,6 +91,7 @@ int BC_CModels::calculate_pixelsize(int colormodel) case BC_RGBA_FLOAT: return 16; // Planar case BC_YUV420P: return 1; + case BC_YUV420PI: return 1; case BC_YUV422P: return 1; case BC_YUV444P: return 1; case BC_YUV422: return 2; @@ -130,6 +132,7 @@ int BC_CModels::calculate_datasize(int w, int h, int bytes_per_line, int color_m switch(color_model) { case BC_YUV410P: return w * h + w * h / 8 + 4; case BC_YUV420P: + case BC_YUV420PI: case BC_YUV411P: return w * h + w * h / 2 + 4; case BC_YUV422P: return w * h * 2 + 4; case BC_YUV444P: return w * h * 3 + 4; @@ -231,6 +234,7 @@ int BC_CModels::is_yuv(int colormodel) case BC_VYU888: case BC_UYVA8888: case BC_YUV420P: + case BC_YUV420PI: case BC_YUV422P: case BC_YUV444P: case BC_YUV411P: diff --git a/cinelerra-5.1/guicast/bccmodels.h b/cinelerra-5.1/guicast/bccmodels.h index 94a9bbcd..13f5868b 100644 --- a/cinelerra-5.1/guicast/bccmodels.h +++ b/cinelerra-5.1/guicast/bccmodels.h @@ -60,6 +60,7 @@ #define BC_YUV410P 28 #define BC_RGB_FLOATP 32 #define BC_RGBA_FLOATP 33 +#define BC_YUV420PI 34 // Colormodels purely used by Quicktime are done in Quicktime. diff --git a/cinelerra-5.1/guicast/test4.C b/cinelerra-5.1/guicast/test4.C index 0c2c2fdd..a878a19d 100644 --- a/cinelerra-5.1/guicast/test4.C +++ b/cinelerra-5.1/guicast/test4.C @@ -81,7 +81,7 @@ const char *cmdl[] = { "yuv422p", "rgb888", "rgba8888", "rgb161616", "rgba16161616", "yuv888", "yuva8888", "yuv161616", "yuva16161616", "yuv411p", "uvy422", "yuv422", "argb8888", "abgr8888", "a8", "a16", "yuv101010", "vyu888", "uyva8888", "yuv444p", "yuv410p", "rgb_float", "rgba_float", "a_float", - "rgb_floatp", "rgba_floatp", + "rgb_floatp", "rgba_floatp", "yuv420pi", }; void write_pgm(uint8_t *tp, int w, int h, const char *fmt, ...) @@ -124,7 +124,7 @@ int main(int ac, char **av) close(fd); int w = ifrm.get_w(), h = ifrm.get_h(); TestWindow test_window(100, 100, w, h); - for( int fr_cmdl=1; fr_cmdl<=32; ++fr_cmdl ) { + for( int fr_cmdl=1; fr_cmdl<=34; ++fr_cmdl ) { if( fr_cmdl == BC_TRANSPARENCY || fr_cmdl == BC_COMPRESSED ) continue; if( fr_cmdl == BC_A8 || fr_cmdl == BC_A16 ) continue; if( fr_cmdl == BC_A_FLOAT || fr_cmdl == 8 ) continue; diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index e8abd025..a0a59744 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -311,6 +311,7 @@ int VFrame::clear_objects(int do_opengl) case BC_YUV410P: case BC_YUV411P: case BC_YUV420P: + case BC_YUV420PI: case BC_YUV422P: case BC_YUV444P: case BC_RGB_FLOATP: @@ -386,6 +387,7 @@ void VFrame::create_row_pointers() break; case BC_YUV420P: + case BC_YUV420PI: case BC_YUV411P: if( this->v_offset ) break; this->y_offset = 0; @@ -851,6 +853,7 @@ int VFrame::clear_frame() case BC_YUV411P: case BC_YUV420P: + case BC_YUV420PI: bzero(get_y(), sz); bzero(get_u(), sz / 4); bzero(get_v(), sz / 4); @@ -1014,6 +1017,7 @@ int VFrame::copy_from(VFrame *frame) break; case BC_YUV420P: + case BC_YUV420PI: case BC_YUV411P: //printf("%d %d %p %p %p %p %p %p\n", w, h, get_y(), get_u(), get_v(), frame->get_y(), frame->get_u(), frame->get_v()); memcpy(get_y(), frame->get_y(), w * h); diff --git a/cinelerra-5.1/guicast/xfer.C b/cinelerra-5.1/guicast/xfer.C index 13f49f82..417a15dc 100644 --- a/cinelerra-5.1/guicast/xfer.C +++ b/cinelerra-5.1/guicast/xfer.C @@ -106,7 +106,8 @@ void BC_Xfer::init( switch( in_colormodel ) { case BC_UVY422: case BC_YUV422: in_w &= ~1; break; // 2x1 - case BC_YUV420P: in_w &= ~1; in_h &= ~1; break; // 2x2 + case BC_YUV420P: + case BC_YUV420PI: in_w &= ~1; in_h &= ~1; break; // 2x2 case BC_YUV422P: in_w &= ~1; break; // 2x1 case BC_YUV410P: in_w &= ~3; in_h &= ~3; break; // 4x4 case BC_YUV411P: in_w &= ~3; break; // 4x1 @@ -114,7 +115,8 @@ void BC_Xfer::init( switch( out_colormodel ) { case BC_UVY422: case BC_YUV422: out_w &= ~1; break; - case BC_YUV420P: out_w &= ~1; out_h &= ~1; break; + case BC_YUV420P: + case BC_YUV420PI: out_w &= ~1; out_h &= ~1; break; case BC_YUV422P: out_w &= ~1; break; case BC_YUV410P: out_w &= ~3; out_h &= ~3; break; case BC_YUV411P: out_w &= ~3; break; diff --git a/cinelerra-5.1/guicast/xfer.h b/cinelerra-5.1/guicast/xfer.h index e6e0aba4..84098b51 100644 --- a/cinelerra-5.1/guicast/xfer.h +++ b/cinelerra-5.1/guicast/xfer.h @@ -103,9 +103,35 @@ ZTYP(float); oty_t *vop = (oty_t *)(out_vp + out_rofs); \ #define xfer_yuv420p_row_in(ity_t) \ - int in_rofs = row_table[i] * total_in_w; \ + int in_r = row_table[i]; \ + int in_rofs = in_r * total_in_w; \ + uint8_t *yip_row = in_yp + in_rofs; \ + in_rofs = in_r / 2 * total_in_w / 2; \ + uint8_t *uip_row = in_up + in_rofs; \ + uint8_t *vip_row = in_vp + in_rofs; \ + for( unsigned j=0; j= 512) config.stroke_width = 0.0; - if(!config.wlen) + if(!config.wlen && !config.timecode) return 0; if(!strlen(config.encoding)) strcpy(config.encoding, DEFAULT_ENCODING); @@ -2190,7 +2190,7 @@ void TitleMain::read_data(KeyFrame *keyframe) config.dropshadow = input.tag.get_property("DROPSHADOW", config.dropshadow); config.outline_size = input.tag.get_property("OUTLINE_SIZE", config.outline_size); config.timecode = input.tag.get_property("TIMECODE", config.timecode); - input.tag.get_property("TIMECODEFORMAT", config.timecode_format); + config.timecode_format = input.tag.get_property("TIMECODEFORMAT", config.timecode_format); config.window_w = input.tag.get_property("WINDOW_W", config.window_w); config.window_h = input.tag.get_property("WINDOW_H", config.window_h); const char *text = input.read_text(); -- 2.26.2