repair default keyframe load, tweak init default histogram threshold
[goodguy/history.git] / cinelerra-5.1 / cinelerra / filempeg.C
index cef98f4dab2df6629b2ff85af1a385ac71efeca7..6c889b92c6cb7a169d3fcde23571454939682c87 100644 (file)
@@ -2,21 +2,21 @@
 /*
  * CINELERRA
  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
 
 #include "asset.h"
@@ -55,7 +55,7 @@
 
 
 // M JPEG dependancies
-static double frame_rate_codes[] = 
+static double frame_rate_codes[] =
 {
        0,
        24000.0/1001.0,
@@ -104,11 +104,9 @@ FileMPEG::~FileMPEG()
        vcommand_line.remove_all_objects();
 }
 
-void FileMPEG::get_parameters(BC_WindowBase *parent_window, 
-       Asset *asset, 
-       BC_WindowBase* &format_window,
-       int audio_options,
-       int video_options)
+void FileMPEG::get_parameters(BC_WindowBase *parent_window,
+       Asset *asset, BC_WindowBase* &format_window,
+       int audio_options, int video_options, EDL *edl)
 {
        if(audio_options && asset->format == FILE_AMPEG)
        {
@@ -159,7 +157,7 @@ void FileMPEG::get_info(char *title_path, char *path, char *text, int len)
                cp += snprintf(cp,ep-cp, _("file path:%s\n"), path);
        int64_t bytes = mpeg3_get_bytes(fd);
        char string[BCTEXTLEN];
-       sprintf(string,"%ld",bytes);
+       sprintf(string,"%jd",bytes);
        Units::punctuate(string);
        cp += snprintf(cp,ep-cp, _("size: %s"), string);
 
@@ -192,7 +190,7 @@ void FileMPEG::get_info(char *title_path, char *path, char *text, int len)
                cp += snprintf(cp,ep-cp, _("  v%d %s %dx%d"), vtrk, cmodel, width, height);
                double frame_rate = mpeg3_frame_rate(fd, vtrk);
                int64_t frames = mpeg3_video_frames(fd, vtrk);
-               cp += snprintf(cp,ep-cp, _(" (%5.2f), %ld frames"), frame_rate, frames);
+               cp += snprintf(cp,ep-cp, _(" (%5.2f), %jd frames"), frame_rate, frames);
                if( frame_rate > 0 ) {
                        double secs = (double)frames / frame_rate;
                        cp += snprintf(cp,ep-cp, _(" (%0.3f secs)"),secs);
@@ -208,10 +206,10 @@ void FileMPEG::get_info(char *title_path, char *path, char *text, int len)
                int sample_rate = mpeg3_sample_rate(fd, atrk);
                cp += snprintf(cp,ep-cp, _(" ch%d (%d)"), channels, sample_rate);
                int64_t samples = mpeg3_audio_samples(fd, atrk);
-               cp += snprintf(cp,ep-cp, " %ld",samples);
+               cp += snprintf(cp,ep-cp, " %jd",samples);
                int64_t nudge = mpeg3_get_audio_nudge(fd, atrk);
                *cp++ = nudge >= 0 ? '+' : (nudge=-nudge, '-');
-               cp += snprintf(cp,ep-cp, _("%ld samples"),nudge);
+               cp += snprintf(cp,ep-cp, _("%jd samples"),nudge);
                if( sample_rate > 0 ) {
                        double secs = (double)(samples+nudge) / sample_rate;
                        cp += snprintf(cp,ep-cp, _(" (%0.3f secs)"),secs);
@@ -244,7 +242,7 @@ void FileMPEG::get_info(char *title_path, char *path, char *text, int len)
                cp += snprintf(cp,ep-cp, _("cell times:"));
                for( int i=0; i<cell_times.size(); ++i ) {
                        if( (i%4) == 0 ) *cp++ = '\n';
-                       cp += snprintf(cp,ep-cp,_("  %3d.  %8.3f"),i,cell_times.get(i));
+                       cp += snprintf(cp,ep-cp,"  %3d.  %8.3f",i,cell_times.get(i));
                }
                cp += snprintf(cp,ep-cp, "\n");
        }
@@ -451,7 +449,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 == ILACE_MODE_UNDETECTED )
+//                                     asset->interlace_mode = mpeg3_detect_interlace(fd, 0);
                                if( !asset->layers ) {
                                        asset->layers = mpeg3_total_vstreams(fd);
                                }
@@ -473,7 +475,7 @@ int FileMPEG::open_file(int rd, int wr)
                        eprintf(_("Couldn't open %s: failed.\n"), asset->path);
                }
        }
-       
+
        if( !result && wr && asset->format == FILE_VMPEG ) {
 // Heroine Virtual encoder
 //  this one is cinelerra-x.x.x/mpeg2enc
@@ -490,9 +492,10 @@ int FileMPEG::open_file(int rd, int wr)
 // Construct command line
                        if(!result)
                        {
-                               char string[BCTEXTLEN];
-                               get_exe_path(string);
-                               sprintf(mjpeg_command, "%s/%s", string, HVPEG_EXE);
+                               const char *exec_path = File::get_cinlib_path();
+                               snprintf(mjpeg_command, sizeof(mjpeg_command),
+                                       "%s/%s", exec_path, HVPEG_EXE);
+                               append_vcommand_line(mjpeg_command);
 
                                if(asset->aspect_ratio > 0)
                                {
@@ -516,7 +519,7 @@ int FileMPEG::open_file(int rd, int wr)
                                append_vcommand_line(asset->vmpeg_cmodel == BC_YUV422P ? "-422" : "");
                                if(asset->vmpeg_fix_bitrate)
                                {
-                                       append_vcommand_line("--cbr -b");
+                                       append_vcommand_line("-b");
                                        append_vcommand_line(bitrate_string);
                                }
                                else
@@ -540,9 +543,9 @@ int FileMPEG::open_file(int rd, int wr)
 // mjpegtools encoder
 //  this one is cinelerra-x.x.x/thirdparty/mjpegtools/mpeg2enc
                {
-                       char string[BCTEXTLEN];
-                       get_exe_path(string);
-                       sprintf(mjpeg_command, "%s/%s -v 0 ", string, MJPEG_EXE);
+                       const char *exec_path = File::get_cinlib_path();
+                       snprintf(mjpeg_command, sizeof(mjpeg_command),
+                               "%s/%s -v 0 ", exec_path, MJPEG_EXE);
 
 // Must disable interlacing if MPEG-1
                        switch (asset->vmpeg_preset)
@@ -552,25 +555,20 @@ 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.
                        if(asset->vmpeg_fix_bitrate)
                        {
-                               sprintf(string, " -b %d -q 1", asset->vmpeg_bitrate / 1000);
+                               snprintf(string, sizeof(string),
+                                       " -b %d -q 1", asset->vmpeg_bitrate / 1000);
                        }
                        else
                        {
-                               sprintf(string, " -b 0 -q %d", asset->vmpeg_quantization);
+                               snprintf(string, sizeof(string),
+                                       " -b 0 -q %d", asset->vmpeg_quantization);
                        }
-                       strcat(mjpeg_command, string);
-
-
-
-
-
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
 
 // Aspect ratio
                        int aspect_ratio_code = -1;
@@ -591,14 +589,14 @@ int FileMPEG::open_file(int rd, int wr)
 // Square pixels
                        if(EQUIV((double)asset->width / asset->height, asset->aspect_ratio))
                                aspect_ratio_code = 1;
-                       
+
                        if(aspect_ratio_code < 0)
                        {
                                eprintf(_("Unsupported aspect ratio %f\n"), asset->aspect_ratio);
                                aspect_ratio_code = 2;
                        }
                        sprintf(string, " -a %d", aspect_ratio_code);
-                       strcat(mjpeg_command, string);
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
 
 
 
@@ -622,43 +620,49 @@ int FileMPEG::open_file(int rd, int wr)
                                eprintf(_("Unsupported frame rate %f\n"), asset->frame_rate);
                        }
                        sprintf(string, " -F %d", frame_rate_code);
-                       strcat(mjpeg_command, string);
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
+
 
 
 
 
+                       strncat(mjpeg_command,
+                               asset->vmpeg_progressive ? " -I 0" : " -I 1",
+                               sizeof(mjpeg_command));
 
-                       strcat(mjpeg_command, 
-                               asset->vmpeg_progressive ? " -I 0" : " -I 1");
-                       
 
 
                        sprintf(string, " -M %d", file->cpus);
-                       strcat(mjpeg_command, string);
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
 
 
                        if(!asset->vmpeg_progressive)
                        {
-                               strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
+                               strncat(mjpeg_command,
+                                       asset->vmpeg_field_order ? " -z b" : " -z t",
+                                       sizeof(mjpeg_command));
                        }
 
 
-                       sprintf(string, " -f %d", asset->vmpeg_preset);
-                       strcat(mjpeg_command, string);
+                       snprintf(string, sizeof(string), " -f %d", asset->vmpeg_preset);
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
 
 
-                       sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
-                       strcat(mjpeg_command, string);
+                       snprintf(string, sizeof(string),
+                               " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
 
 
-                       if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
+                       if(asset->vmpeg_seq_codes)
+                               strncat(mjpeg_command, " -s", sizeof(mjpeg_command));
 
 
-                       sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
-                       strcat(mjpeg_command, string);
+                       snprintf(string, sizeof(string),
+                               " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
 
-                       sprintf(string, " -o '%s'", asset->path);
-                       strcat(mjpeg_command, string);
+                       snprintf(string, sizeof(string), " -o '%s'", asset->path);
+                       strncat(mjpeg_command, string, sizeof(mjpeg_command));
 
 
 
@@ -698,7 +702,7 @@ int FileMPEG::open_file(int rd, int wr)
 //                     lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
                        lame_set_brate(lame_global, asset->ampeg_bitrate);
                        lame_set_quality(lame_global, 0);
-                       lame_set_in_samplerate(lame_global, 
+                       lame_set_in_samplerate(lame_global,
                                asset->sample_rate);
                        lame_set_num_channels(lame_global,
                                asset->channels);
@@ -770,6 +774,7 @@ int FileMPEG::skim_video(int track, void *vp, skim_fn fn)
 
 
 
+#ifdef HAVE_COMMERCIAL
 int FileMPEG::toc_nail(void *vp, int track)
 {
        File *file = (File *)vp;
@@ -780,18 +785,19 @@ int FileMPEG::toc_nail(void *vp, int track)
        if( mpeg->get_video_info(track, pid, framerate, width, height) ) return 1;
        if( pid < 0 || framerate <= 0 ) return 1;
        double position = framenum / framerate;
-//printf("t%d/%03x f"_LD", %dx%d %dx%d\n",track,pid,framenum,mw,mh,width,height);
+//printf("t%d/%03x f%jd, %dx%d %dx%d\n",track,pid,framenum,mw,mh,width,height);
        MWindow::commercials->get_frame(file, pid, position, tdat, mw, mh, width, height);
        return 0;
 }
-
+#endif
 
 int FileMPEG::create_toc(char *toc_path)
 {
 // delete any existing toc files
        char toc_file[BCTEXTLEN];
        strcpy(toc_file, toc_path);
-       remove(toc_file);
+       if( strcmp(toc_file, asset->path) )
+               remove(toc_file);
        char *bp = strrchr(toc_file, '/');
        if( !bp ) bp = toc_file;
        char *sfx = strrchr(bp,'.');
@@ -811,11 +817,13 @@ int FileMPEG::create_toc(char *toc_path)
 // File needs a table of contents.
        struct timeval new_time, prev_time, start_time, current_time;
        gettimeofday(&prev_time, 0);  gettimeofday(&start_time, 0);
+#ifdef HAVE_COMMERCIAL
        if( file->preferences->scan_commercials ) {
                set_skimming(-1, 1, toc_nail, file);
                if( MWindow::commercials->resetDb() != 0 )
                        eprintf(_("cant access commercials database"));
        }
+#endif
 // This gets around the fact that MWindowGUI may be locked.
        char progress_title[BCTEXTLEN];
        sprintf(progress_title, _("Creating %s\n"), toc_file);
@@ -846,7 +854,7 @@ int FileMPEG::create_toc(char *toc_path)
                        sprintf(string, "%sETA: %jdm%jds",
                                progress_title, eta / 60, eta % 60);
                        progress.update_title(string, 1);
-//                     fprintf(stderr, "ETA: %dm%ds        \r", 
+//                     fprintf(stderr, "ETA: %dm%ds        \r",
 //                             bytes_processed * 100 / total_bytes,
 //                             eta / 60, eta % 60);
 //                     fflush(stdout);
@@ -859,10 +867,12 @@ int FileMPEG::create_toc(char *toc_path)
                }
        }
 
+#ifdef HAVE_COMMERCIAL
        if( file->preferences->scan_commercials ) {
                if( !result ) MWindow::commercials->write_ads(asset->path);
                MWindow::commercials->closeDb();
        }
+#endif
 
        mpeg3_stop_toc(fd);
        fd = 0;
@@ -951,7 +961,7 @@ int FileMPEG::close_file()
        vcommand_line.remove_all_objects();
 
        if(twofp) {
-               unsigned char opkt[1152*2]; 
+               unsigned char opkt[1152*2];
                int ret = twolame_encode_flush(twopts, opkt, sizeof(opkt));
                if( ret > 0 )
                        fwrite(opkt, 1, ret, twofp);
@@ -991,20 +1001,18 @@ int FileMPEG::get_best_colormodel(Asset *asset, int driver)
        switch(driver)
        {
                case PLAYBACK_X11:
-                       return BC_RGB888;
+//                     return BC_RGB888;
+// the direct X11 color model requires scaling in the codec
+                       return BC_BGR8888;
                case PLAYBACK_X11_XV:
                case PLAYBACK_ASYNCHRONOUS:
                        return zmpeg3_cmdl(asset->vmpeg_cmodel) > 0 ?
                                asset->vmpeg_cmodel : BC_RGB888;
                case PLAYBACK_X11_GL:
                        return BC_YUV888;
-               case PLAYBACK_LML:
-               case PLAYBACK_BUZ:
-                       return BC_YUV422P;
                case PLAYBACK_DV1394:
                case PLAYBACK_FIREWIRE:
                        return BC_YUV422P;
-               case VIDEO4LINUX:
                case VIDEO4LINUX2:
                        return zmpeg3_cmdl(asset->vmpeg_cmodel) > 0 ?
                                asset->vmpeg_cmodel : BC_RGB888;
@@ -1017,9 +1025,6 @@ int FileMPEG::get_best_colormodel(Asset *asset, int driver)
                        return BC_COMPRESSED;
                case CAPTURE_YUYV_WEBCAM:
                        return BC_YUV422;
-               case CAPTURE_BUZ:
-               case CAPTURE_LML:
-                       return BC_YUV422;
                case CAPTURE_FIREWIRE:
                case CAPTURE_IEC61883:
                        return BC_YUV422P;
@@ -1042,7 +1047,7 @@ int FileMPEG::set_audio_position(int64_t sample)
 {
 #if 0
        if(!fd) return 1;
-       
+
        int channel, stream;
        to_streamchannel(file->current_channel, stream, channel);
 
@@ -1271,12 +1276,16 @@ 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 == ILACE_MODE_TOP_FIRST ||
+                             asset->interlace_mode == ILACE_MODE_BOTTOM_FIRST ) )
+                               output_cmodel = BC_YUV420PI;
                case BC_YUV422P:
                        break;
                default:
                        return 1;
                }
-               
+
 // Height depends on progressiveness
                if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
                        temp_h = (int)((asset->height + 15) / 16) * 16;
@@ -1284,23 +1293,23 @@ int FileMPEG::write_frames(VFrame ***frames, int len)
                        temp_h = (int)((asset->height + 31) / 32) * 32;
 
 //printf("FileMPEG::write_frames 1\n");
-               
+
 // Only 1 layer is supported in MPEG output
                for(int i = 0; i < 1; i++)
                {
                        for(int j = 0; j < len && !result; j++)
                        {
                                VFrame *frame = frames[i][j];
-                               
-                               
-                               
+
+
+
                                if(asset->vmpeg_cmodel == BC_YUV422P)
                                {
                                        if(frame->get_w() == temp_w &&
                                                frame->get_h() == temp_h &&
                                                frame->get_color_model() == output_cmodel)
                                        {
-                                               mpeg2enc_set_input_buffers(0, 
+                                               mpeg2enc_set_input_buffers(0,
                                                        (char*)frame->get_y(),
                                                        (char*)frame->get_u(),
                                                        (char*)frame->get_v());
@@ -1319,15 +1328,11 @@ int FileMPEG::write_frames(VFrame ***frames, int len)
 
                                                if(!temp_frame)
                                                {
-                                                       temp_frame = new VFrame(0, 
-                                                               -1,
-                                                               temp_w, 
-                                                               temp_h, 
-                                                               output_cmodel,
-                                                               -1);
+                                                       temp_frame = new VFrame(temp_w, temp_h,
+                                                                       output_cmodel, 0);
                                                }
 
-                                               BC_CModels::transfer(temp_frame->get_rows(), 
+                                               BC_CModels::transfer(temp_frame->get_rows(),
                                                        frame->get_rows(),
                                                        temp_frame->get_y(),
                                                        temp_frame->get_u(),
@@ -1343,13 +1348,13 @@ int FileMPEG::write_frames(VFrame ***frames, int len)
                                                        0,
                                                        temp_frame->get_w(),
                                                        temp_frame->get_h(),
-                                                       frame->get_color_model(), 
+                                                       frame->get_color_model(),
                                                        temp_frame->get_color_model(),
-                                                       0, 
+                                                       0,
                                                        frame->get_w(),
                                                        temp_frame->get_w());
 
-                                               mpeg2enc_set_input_buffers(0, 
+                                               mpeg2enc_set_input_buffers(0,
                                                        (char*)temp_frame->get_y(),
                                                        (char*)temp_frame->get_u(),
                                                        (char*)temp_frame->get_v());
@@ -1370,15 +1375,11 @@ int FileMPEG::write_frames(VFrame ***frames, int len)
 //printf("FileMPEG::write_frames %d\n", __LINE__);sleep(1);
                                                if(!temp_frame)
                                                {
-                                                       temp_frame = new VFrame(0, 
-                                                               -1,
-                                                               asset->width, 
-                                                               asset->height, 
-                                                               output_cmodel,
-                                                               -1);
+                                                       temp_frame = new VFrame(asset->width, asset->height,
+                                                                               output_cmodel, 0);
                                                }
 
-// printf("FileMPEG::write_frames %d temp_frame=%p %p %p %p frame=%p %p %p %p color_model=%p %p\n", 
+// printf("FileMPEG::write_frames %d temp_frame=%p %p %p %p frame=%p %p %p %p color_model=%p %p\n",
 // __LINE__,
 // temp_frame,
 // temp_frame->get_w(),
@@ -1388,27 +1389,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();
@@ -1438,7 +1419,7 @@ int FileMPEG::write_frames(VFrame ***frames, int len)
 }
 
 int FileMPEG::zmpeg3_cmdl(int colormodel)
-{   
+{
        switch( colormodel ) {
        case BC_BGR888:       return zmpeg3_t::cmdl_BGR888;
        case BC_BGR8888:      return zmpeg3_t::cmdl_BGRA8888;
@@ -1453,7 +1434,7 @@ int FileMPEG::zmpeg3_cmdl(int colormodel)
        case BC_YUVA8888:     return zmpeg3_t::cmdl_YUVA8888;
        }
        return -1;
-}   
+}
 
 int FileMPEG::bc_colormodel(int cmdl)
 {
@@ -1515,12 +1496,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 == 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() ) {
@@ -1561,11 +1543,11 @@ int FileMPEG::read_frame(VFrame *frame)
                        for( int i=0; i<uvh; ++i, rp+=uvw ) rows[n++] = rp;
                }
 
-               mpeg3_read_frame(fd, 
+               mpeg3_read_frame(fd,
                                rows,                /* start of each output row */
                                0, 0, width, height, /* input box */
                                frame->get_w(),      /* Dimensions of output_rows */
