X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ffilempeg.C;h=6c889b92c6cb7a169d3fcde23571454939682c87;hp=8b73e6d59a6b5f1a1c312ec63d8d55d95f3158a8;hb=2e48b660e37eb5c661264d601211e16cb6cd6e89;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd diff --git a/cinelerra-5.1/cinelerra/filempeg.C b/cinelerra-5.1/cinelerra/filempeg.C index 8b73e6d5..6c889b92 100644 --- a/cinelerra-5.1/cinelerra/filempeg.C +++ b/cinelerra-5.1/cinelerra/filempeg.C @@ -2,21 +2,21 @@ /* * CINELERRA * Copyright (C) 2008 Adam Williams - * + * * 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; ipreferences->get_asset_file_path(asset, toc_name); - int error = 0; - fd = mpeg3_open_title(asset->path, toc_name, &error); - if( !fd ) { - result = 1; - if(error == zmpeg3_t::ERR_INVALID_TOC_VERSION) { - eprintf(_("Couldn't open %s: invalid table of contents version.\n" - "Rebuilding the table of contents."), asset->path); - } - else if(error == zmpeg3_t::ERR_TOC_DATE_MISMATCH) { - eprintf(_("Couldn't open %s: table of contents out of date.\n" - "Rebuilding the table of contents."), asset->path); + if( result >= 0 ) { + int error = 0; +// if toc exists, use it otherwise just probe file + char *path = !result ? toc_name : asset->path; + fd = mpeg3_open_title(asset->path, path, &error); + if( !fd ) { + switch( error ) { + case zmpeg3_t::ERR_INVALID_TOC_VERSION: + eprintf(_("Couldn't open %s: invalid table of contents version.\n"),asset->path); + result = 1; + break; + case zmpeg3_t::ERR_TOC_DATE_MISMATCH: + eprintf(_("Couldn't open %s: table of contents out of date.\n"),asset->path); + result = 1; + break; + default: + eprintf(_("Couldn't open %s: table of contents corrupt.\n"),asset->path); + result = -1; + break; + } + if( result > 0 ) { + eprintf(_("Rebuilding the table of contents\n")); + } + } else { - eprintf(_("Couldn't open %s: table of contents corrupt.\n" - "Rebuilding the table of contents."), asset->path); - } - char filename[BCTEXTLEN]; - strcpy(filename, toc_name); - char *sfx = strrchr(filename,'.'); - if( sfx && !strcmp(sfx+1,"toc") ) { - remove(filename); - strcpy(sfx+1,"idx"); - remove(filename); - strcpy(toc_name, asset->path); - fd = mpeg3_open_title(asset->path, toc_name, &error); - if( fd ) result = 0; + if( mpeg3_has_toc(fd) ) + result = 0; + else if( mpeg3_total_vstreams(fd) || mpeg3_total_astreams(fd) ) + result = 1; + else { + eprintf(_("Couldn't open %s: no audio or video.\n"),asset->path); + result = -1; + } } - if( result ) - eprintf(_("Couldn't open %s: rebuild failed.\n"), asset->path); } - if(!result) { -// Determine if the file needs a table of contents and create one if needed. -// If it has video it must be scanned since video has keyframes. - if(mpeg3_total_vstreams(fd) || mpeg3_total_astreams(fd)) { - if(create_index()) return 1; - } -// more than 4 doesnt help much + if( result > 0 ) { + if( fd ) { mpeg3_close(fd); fd = 0; } + result = create_toc(toc_name); + } + + if( !result ) { mpeg3_set_cpus(fd, file->cpus < 4 ? file->cpus : 4); file->current_program = mpeg3_set_program(fd, -1); if( asset->program < 0 ) @@ -439,14 +443,17 @@ int FileMPEG::open_file(int rd, int wr) if(!asset->sample_rate) asset->sample_rate = mpeg3_sample_rate(fd, 0); asset->audio_length = mpeg3_audio_samples(fd, 0); - if(!asset->channels || - !asset->sample_rate) + if( !asset->channels || !asset->sample_rate ) result = 1; } asset->video_data = mpeg3_has_video(fd); - if(asset->video_data) { - asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; + if( !result && asset->video_data ) { +//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); } @@ -464,12 +471,12 @@ int FileMPEG::open_file(int rd, int wr) asset->frame_rate = mpeg3_frame_rate(fd, 0); } } + if( result ) { + eprintf(_("Couldn't open %s: failed.\n"), asset->path); + } } - - - if(!result && wr && asset->format == FILE_VMPEG) - { + if( !result && wr && asset->format == FILE_VMPEG ) { // Heroine Virtual encoder // this one is cinelerra-x.x.x/mpeg2enc if(asset->vmpeg_cmodel == BC_YUV422P) @@ -485,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) { @@ -511,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 @@ -535,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) @@ -547,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; @@ -586,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)); @@ -617,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)); @@ -669,9 +678,7 @@ int FileMPEG::open_file(int rd, int wr) video_out->start(); } } - else - if(wr && asset->format == FILE_AMPEG) - { + else if( !result && wr && asset->format == FILE_AMPEG) { //char encoder_string[BCTEXTLEN]; encoder_string[0] = 0; //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative); @@ -695,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); @@ -723,11 +730,9 @@ int FileMPEG::open_file(int rd, int wr) } // Transport stream for DVB capture - if(!result && !rd && !wr && asset->format == FILE_MPEG) - { + if( !result && !rd && !wr && asset->format == FILE_MPEG ) { if( (recd_fd = open(asset->path, O_CREAT+O_TRUNC+O_WRONLY, - S_IRUSR+S_IWUSR + S_IRGRP+S_IWGRP)) < 0 ) - { + S_IRUSR+S_IWUSR + S_IRGRP+S_IWGRP)) < 0 ) { perror("FileMPEG::open_file"); eprintf(_("Error while opening \"%s\" for writing\n%m\n"), asset->path); result = 1; @@ -769,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; @@ -779,125 +785,142 @@ 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); + if( strcmp(toc_file, asset->path) ) + remove(toc_file); + char *bp = strrchr(toc_file, '/'); + if( !bp ) bp = toc_file; + char *sfx = strrchr(bp,'.'); + if( sfx ) { + strcpy(sfx+1,"toc"); + remove(toc_file); + } -int FileMPEG::create_index() -{ -// Calculate TOC path - char index_filename[BCTEXTLEN]; - char source_filename[BCTEXTLEN]; - - IndexFile::get_index_filename(source_filename, - file->preferences->index_directory, - index_filename, - asset->path); - char *ptr = strrchr(index_filename, '.'); - int error = 0; - - if(!ptr) return 1; - -// File is a table of contents. - if(fd && mpeg3_has_toc(fd)) return 0; - - sprintf(ptr, ".toc"); - - int need_toc = 1; + int64_t total_bytes = 0, last_bytes = -1; + fd = mpeg3_start_toc(asset->path, toc_file, + file->current_program, &total_bytes); + if( !fd ) { + eprintf(_("cant start toc/idx for file: %s\n"), asset->path); + return 1; + } - if(fd) mpeg3_close(fd); - fd = 0; +// 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); + BC_ProgressBox progress(-1, -1, progress_title, total_bytes); + progress.start(); -// Test existing copy of TOC - if((fd = mpeg3_open_title(asset->path, index_filename, &error))) - need_toc = 0; + int result = 0; + while( !result ) { + int64_t bytes_processed = 0; + if( mpeg3_do_toc(fd, &bytes_processed) ) break; - if(need_toc) - { - int result = 0; -// Create progress window. -// This gets around the fact that MWindowGUI is locked. - int64_t total_bytes = 0, last_bytes = -1; - fd = mpeg3_start_toc( asset->path, index_filename, - file->current_program, &total_bytes); - if( !fd ) { - eprintf(_("cant init toc index\n")); - result = 1; + if( bytes_processed >= total_bytes ) break; + if( bytes_processed == last_bytes ) { + eprintf(_("toc scan stopped before eof")); + break; } - - struct timeval new_time, prev_time, start_time, current_time; - gettimeofday(&prev_time, 0); gettimeofday(&start_time, 0); - - if( !result && file->preferences->scan_commercials ) { - set_skimming(-1, 1, toc_nail, file); - if( (result=MWindow::commercials->resetDb() ) != 0 ) - eprintf(_("cant access commercials database")); + last_bytes = bytes_processed; + + gettimeofday(&new_time, 0); + if( new_time.tv_sec - prev_time.tv_sec >= 1 ) { + gettimeofday(¤t_time, 0); + int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec; + int64_t total_seconds = !bytes_processed ? 0 : + elapsed_seconds * total_bytes / bytes_processed; + int64_t eta = total_seconds - elapsed_seconds; + progress.update(bytes_processed, 1); + char string[BCTEXTLEN]; + sprintf(string, "%sETA: %jdm%jds", + progress_title, eta / 60, eta % 60); + progress.update_title(string, 1); +// fprintf(stderr, "ETA: %dm%ds \r", +// bytes_processed * 100 / total_bytes, +// eta / 60, eta % 60); +// fflush(stdout); + prev_time = new_time; } - char progress_title[BCTEXTLEN]; progress_title[0] = 0; - BC_ProgressBox *progress = 0; - if( !result ) { - sprintf(progress_title, _("Creating %s\n"), index_filename); - progress = new BC_ProgressBox(-1, -1, - progress_title, total_bytes); - progress->start(); + if( progress.is_cancelled() ) { + result = 1; + break; } + } - while( !result ) { - int64_t bytes_processed = 0; - if( mpeg3_do_toc(fd, &bytes_processed) ) break; - gettimeofday(&new_time, 0); +#ifdef HAVE_COMMERCIAL + if( file->preferences->scan_commercials ) { + if( !result ) MWindow::commercials->write_ads(asset->path); + MWindow::commercials->closeDb(); + } +#endif - if(new_time.tv_sec - prev_time.tv_sec >= 1) - { - gettimeofday(¤t_time, 0); - int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec; - int64_t total_seconds = !bytes_processed ? 0 : - elapsed_seconds * total_bytes / bytes_processed; - int64_t eta = total_seconds - elapsed_seconds; - progress->update(bytes_processed, 1); - char string[BCTEXTLEN]; - sprintf(string, "%sETA: %jdm%jds", - progress_title, eta / 60, eta % 60); - progress->update_title(string, 1); -// fprintf(stderr, "ETA: %dm%ds \r", -// bytes_processed * 100 / total_bytes, -// eta / 60, eta % 60); -// fflush(stdout); - prev_time = new_time; - } - if(bytes_processed >= total_bytes) break; - if(progress->is_cancelled()) result = 1; - if( bytes_processed == last_bytes ) { - eprintf(_("toc scan stopped before eof")); - break; - } - last_bytes = bytes_processed; - } + mpeg3_stop_toc(fd); + fd = 0; - // record scan results - if( file->preferences->scan_commercials ) { - if( !result ) MWindow::commercials->write_ads(asset->path); - MWindow::commercials->closeDb(); - } + progress.stop_progress(); - if( fd ) { mpeg3_stop_toc(fd); fd = 0; } - if( progress ) { progress->stop_progress(); delete progress; } - if( result ) { remove_file(index_filename); return 1; } + if( result ) { + remove_file(toc_file); + return 1; } - if(!fd) - { -// Reopen file from index path instead of asset path. - if(!(fd = mpeg3_open(index_filename, &error))) - { - return 1; +// Reopen file from toc path instead of asset path. + int error = 0; + fd = mpeg3_open(toc_file, &error); + if( !fd ) { + eprintf(_("mpeg3_open failed: %s"), toc_file); + return 1; + } + return 0; +} + +int FileMPEG::get_index(IndexFile *index_file, MainProgressBar *progress_bar) +{ + if( !fd ) return 1; + IndexState *index_state = index_file->get_state(); + index_state->reset_index(); + index_state->reset_markers(); + +// Convert the index tables from tracks to channels. + int ntracks = mpeg3_index_tracks(fd); + if( !ntracks ) return 1; + + int index_zoom = mpeg3_index_zoom(fd); + int64_t offset = 0; + for( int i = 0; i < ntracks; ++i ) { + int nch = mpeg3_index_channels(fd, i); + for( int j = 0; j < nch; ++j ) { + float *bfr = (float *)mpeg3_index_data(fd, i, j); + int64_t size = 2*mpeg3_index_size(fd, i); + index_state->add_index_entry(bfr, offset, size); + offset += size; } } - return 0; + FileSystem fs; + int64_t file_bytes = fs.get_size(asset->path); + char *index_path = index_file->index_filename; + return index_state->write_index(index_path, asset, index_zoom, file_bytes); } @@ -938,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); @@ -978,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; @@ -1004,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; @@ -1020,36 +1038,6 @@ int FileMPEG::colormodel_supported(int colormodel) return colormodel; } -int FileMPEG::get_index(char *index_path) -{ - if(!fd) return 1; - IndexState *index_state = asset->index_state; - index_state->reset_index(); - index_state->reset_markers(); - -// Convert the index tables from tracks to channels. - if(mpeg3_index_tracks(fd)) { - int index_zoom = mpeg3_index_zoom(fd); - int ntracks = mpeg3_index_tracks(fd); - int64_t offset = 0; - for(int i = 0; i < ntracks; i++) { - int nch = mpeg3_index_channels(fd, i); - for(int j = 0; j < nch; j++) { - float *bfr = (float *)mpeg3_index_data(fd, i, j); - int64_t size = 2*mpeg3_index_size(fd, i); - index_state->add_index_entry(bfr, offset, size); - offset += size; - } - } - FileSystem fs; - int64_t file_bytes = fs.get_size(asset->path); - return index_state->write_index(index_path, asset, index_zoom, file_bytes); - } - - return 1; -} - - int FileMPEG::can_copy_from(Asset *asset, int64_t position) { return 0; @@ -1059,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); @@ -1288,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; @@ -1301,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()); @@ -1336,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(), @@ -1360,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()); @@ -1387,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(), @@ -1405,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(); @@ -1455,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; @@ -1470,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) { @@ -1532,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() ) { @@ -1578,11 +1543,11 @@ int FileMPEG::read_frame(VFrame *frame) for( int i=0; iget_w(), /* Dimensions of output_rows */ - frame->get_h(), + frame->get_h(), frame_cmdl, file->current_layer); return result; @@ -1591,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; @@ -1634,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 */ @@ -1765,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; @@ -1818,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)) { @@ -1877,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; @@ -1892,10 +1840,7 @@ void MPEGABitrate::create_objects() void MPEGABitrate::set_layer(int layer) { - while(total_items()) - { - remove_item(0); - } + while(total_items()) del_item(0); if(layer == 2) { @@ -1960,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; @@ -2109,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)) { @@ -2140,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)) { @@ -2184,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))); } } @@ -2198,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; } @@ -2208,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"); }