add dvd chroma 420pi colormodel, misc fixes
authorGood Guy <good1.2guy@gmail.com>
Wed, 27 Jul 2016 22:39:15 +0000 (16:39 -0600)
committerGood Guy <good1.2guy@gmail.com>
Wed, 27 Jul 2016 22:39:15 +0000 (16:39 -0600)
20 files changed:
cinelerra-5.1/cinelerra/assetedit.C
cinelerra-5.1/cinelerra/filedv.C
cinelerra-5.1/cinelerra/fileexr.C
cinelerra-5.1/cinelerra/filempeg.C
cinelerra-5.1/cinelerra/filepng.C
cinelerra-5.1/cinelerra/indexable.C
cinelerra-5.1/cinelerra/performanceprefs.C
cinelerra-5.1/cinelerra/performanceprefs.h
cinelerra-5.1/cinelerra/performanceprefs.inc
cinelerra-5.1/cinelerra/preferences.C
cinelerra-5.1/cinelerra/preferences.h
cinelerra-5.1/cinelerra/tracks.C
cinelerra-5.1/guicast/bccmdl.py
cinelerra-5.1/guicast/bccmodels.C
cinelerra-5.1/guicast/bccmodels.h
cinelerra-5.1/guicast/test4.C
cinelerra-5.1/guicast/vframe.C
cinelerra-5.1/guicast/xfer.C
cinelerra-5.1/guicast/xfer.h
cinelerra-5.1/plugins/titler/title.C

index 9d878072aca702bd3621865c1587ed1f48ec4a6b..c2102d2bc10b57da38f8883c7856175da2b3933b 100644 (file)
@@ -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<BC_ListBoxItem*>*)&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<BC_ListBoxItem*>*)&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;
 }
index d731582b1c5148016a4ba2e8a51979b167232ac6..2ec80d8d5e47ece6a6ee0235f45f9ca9bce6898f 100644 (file)
@@ -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;
index 1beb3a7c6b9b7293da1c7ba283a480c533366f1a..2589a0067c34ca42bbef1843564107e938395122 100644 (file)
@@ -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;
index fc188a145d71ffe73433be480bbb5aed5ff8d639..54b006fc46eabda718bb573092bbb12a1030e2c7 100644 (file)
@@ -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;
index d84fcda92d8a6a2d41a66ad106d229feda689dcb..6ccbf28819f51343957018d075574d54f45cbbbb 100644 (file)
@@ -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);
index fa86e313828488d74f5951cf195d4f3cba938dcc..fad92e7b77b9a9932546552e9400320e3f4ad4a6 100644 (file)
@@ -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();
index 1404ea8cb6296fef2bb5535e4b6c4f845ccaf50f..99268702d7d63c42745c1be72776508c3a615dea 100644 (file)
@@ -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;
+}
+
index 29ae972716310b6ee7e37c1338692ae1c8ad0611..dc02a2144e93507a0c11cc7774aa689494f1f6d7 100644 (file)
@@ -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
index e300a7e01ed09ee35e42b17d0187e4462a6c5d92..75131e5c6a33b32dac99f6fe44c53a923374e8e4 100644 (file)
@@ -45,6 +45,7 @@ class PrefsRenderFarmReplaceNode;
 class PrefsRenderFarmDelNode;
 class PrefsRenderFarmSortNodes;
 class PrefsRenderFarmReset;
+class PrefsYUV420P_DVDlace;
 class CICacheSize;
 
 #endif
index cbdf27cd9353a5648987a45cf358cce1d4cc5770..6c20a53a7a071d9135c746e7e70b804019a484c1 100644 (file)
@@ -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,
index 412d57214337fc8c47757ab1e49bd458173fdd94..889624ab8a3f720c2e6b7bb4bb1bda37c40f9682 100644 (file)
@@ -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];
index e2abde91f9cf6b94362bb28ba28c0dd389f73e27..8db132bc1eff7c9c50838b9147d46d9745c57bef 100644 (file)
@@ -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;
 
index 0c730de07c6ff6b61ab3a3bebef5450b52e1d5b3..a8d8d0a7af75068938994dc3d52197b65f1e24df 100755 (executable)
@@ -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):
index 88ed1acdb201402d7bd5477e0f868256aa69e455..4831526066fe22a4589d07710607908b088ccd0d 100644 (file)
@@ -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:
index 94a9bbcd80a136ceb1f56586bdcaafefebe768e3..13f5868b081adf576f2f4e31cba499ea075f2858 100644 (file)
@@ -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.
 
index 0c2c2fdd1e9b3885ae54d8ebf8a2464879459c6d..a878a19d01c82179b02cb4f3eb5f58189b136510 100644 (file)
@@ -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;
index e8abd02504ea3ff94b2ef7fe2d29db573606a5bd..a0a597441876a1e42e27fc2e8074fee2a10f4fe6 100644 (file)
@@ -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);
index 13f49f82975938d9ef8be647a1300a5e4c1c645b..417a15dcda9ee5c7c0d797c3d1205ace35d55364 100644 (file)
@@ -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;
index e6e0aba40b52a5bb365441d23e6aac3487c10b2d..84098b511f6563af6a6b575fb32aa26226313eaa 100644 (file)
@@ -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<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+      in_ofs /= 2; \
+      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// yuv420pi  2x2
+#define xfer_yuv420pi_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
+    int ot_k = ((i/4)<<1) + (i&1); \
+    out_rofs = ot_k * total_out_w / 2 + out_x / 2; \
+    oty_t *uop = (oty_t *)(out_up + out_rofs); \
+    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv420pi_row_in(ity_t) \
+    int in_r = row_table[i]; \
+    int in_rofs = in_r * total_in_w; \
     uint8_t *yip_row = in_yp + in_rofs; \
-    in_rofs = row_table[i] / 2 * total_in_w / 2; \
+    int in_k = ((in_r/4)<<1) + (in_r&1); \
+    in_rofs = in_k * 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<out_w; ++j ) { \
index 2379201d7c66cceb2d6d5a0cb3acb0737431741e..c836f196e52d7c970645d3a8bcad93d05c3f5f9d 100644 (file)
@@ -1991,7 +1991,7 @@ int TitleMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
                config.size = 72;
        if(config.stroke_width < 0 || config.stroke_width >= 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();