X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ffile.C;h=2923c7461b366ba74272c6a83ff337188494756b;hb=fee54016102a7a59d2181c8f16a7f2562f68540d;hp=f5932e3e8f07a58a1e2b89ac9c50d126443b452d;hpb=5820b5f022aeec75ec03f7dd0121aa8a3d7f7590;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C index f5932e3e..2923c746 100644 --- a/cinelerra-5.1/cinelerra/file.C +++ b/cinelerra-5.1/cinelerra/file.C @@ -65,11 +65,13 @@ #include "formattools.h" #include "framecache.h" #include "language.h" +#include "mainprogress.inc" #include "mutex.h" #include "mwindow.h" #include "packagingengine.h" #include "pluginserver.h" #include "preferences.h" +#include "probeprefs.h" #include "samples.h" #include "vframe.h" @@ -176,6 +178,7 @@ int File::get_options(FormatTools *format, audio_options, video_options); break; +#ifdef HAVE_DV case FILE_RAWDV: FileDV::get_parameters(parent_window, asset, @@ -183,6 +186,7 @@ int File::get_options(FormatTools *format, audio_options, video_options); break; +#endif case FILE_PCM: case FILE_WAV: case FILE_AU: @@ -356,15 +360,139 @@ int File::delete_oldest() return frame_cache->delete_oldest(); } - - - - - - - - - +// file driver in order of probe precidence +// can be reordered in preferences->interface +const char *File::default_probes[] = { + "FFMPEG_Early", + "Scene", + "DB", +#ifdef HAVE_DV + "DV", +#endif + "SndFile", + "PNG", + "JPEG", + "GIF", + "EXR", + "FLAC", + "CR2", + "TGA", + "TIFF", + "OGG", + "Vorbis", + "MPEG", + "EDL", + "FFMPEG_Late", +}; +const int File::nb_probes = + sizeof(File::default_probes)/sizeof(File::default_probes[0]); + + +int File::probe() +{ + FILE *fp = fopen(this->asset->path, "rb"); + if( !fp ) return FILE_NOT_FOUND; + char data[16]; + memset(data,0,sizeof(data)); + int ret = fread(data, 1, 16, fp); + fclose(fp); + if( !ret ) return FILE_NOT_FOUND; + + for( int i=0; ifile_probes.size(); ++i ) { + ProbePref *pref = preferences->file_probes[i]; + if( !pref->armed ) continue; + if( !strncmp(pref->name,"FFMPEG",6) ) { // FFMPEG Early/Late + if( !FileFFMPEG::check_sig(this->asset) ) continue; + file = new FileFFMPEG(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"DB") ) { // MediaDB + if( !FileDB::check_sig(this->asset) ) continue; + file = new FileDB(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"Scene") ) { // scene file + if( !FileScene::check_sig(this->asset, data)) continue; + file = new FileScene(this->asset, this); + return FILE_OK; + } +#ifdef HAVE_DV + if( !strcmp(pref->name,"DV") ) { // libdv + if( !FileDV::check_sig(this->asset) ) continue; + file = new FileDV(this->asset, this); + return FILE_OK; + } +#endif + if( !strcmp(pref->name,"SndFile") ) { // libsndfile + if( !FileSndFile::check_sig(this->asset) ) continue; + file = new FileSndFile(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"PNG") ) { // PNG file + if( !FilePNG::check_sig(this->asset) ) continue; + file = new FilePNG(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"JPEG") ) { // JPEG file + if( !FileJPEG::check_sig(this->asset) ) continue; + file = new FileJPEG(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"GIF") ) { // GIF file + if( !FileGIF::check_sig(this->asset)) continue; + file = new FileGIF(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"EXR") ) { // EXR file + if( !FileEXR::check_sig(this->asset, data)) continue; + file = new FileEXR(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"FLAC") ) { // FLAC file + if( !FileFLAC::check_sig(this->asset, data)) continue; + file = new FileFLAC(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"CR2") ) { // CR2 file + if( !FileCR2::check_sig(this->asset)) continue; + file = new FileCR2(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"TGA") ) { // TGA file + if( !FileTGA::check_sig(this->asset) ) continue; + file = new FileTGA(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"TIFF") ) { // TIFF file + if( !FileTIFF::check_sig(this->asset) ) continue; + file = new FileTIFF(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"OGG") ) { // OGG file + if( !FileOGG::check_sig(this->asset) ) continue; + file = new FileOGG(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"Vorbis") ) { // VorbisFile file + if( !FileVorbis::check_sig(this->asset) ) continue; + file = new FileVorbis(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"MPEG") ) { // MPEG file + if( !FileMPEG::check_sig(this->asset) ) continue; + file = new FileMPEG(this->asset, this); + return FILE_OK; + } + if( !strcmp(pref->name,"EDL") ) { // XML file + if( data[0] != '<' ) continue; + if( !strncmp(&data[1],"EDL>",4) || + !strncmp(&data[1],"HTAL>",5) || + !strncmp(&data[1],"?xml",4) ) + return FILE_IS_XML; + } + } + return FILE_UNRECOGNIZED_CODEC; // maybe PCM file ? +} int File::open_file(Preferences *preferences, Asset *asset, @@ -383,136 +511,14 @@ int File::open_file(Preferences *preferences, if(debug) printf("File::open_file %p %d\n", this, __LINE__); - switch(this->asset->format) - { + switch(this->asset->format) { // get the format now // If you add another format to case 0, you also need to add another case for the // file format #define. - case FILE_UNKNOWN: - if(FileDB::check_sig(this->asset)) { -// MediaDb file - file = new FileDB(this->asset, this); - break; - } -// if early probe enabled - if( preferences->ffmpeg_early_probe && - FileFFMPEG::check_sig(this->asset)) { - file = new FileFFMPEG(this->asset, this); - break; - } - - FILE *stream; - if(!(stream = fopen(this->asset->path, "rb"))) { -// file not found - return 1; - } - - char test[16]; memset(test,0,sizeof(test)); // int result = - fread(test, 16, 1, stream); - - if(FileScene::check_sig(this->asset, test)) { -// scene file - fclose(stream); - file = new FileScene(this->asset, this); - break; - } - if(FileDV::check_sig(this->asset)) { -// libdv - fclose(stream); - file = new FileDV(this->asset, this); - break; - } - if(FileSndFile::check_sig(this->asset)) { -// libsndfile - fclose(stream); - file = new FileSndFile(this->asset, this); - break; - } - if(FilePNG::check_sig(this->asset)) { -// PNG file - fclose(stream); - file = new FilePNG(this->asset, this); - break; - } - if(FileJPEG::check_sig(this->asset)) { -// JPEG file - fclose(stream); - file = new FileJPEG(this->asset, this); - break; - } - if(FileGIF::check_sig(this->asset)) { -// GIF file - fclose(stream); - file = new FileGIF(this->asset, this); - break; - } - if(FileEXR::check_sig(this->asset, test)) { -// EXR file - fclose(stream); - file = new FileEXR(this->asset, this); - break; - } - if(FileFLAC::check_sig(this->asset, test)) { -// FLAC file - fclose(stream); - file = new FileFLAC(this->asset, this); - break; - } - if(FileCR2::check_sig(this->asset)) { -// CR2 file - fclose(stream); - file = new FileCR2(this->asset, this); - break; - } - if(FileTGA::check_sig(this->asset)) { -// TGA file - fclose(stream); - file = new FileTGA(this->asset, this); - break; - } - if(FileTIFF::check_sig(this->asset)) { -// TIFF file - fclose(stream); - file = new FileTIFF(this->asset, this); - break; - } - if(FileOGG::check_sig(this->asset)) { -// OGG file - fclose(stream); - file = new FileOGG(this->asset, this); - break; - } - if(FileVorbis::check_sig(this->asset)) { -// VorbisFile file - fclose(stream); - file = new FileVorbis(this->asset, this); - break; - } - if(FileMPEG::check_sig(this->asset)) { -// MPEG file - fclose(stream); - file = new FileMPEG(this->asset, this); - break; - } - if( test[0] == '<' && ( - !strncmp(&test[1],"EDL>",4) || - !strncmp(&test[1],"HTAL>",5) || - !strncmp(&test[1],"?xml",4) ) ) { -// XML file - fclose(stream); - return FILE_IS_XML; - } // can't load project file - if( !preferences->ffmpeg_early_probe && - FileFFMPEG::check_sig(this->asset) ) { - fclose(stream); - file = new FileFFMPEG(this->asset, this); - break; - } -// PCM file - fclose(stream); - return FILE_UNRECOGNIZED_CODEC; - break; - + case FILE_UNKNOWN: { + int ret = probe(); + if( ret != FILE_OK ) return ret; + break; } // format already determined case FILE_AC3: file = new FileAC3(this->asset, this); @@ -591,11 +597,11 @@ int File::open_file(Preferences *preferences, case FILE_VORBIS: file = new FileVorbis(this->asset, this); break; - +#ifdef HAVE_DV case FILE_RAWDV: file = new FileDV(this->asset, this); break; - +#endif // try plugins default: return 1; @@ -617,10 +623,13 @@ int File::open_file(Preferences *preferences, } if( rd ) { -// one frame image file, no specific length - if( !this->asset->audio_data && this->asset->video_data && - this->asset->video_length <= 1 ) +// one frame image file, not brender, no specific length + if( !this->asset->audio_data && this->asset->use_header && + this->asset->video_data && !this->asset->single_frame && + this->asset->video_length >= 0 && this->asset->video_length <= 1 ) { + this->asset->single_frame = 1; this->asset->video_length = -1; + } } // Synchronize header parameters @@ -710,12 +719,9 @@ int File::close_file(int ignore_thread) -int File::get_index(char *index_path) +int File::get_index(IndexFile *index_file, MainProgressBar *progress_bar) { - if(file) { - return file->get_index(index_path); - } - return 1; + return !file ? -1 : file->get_index(index_file, progress_bar); } @@ -1122,7 +1128,7 @@ VFrame*** File::get_video_buffer() int File::read_samples(Samples *samples, int64_t len) { // Never try to read more samples than exist in the file - if (current_sample + len > asset->audio_length) { + if (asset->audio_length >= 0 && current_sample + len > asset->audio_length) { len = asset->audio_length - current_sample; } if(len <= 0) return 0; @@ -1169,10 +1175,11 @@ int File::read_frame(VFrame *frame, int is_thread) if(debug) PRINT_TRACE if( !file ) return 1; if(debug) PRINT_TRACE + int result = 0; int supported_colormodel = colormodel_supported(frame->get_color_model()); int advance_position = 1; - int cache_active = use_cache || asset->video_length < 0 ? 1 : 0; - int64_t cache_position = asset->video_length >= 0 ? current_frame : -1; + int cache_active = use_cache || asset->single_frame ? 1 : 0; + int64_t cache_position = !asset->single_frame ? current_frame : -1; // Test cache if( cache_active && frame_cache->get_frame(frame, cache_position, current_layer, asset->frame_rate) ) @@ -1212,37 +1219,26 @@ int File::read_frame(VFrame *frame, int is_thread) // printf("File::read_frame %d\n", __LINE__); temp_frame->copy_stacks(frame); - int result = file->read_frame(temp_frame); - if( result && frame->get_status() > 0 ) + result = file->read_frame(temp_frame); + if( !result ) + frame->transfer_from(temp_frame); + else if( result && frame->get_status() > 0 ) frame->set_status(-1); -//for(int i = 0; i < 1000 * 1000; i++) ((float*)temp_frame->get_rows()[0])[i] = 1.0; -// printf("File::read_frame %d %d %d %d %d %d\n", -// temp_frame->get_color_model(), -// temp_frame->get_w(), -// temp_frame->get_h(), -// frame->get_color_model(), -// frame->get_w(), -// frame->get_h()); - BC_CModels::transfer(frame->get_rows(), temp_frame->get_rows(), - frame->get_y(), frame->get_u(), frame->get_v(), - temp_frame->get_y(), temp_frame->get_u(), temp_frame->get_v(), - 0, 0, temp_frame->get_w(), temp_frame->get_h(), - 0, 0, frame->get_w(), frame->get_h(), - temp_frame->get_color_model(), - frame->get_color_model(), 0, temp_frame->get_w(), - frame->get_w()); -// printf("File::read_frame %d\n", __LINE__); +//printf("File::read_frame %d\n", __LINE__); } else { // Can't advance position here because it needs to be added to cache //printf("File::read_frame %d\n", __LINE__); - int result = file->read_frame(frame); + result = file->read_frame(frame); if( result && frame->get_status() > 0 ) frame->set_status(-1); //for(int i = 0; i < 100 * 1000; i++) ((float*)frame->get_rows()[0])[i] = 1.0; } + if( result && !current_frame ) + frame->clear_frame(); + if( cache_active && advance_position && frame->get_status() > 0 ) frame_cache->put_frame(frame, cache_position, current_layer, asset->frame_rate, 1, 0); @@ -1422,7 +1418,9 @@ int File::get_best_colormodel(Asset *asset, int driver) { switch(asset->format) { +#ifdef HAVE_FIREWIRE case FILE_RAWDV: return FileDV::get_best_colormodel(asset, driver); +#endif case FILE_MPEG: return FileMPEG::get_best_colormodel(asset, driver); case FILE_JPEG: case FILE_JPEG_LIST: return FileJPEG::get_best_colormodel(asset, driver); @@ -1435,6 +1433,7 @@ int File::get_best_colormodel(Asset *asset, int driver) case FILE_CR2: case FILE_CR2_LIST: return FileCR2::get_best_colormodel(asset, driver); case FILE_DB: return FileDB::get_best_colormodel(asset, driver); + case FILE_FFMPEG: return FileFFMPEG::get_best_colormodel(asset, driver); } return BC_RGB888; @@ -1527,6 +1526,7 @@ int File::supports_audio(int format) case FILE_AIFF: case FILE_SND: case FILE_FFMPEG: + case FILE_RAWDV: return 1; } return 0; @@ -1624,16 +1624,96 @@ int File::record_fd() } -void get_exe_path(char *result) +void File::get_exe_path(char *result, char *bnp) { -// Get executable path +// Get executable path, basename int len = readlink("/proc/self/exe", result, BCTEXTLEN-1); if( len >= 0 ) { result[len] = 0; char *ptr = strrchr(result, '/'); - if( ptr ) *ptr = 0; + if( ptr ) *ptr++ = 0; else ptr = result; + if( bnp ) strncpy(bnp, ptr, BCTEXTLEN); + } + else { + *result = 0; + if( bnp ) *bnp = 0; } - else - result[0] = 0; } +void File::getenv_path(char *result, const char *path) +{ + char *rp = result, *ep = rp + BCTEXTLEN-1; + const char *cp = path; +// any env var can be used here to expand a path as: +// "path...$id...": and id is a word as alpha,alnum... +// expands as "path...getenv(id)..." +// CIN_PATH, CIN_LIB are set in main.C, + for( int ch=*cp++; ch && rp < ep; ch=*cp++ ) { + if( ch == '$' && isalpha(*cp) ) { // scan alpha,alnum... + const char *bp = cp; char *p = rp; + while( p < ep && *bp && (isalnum(*bp) || *bp == '_') ) *p++ = *bp++; + *p = 0; + const char *envp = getenv(rp); // read env value + if( !envp ) continue; + while( *envp && rp < ep ) *rp++ = *envp++; + cp = bp; // subst id=value + continue; + } + *rp++ = ch; + } + *rp = 0; +} + +char File::cinexe_path[BCTEXTLEN]; +char File::cinpkg_path[BCTEXTLEN]; +char File::cindat_path[BCTEXTLEN]; +char File::cinlib_path[BCTEXTLEN]; +char File::cincfg_path[BCTEXTLEN]; +char File::cinplg_path[BCTEXTLEN]; +char File::cinlad_path[BCTEXTLEN]; +char File::cinlcl_path[BCTEXTLEN]; +char File::cinbwr_path[BCTEXTLEN]; + +void File::init_cin_path() +{ + char env_path[BCTEXTLEN], env_pkg[BCTEXTLEN]; +// these values are advertised for forks/shell scripts + get_exe_path(env_path, env_pkg); + snprintf(cinexe_path, sizeof(cinexe_path), "CIN_PATH=%s", env_path); + putenv(cinexe_path); + snprintf(cinpkg_path, sizeof(cinpkg_path), "CIN_PKG=%s", env_pkg); + putenv(cinpkg_path); + + getenv_path(env_path, CINDAT_DIR); + snprintf(cindat_path, sizeof(cindat_path), "CIN_DAT=%s", env_path); + putenv(cindat_path); + + getenv_path(env_path, CINLIB_DIR); + snprintf(cinlib_path, sizeof(cinlib_path), "CIN_LIB=%s", env_path); + putenv(cinlib_path); + + getenv_path(env_path, CONFIG_DIR); + snprintf(cincfg_path, sizeof(cincfg_path), "CIN_CONFIG=%s", env_path); + putenv(cincfg_path); + + getenv_path(env_path, PLUGIN_DIR); + snprintf(cinplg_path, sizeof(cinplg_path), "CIN_PLUGIN=%s", env_path); + putenv(cinplg_path); + + getenv_path(env_path, LADSPA_DIR); + snprintf(cinlad_path, sizeof(cinlad_path), "CIN_LADSPA=%s", env_path); + putenv(cinlad_path); + + getenv_path(env_path, LOCALE_DIR); + snprintf(cinlcl_path, sizeof(cinlcl_path), "CIN_LOCALE=%s", env_path); + putenv(cinlcl_path); + +#ifndef CIN_BROWSER +#define CIN_BROWSER "firefox" +#endif + getenv_path(env_path, CIN_BROWSER); + snprintf(cinbwr_path, sizeof(cinlcl_path), "CIN_BROWSER=%s", env_path); + putenv(cinbwr_path); +} + +