-                               frame->get_h(), 
+                               frame->get_h(),
                                frame_cmdl,
                                file->current_layer);
                return result;
@@ -1574,20 +1556,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 == ILACE_MODE_TOP_FIRST ||
+                       asset->interlace_mode == 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;
@@ -1617,10 +1595,10 @@ int FileMPEG::read_samples(double *buffer, int64_t len)
 
 //printf("FileMPEG::read_samples 1 current_sample=%jd len=%jd channel=%d\n", file->current_sample, len, channel);
 
-       mpeg3_set_sample(fd, 
+       mpeg3_set_sample(fd,
                file->current_sample,
                stream);
-       mpeg3_read_audio_d(fd, 
+       mpeg3_read_audio_d(fd,
                buffer, /* Pointer to pre-allocated buffer of doubles */
                channel,          /* Channel to decode */
                len,         /* Number of samples to decode */
@@ -1748,13 +1726,7 @@ MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
  : BC_Window(_(PROGRAM_NAME ": Audio Compression"),
        parent_window->get_abs_cursor_x(1),
        parent_window->get_abs_cursor_y(1),
-       310,
-       120,
-       -1,
-       -1,
-       0,
-       0,
-       1)
+       310, 120, -1, -1, 0, 0, 1)
 {
        this->parent_window = parent_window;
        this->asset = asset;
@@ -1801,11 +1773,6 @@ int MPEGConfigAudio::close_event()
 }
 
 
-
-
-
-
-
 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
  : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
 {
@@ -1860,9 +1827,7 @@ char* MPEGLayer::layer_to_string(int layer)
 
 
 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
- : BC_PopupMenu(x,
-       y,
-       100,
+ : BC_PopupMenu(x, y, 100,
        bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
 {
        this->gui = gui;
@@ -1940,13 +1905,7 @@ MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window,
  : BC_Window(_(PROGRAM_NAME ": Video Compression"),
        parent_window->get_abs_cursor_x(1),
        parent_window->get_abs_cursor_y(1),
-       500,
-       400,
-       -1,
-       -1,
-       0,
-       0,
-       1)
+       500, 400, -1, -1, 0, 0, 1)
 {
        this->parent_window = parent_window;
        this->asset = asset;
@@ -2089,17 +2048,6 @@ void MPEGConfigVideo::update_cmodel_objs()
 }
 
 
-
-
-
-
-
-
-
-
-
-
-
 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
  : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
 {
@@ -2120,42 +2068,21 @@ int MPEGDerivative::handle_event()
 
 int MPEGDerivative::string_to_derivative(char *string)
 {
-       if(!strcasecmp(derivative_to_string(1), string))
-               return 1;
-       if(!strcasecmp(derivative_to_string(2), string))
-               return 2;
-
+       if( !strcasecmp(derivative_to_string(1), string) ) return 1;
+       if( !strcasecmp(derivative_to_string(2), string) ) return 2;
        return 1;
 }
 
 char* MPEGDerivative::derivative_to_string(int derivative)
 {
-       switch(derivative)
-       {
-               case 1:
-                       return _("MPEG-1");
-                       break;
-
-               case 2:
-                       return _("MPEG-2");
-                       break;
-
-               default:
-                       return _("MPEG-1");
-                       break;
+       switch(derivative) {
+       case 1: return _("MPEG-1");
+       case 2: return _("MPEG-2");
        }
+       return _("MPEG-1");
 }
 
 
-
-
-
-
-
-
-
-
-
 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
  : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
 {
@@ -2164,8 +2091,7 @@ MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
 
 void MPEGPreset::create_objects()
 {
-       for(int i = 0; i < 10; i++)
-       {
+       for(int i = 0; i < 14; i++) {
                add_item(new BC_MenuItem(value_to_string(i)));
        }
 }
@@ -2178,8 +2104,7 @@ int MPEGPreset::handle_event()
 
 int MPEGPreset::string_to_value(char *string)
 {
-       for(int i = 0; i < 10; i++)
-       {
+       for(int i = 0; i < 14; i++) {
                if(!strcasecmp(value_to_string(i), string))
                        return i;
        }
@@ -2188,20 +2113,23 @@ int MPEGPreset::string_to_value(char *string)
 
 char* MPEGPreset::value_to_string(int derivative)
 {
-       switch(derivative)
-       {
-               case 0: return _("Generic MPEG-1"); break;
-               case 1: return _("standard VCD"); break;
-               case 2: return _("user VCD"); break;
-               case 3: return _("Generic MPEG-2"); break;
-               case 4: return _("standard SVCD"); break;
-               case 5: return _("user SVCD"); break;
-               case 6: return _("VCD Still sequence"); break;
-               case 7: return _("SVCD Still sequence"); break;
-               case 8: return _("DVD NAV"); break;
-               case 9: return _("DVD"); break;
-               default: return _("Generic MPEG-1"); break;
+       switch( derivative ) {
+       case 0: return _("Generic MPEG-1"); break;
+       case 1: return _("standard VCD"); break;
+       case 2: return _("user VCD"); break;
+       case 3: return _("Generic MPEG-2"); break;
+       case 4: return _("standard SVCD"); break;
+       case 5: return _("user SVCD"); break;
+       case 6: return _("VCD Still sequence"); break;
+       case 7: return _("SVCD Still sequence"); break;
+       case 8: return _("DVD NAV"); break;
+       case 9: return _("DVD"); break;
+       case 10: return _("ATSC 480i"); break;
+       case 11: return _("ATSC 480p"); break;
+       case 12: return _("ATSC 720p"); break;
+       case 13: return _("ATSC 1080i"); break;
        }
+       return _("Generic MPEG-1");
 }