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=fc188a145d71ffe73433be480bbb5aed5ff8d639;hb=2e48b660e37eb5c661264d601211e16cb6cd6e89;hpb=0b78779e9e75131eee81d2e4689b98df0e91c092 diff --git a/cinelerra-5.1/cinelerra/filempeg.C b/cinelerra-5.1/cinelerra/filempeg.C index fc188a14..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); @@ -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 @@ -491,7 +493,8 @@ int FileMPEG::open_file(int rd, int wr) if(!result) { const char *exec_path = File::get_cinlib_path(); - sprintf(mjpeg_command, "%s/%s", exec_path, HVPEG_EXE); + snprintf(mjpeg_command, sizeof(mjpeg_command), + "%s/%s", exec_path, HVPEG_EXE); append_vcommand_line(mjpeg_command); if(asset->aspect_ratio > 0) @@ -541,7 +544,8 @@ int FileMPEG::open_file(int rd, int wr) // this one is cinelerra-x.x.x/thirdparty/mjpegtools/mpeg2enc { const char *exec_path = File::get_cinlib_path(); - sprintf(mjpeg_command, "%s/%s -v 0 ", exec_path, MJPEG_EXE); + snprintf(mjpeg_command, sizeof(mjpeg_command), + "%s/%s -v 0 ", exec_path, MJPEG_EXE); // Must disable interlacing if MPEG-1 switch (asset->vmpeg_preset) @@ -551,26 +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; iget_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;