locale expanders txt, libpulse prereq, debian shlibs deps,
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / file.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include <stdio.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <stdarg.h>
27 #include <ctype.h>
28 #include <limits.h>
29 // work arounds (centos)
30 #include <lzma.h>
31 #ifndef INT64_MAX
32 #define INT64_MAX 9223372036854775807LL
33 #endif
34
35 #include "asset.h"
36 #include "bchash.h"
37 #include "bcsignals.h"
38 #include "byteorder.h"
39 #include "cache.inc"
40 #include "condition.h"
41 #include "errorbox.h"
42 #include "fileac3.h"
43 #include "filebase.h"
44 #include "filecr2.h"
45 #include "filedb.h"
46 #include "filedv.h"
47 #include "fileexr.h"
48 #include "fileffmpeg.h"
49 #include "fileflac.h"
50 #include "filegif.h"
51 #include "file.h"
52 #include "filejpeg.h"
53 #include "filempeg.h"
54 #undef HAVE_STDLIB_H // automake conflict
55 #include "fileogg.h"
56 #include "filepng.h"
57 #include "fileppm.h"
58 #include "fileref.h"
59 #include "filescene.h"
60 #include "filesndfile.h"
61 #include "filetga.h"
62 #include "filethread.h"
63 #include "filetiff.h"
64 #include "filevorbis.h"
65 #include "filexml.h"
66 #include "formatwindow.h"
67 #include "formattools.h"
68 #include "framecache.h"
69 #include "language.h"
70 #include "mainprogress.inc"
71 #include "mutex.h"
72 #include "mwindow.h"
73 #include "packagingengine.h"
74 #include "pluginserver.h"
75 #include "preferences.h"
76 #include "probeprefs.h"
77 #include "samples.h"
78 #include "vframe.h"
79
80 #ifdef HAVE_OGG
81 //suppress noref warning
82 void *vorbis0_ov_callbacks[] = {
83  &OV_CALLBACKS_DEFAULT, &OV_CALLBACKS_NOCLOSE,
84  &OV_CALLBACKS_STREAMONLY, &OV_CALLBACKS_STREAMONLY_NOCLOSE,
85 };
86 #endif
87
88 File::File()
89 {
90         cpus = 1;
91         asset = new Asset;
92         format_completion = new Condition(1, "File::format_completion");
93         write_lock = new Condition(1, "File::write_lock");
94         frame_cache = new FrameCache;
95         reset_parameters();
96 }
97
98 File::~File()
99 {
100         if( getting_options ) {
101                 if( format_window ) format_window->set_done(0);
102                 format_completion->lock("File::~File");
103                 format_completion->unlock();
104         }
105
106         if( temp_frame ) {
107                 delete temp_frame;
108         }
109
110         close_file(0);
111
112         asset->Garbage::remove_user();
113         delete format_completion;
114         delete write_lock;
115         delete frame_cache;
116 }
117
118 void File::reset_parameters()
119 {
120         file = 0;
121         audio_thread = 0;
122         video_thread = 0;
123         getting_options = 0;
124         format_window = 0;
125         temp_frame = 0;
126         current_sample = 0;
127         current_frame = 0;
128         current_channel = 0;
129         current_program = 0;
130         current_layer = 0;
131         normalized_sample = 0;
132         use_cache = 0;
133         preferences = 0;
134         playback_subtitle = -1;
135         interpolate_raw = 1;
136
137
138         temp_samples_buffer = 0;
139         temp_frame_buffer = 0;
140         current_frame_buffer = 0;
141         audio_ring_buffers = 0;
142         video_ring_buffers = 0;
143         video_buffer_size = 0;
144 }
145
146 int File::raise_window()
147 {
148         if( getting_options && format_window ) {
149                 format_window->raise_window();
150                 format_window->flush();
151         }
152         return 0;
153 }
154
155 void File::close_window()
156 {
157         if( getting_options ) {
158                 format_window->lock_window("File::close_window");
159                 format_window->set_done(1);
160                 format_window->unlock_window();
161                 getting_options = 0;
162         }
163 }
164
165 int File::get_options(FormatTools *format,
166         int audio_options, int video_options)
167 {
168         BC_WindowBase *parent_window = format->window;
169         Asset *asset = format->asset;
170         EDL *edl = format->mwindow ? format->mwindow->edl : 0;
171         format_window = 0;
172         getting_options = 1;
173         format_completion->lock("File::get_options");
174         switch( asset->format ) {
175 #ifdef HAVE_CIN_3RDPARTY
176         case FILE_AC3: FileAC3::get_parameters(parent_window, asset, format_window,
177                         audio_options, video_options, edl);
178                 break;
179 #endif
180 #ifdef HAVE_DV
181         case FILE_RAWDV:
182                 FileDV::get_parameters(parent_window, asset, format_window,
183                         audio_options, video_options, edl);
184                 break;
185 #endif
186         case FILE_PCM:
187         case FILE_WAV:
188         case FILE_AU:
189         case FILE_AIFF:
190         case FILE_SND:
191                 FileSndFile::get_parameters(parent_window, asset, format_window,
192                         audio_options, video_options, edl);
193                 break;
194         case FILE_FFMPEG:
195                 FileFFMPEG::get_parameters(parent_window, asset, format_window,
196                         audio_options, video_options, edl);
197                 break;
198 #ifdef HAVE_LIBZMPEG
199         case FILE_AMPEG:
200         case FILE_VMPEG:
201                 FileMPEG::get_parameters(parent_window, asset, format_window,
202                         audio_options, video_options, edl);
203                 break;
204 #endif
205         case FILE_JPEG:
206         case FILE_JPEG_LIST:
207                 FileJPEG::get_parameters(parent_window, asset, format_window,
208                         audio_options, video_options, edl);
209                 break;
210 #ifdef HAVE_OPENEXR
211         case FILE_EXR:
212         case FILE_EXR_LIST:
213                 FileEXR::get_parameters(parent_window, asset, format_window,
214                         audio_options, video_options, edl);
215                 break;
216 #endif
217         case FILE_FLAC:
218                 FileFLAC::get_parameters(parent_window, asset, format_window,
219                         audio_options, video_options, edl);
220                 break;
221         case FILE_PNG:
222         case FILE_PNG_LIST:
223                 FilePNG::get_parameters(parent_window, asset, format_window,
224                         audio_options, video_options, edl);
225                 break;
226         case FILE_PPM:
227         case FILE_PPM_LIST:
228                 FilePPM::get_parameters(parent_window, asset, format_window,
229                         audio_options, video_options, edl);
230                 break;
231         case FILE_TGA:
232         case FILE_TGA_LIST:
233                 FileTGA::get_parameters(parent_window, asset, format_window,
234                         audio_options, video_options, edl);
235                 break;
236         case FILE_TIFF:
237         case FILE_TIFF_LIST:
238                 FileTIFF::get_parameters(parent_window, asset, format_window,
239                         audio_options, video_options, edl);
240                 break;
241 #ifdef HAVE_OGG
242         case FILE_OGG:
243                 FileOGG::get_parameters(parent_window, asset, format_window,
244                         audio_options, video_options, edl);
245                 break;
246 #endif
247         default:
248                 break;
249         }
250
251         if( !format_window ) {
252                 ErrorBox *errorbox = new ErrorBox(_(PROGRAM_NAME ": Error"),
253                         parent_window->get_abs_cursor_x(1),
254                         parent_window->get_abs_cursor_y(1));
255                 format_window = errorbox;
256                 getting_options = 1;
257                 if( audio_options )
258                         errorbox->create_objects(_("This format doesn't support audio."));
259                 else
260                 if( video_options )
261                         errorbox->create_objects(_("This format doesn't support video."));
262                 errorbox->run_window();
263                 delete errorbox;
264         }
265
266         getting_options = 0;
267         format_window = 0;
268         format_completion->unlock();
269         return 0;
270 }
271
272 int File::can_scale_input(Asset *asset)
273 {
274         switch( asset->format ) {
275         case FILE_MPEG:
276         case FILE_FFMPEG:
277                 return 1;
278         case FILE_EXR:
279         case FILE_JPEG:
280         case FILE_PNG:
281         case FILE_PPM:
282         case FILE_TGA:
283         case FILE_TIFF:
284                 if( asset->video_length < 0 )
285                         return 1;
286         }
287         return 0;
288 }
289
290
291 int File::set_processors(int cpus)   // Set the number of cpus for certain codecs
292 {
293         if( cpus > 8 )          // mpegvideo max_threads = 16, more causes errs
294                 cpus = 8;       //  8 cpus ought to decode just about anything
295 // Set all instances so gets work.
296         this->cpus = cpus;
297
298         return 0;
299 }
300
301 int File::set_preload(int64_t size)
302 {
303         this->playback_preload = size;
304         return 0;
305 }
306
307 void File::set_subtitle(int value)
308 {
309         this->playback_subtitle = value;
310         if( file ) file->set_subtitle(value);
311 }
312
313 void File::set_interpolate_raw(int value)
314 {
315         this->interpolate_raw = value;
316 }
317
318 void File::set_white_balance_raw(int value)
319 {
320         this->white_balance_raw = value;
321 }
322
323 void File::set_cache_frames(int value)
324 {
325 // caching only done locally
326         if( !video_thread )
327                 use_cache = value;
328 }
329
330 int File::purge_cache()
331 {
332 // caching only done locally
333         int result = 0;
334         if( frame_cache->cache_items() > 0 ) {
335                 frame_cache->remove_all();
336                 result = 1;
337         }
338         return result;
339 }
340
341 int File::delete_oldest()
342 {
343 // return the number of bytes freed
344         return frame_cache->delete_oldest();
345 }
346
347 // file driver in order of probe precidence
348 //  can be reordered in preferences->interface
349 const char *File::default_probes[] = { 
350         "FFMPEG_Early",
351         "Scene", 
352         "DB",
353 #ifdef HAVE_DV 
354         "DV",   
355 #endif 
356         "SndFile",
357         "PNG",
358         "PPM",
359         "JPEG",
360         "GIF",
361 #ifdef HAVE_OPENEXR
362         "EXR",
363 #endif
364         "FLAC",
365         "CR2",
366         "TGA",
367         "TIFF",
368 #ifdef HAVE_OGG
369         "OGG",
370         "Vorbis",
371 #endif
372         "MPEG",
373         "EDL",
374         "FFMPEG_Late", 
375 }; 
376 const int File::nb_probes =
377         sizeof(File::default_probes)/sizeof(File::default_probes[0]); 
378
379
380 int File::probe()
381 {
382         FILE *fp = fopen(this->asset->path, "rb");
383         if( !fp ) return FILE_NOT_FOUND;
384         char data[16];
385         memset(data,0,sizeof(data));
386         int ret = fread(data, 1, 16, fp);
387         fclose(fp);
388         if( !ret ) return FILE_NOT_FOUND;
389
390         for( int i=0; i<preferences->file_probes.size(); ++i ) {
391                 ProbePref *pref = preferences->file_probes[i];
392                 if( !pref->armed ) continue;
393                 if( !strncmp(pref->name,"FFMPEG",6) ) { // FFMPEG Early/Late
394                         if( !FileFFMPEG::check_sig(this->asset) ) continue;
395                         file = new FileFFMPEG(this->asset, this);
396                         return FILE_OK;
397                 }
398 #ifdef HAVE_COMMERCIAL
399                 if( !strcmp(pref->name,"DB") ) { // MediaDB
400                         if( !FileDB::check_sig(this->asset) ) continue;
401                         file = new FileDB(this->asset, this);
402                         return FILE_OK;
403                 }
404 #endif
405                 if( !strcmp(pref->name,"Scene") ) { // scene file
406                         if( !FileScene::check_sig(this->asset, data)) continue;
407                         file = new FileScene(this->asset, this);
408                         return FILE_OK;
409                 }
410 #ifdef HAVE_DV
411                 if( !strcmp(pref->name,"DV") ) { // libdv
412                         if( !FileDV::check_sig(this->asset) ) continue;
413                         file = new FileDV(this->asset, this);
414                         return FILE_OK;
415                 }
416 #endif
417                 if( !strcmp(pref->name,"SndFile") ) { // libsndfile
418                         if( !FileSndFile::check_sig(this->asset) ) continue;
419                         file = new FileSndFile(this->asset, this);
420                         return FILE_OK;
421                 }
422                 if( !strcmp(pref->name,"PNG") ) { // PNG file
423                         if( !FilePNG::check_sig(this->asset) ) continue;
424                         file = new FilePNG(this->asset, this);
425                         return FILE_OK;
426                 }
427                 if( !strcmp(pref->name,"PPM") ) { // PPM file
428                         if( !FilePPM::check_sig(this->asset) ) continue;
429                         file = new FilePPM(this->asset, this);
430                         return FILE_OK;
431                 }
432                 if( !strcmp(pref->name,"JPEG") ) { // JPEG file
433                         if( !FileJPEG::check_sig(this->asset) ) continue;
434                         file = new FileJPEG(this->asset, this);
435                         return FILE_OK;
436                 }
437                 if( !strcmp(pref->name,"GIF") ) { // GIF file
438                         if( FileGIFList::check_sig(this->asset) )
439                                 file = new FileGIFList(this->asset, this);
440                         else if( FileGIF::check_sig(this->asset) )
441                                 file = new FileGIF(this->asset, this);
442                         else continue;
443                         return FILE_OK;
444                 }
445 #ifdef HAVE_OPENEXR
446                 if( !strcmp(pref->name,"EXR") ) { // EXR file
447                         if( !FileEXR::check_sig(this->asset, data)) continue;
448                         file = new FileEXR(this->asset, this);
449                         return FILE_OK;
450                 }
451 #endif
452                 if( !strcmp(pref->name,"FLAC") ) { // FLAC file
453                         if( !FileFLAC::check_sig(this->asset, data)) continue;
454                         file = new FileFLAC(this->asset, this);
455                         return FILE_OK;
456                 }
457                 if( !strcmp(pref->name,"CR2") ) { // CR2 file
458                         if( !FileCR2::check_sig(this->asset)) continue;
459                         file = new FileCR2(this->asset, this);
460                         return FILE_OK;
461                 }
462                 if( !strcmp(pref->name,"TGA") ) { // TGA file
463                         if( !FileTGA::check_sig(this->asset) ) continue;
464                         file = new FileTGA(this->asset, this);
465                         return FILE_OK;
466                 }
467                 if( !strcmp(pref->name,"TIFF") ) { // TIFF file
468                         if( !FileTIFF::check_sig(this->asset) ) continue;
469                         file = new FileTIFF(this->asset, this);
470                         return FILE_OK;
471                 }
472 #ifdef HAVE_OGG
473                 if( !strcmp(pref->name,"OGG") ) { // OGG file
474                         if( !FileOGG::check_sig(this->asset) ) continue;
475                         file = new FileOGG(this->asset, this);
476                         return FILE_OK;
477                 }
478                 if( !strcmp(pref->name,"Vorbis") ) { // VorbisFile file
479                         if( !FileVorbis::check_sig(this->asset) ) continue;
480                         file = new FileVorbis(this->asset, this);
481                         return FILE_OK;
482                 }
483 #endif
484 #ifdef HAVE_LIBZMPEG
485                 if( !strcmp(pref->name,"MPEG") ) { // MPEG file
486                         if( !FileMPEG::check_sig(this->asset) ) continue;
487                         file = new FileMPEG(this->asset, this);
488                         return FILE_OK;
489                 }
490 #endif
491                 if( !strcmp(pref->name,"EDL") ) { // XML file
492                         if( data[0] != '<' ) continue;
493                         if( !strncmp(&data[1],"EDL>",4) ||
494                             !strncmp(&data[1],"HTAL>",5) ||
495                             !strncmp(&data[1],"?xml",4) )
496                                 return FILE_IS_XML;
497                 }
498         }
499         return FILE_UNRECOGNIZED_CODEC; // maybe PCM file ?
500 }
501
502 int File::open_file(Preferences *preferences,
503         Asset *asset,
504         int rd,
505         int wr)
506 {
507         const int debug = 0;
508
509         this->preferences = preferences;
510         this->asset->copy_from(asset, 1);
511         this->rd = rd;
512         this->wr = wr;
513         file = 0;
514
515         if( debug ) printf("File::open_file %p %d\n", this, __LINE__);
516
517         switch( this->asset->format ) {
518 // get the format now
519 // If you add another format to case 0, you also need to add another case for the
520 // file format #define.
521         case FILE_UNKNOWN: {
522                 int ret = probe();
523                 if( ret != FILE_OK ) return ret;
524                 break; }
525 // format already determined
526 #ifdef HAVE_CIN_3RDPARTY
527         case FILE_AC3:
528                 file = new FileAC3(this->asset, this);
529                 break;
530 #endif
531         case FILE_SCENE:
532                 file = new FileScene(this->asset, this);
533                 break;
534
535         case FILE_FFMPEG:
536                 file = new FileFFMPEG(this->asset, this);
537                 break;
538
539         case FILE_PCM:
540         case FILE_WAV:
541         case FILE_AU:
542         case FILE_AIFF:
543         case FILE_SND:
544 //printf("File::open_file 1\n");
545                 file = new FileSndFile(this->asset, this);
546                 break;
547
548         case FILE_PNG:
549         case FILE_PNG_LIST:
550                 file = new FilePNG(this->asset, this);
551                 break;
552
553         case FILE_PPM:
554         case FILE_PPM_LIST:
555                 file = new FilePPM(this->asset, this);
556                 break;
557
558         case FILE_JPEG:
559         case FILE_JPEG_LIST:
560                 file = new FileJPEG(this->asset, this);
561                 break;
562
563         case FILE_GIF:
564                 file = new FileGIF(this->asset, this);
565                 break;
566         case FILE_GIF_LIST:
567                 file = new FileGIFList(this->asset, this);
568                 break;
569
570 #ifdef HAVE_OPENEXR
571         case FILE_EXR:
572         case FILE_EXR_LIST:
573                 file = new FileEXR(this->asset, this);
574                 break;
575 #endif
576         case FILE_FLAC:
577                 file = new FileFLAC(this->asset, this);
578                 break;
579
580         case FILE_CR2:
581         case FILE_CR2_LIST:
582                 file = new FileCR2(this->asset, this);
583                 break;
584
585         case FILE_TGA_LIST:
586         case FILE_TGA:
587                 file = new FileTGA(this->asset, this);
588                 break;
589
590         case FILE_TIFF:
591         case FILE_TIFF_LIST:
592                 file = new FileTIFF(this->asset, this);
593                 break;
594 #ifdef HAVE_COMMERCIAL
595         case FILE_DB:
596                 file = new FileDB(this->asset, this);
597                 break;
598 #endif
599
600 #ifdef HAVE_LIBZMPEG
601         case FILE_MPEG:
602         case FILE_AMPEG:
603         case FILE_VMPEG:
604                 file = new FileMPEG(this->asset, this);
605                 break;
606 #endif
607 #ifdef HAVE_OGG
608         case FILE_OGG:
609                 file = new FileOGG(this->asset, this);
610                 break;
611
612         case FILE_VORBIS:
613                 file = new FileVorbis(this->asset, this);
614                 break;
615 #endif
616 #ifdef HAVE_DV
617         case FILE_RAWDV:
618                 file = new FileDV(this->asset, this);
619                 break;
620 #endif
621         case FILE_REF:
622                 file = new FileREF(this->asset, this);
623                 break;
624 // try plugins
625         default:
626                 return 1;
627                 break;
628         }
629
630
631 // Reopen file with correct parser and get header.
632         if( file->open_file(rd, wr) ) {
633                 delete file;  file = 0;
634                 return FILE_NOT_FOUND;
635         }
636
637
638
639 // Set extra writing parameters to mandatory settings.
640         if( wr ) {
641                 if( this->asset->dither ) file->set_dither();
642         }
643
644         if( rd ) {
645 // one frame image file, not brender, no specific length
646                 if( !this->asset->audio_data && this->asset->use_header &&
647                     this->asset->video_data && !this->asset->single_frame &&
648                     this->asset->video_length >= 0 && this->asset->video_length <= 1 ) {
649                         this->asset->single_frame = 1;
650                         this->asset->video_length = -1;
651                 }
652         }
653
654 // Synchronize header parameters
655         asset->copy_from(this->asset, 1);
656 //asset->dump();
657
658         if( debug ) printf("File::open_file %d file=%p\n", __LINE__, file);
659 // sleep(1);
660
661         return FILE_OK;
662 }
663
664 void File::delete_temp_samples_buffer()
665 {
666
667         if( temp_samples_buffer ) {
668                 for( int j = 0; j < audio_ring_buffers; j++ ) {
669                         for( int i = 0; i < asset->channels; i++ ) {
670                                 delete temp_samples_buffer[j][i];
671                         }
672                         delete [] temp_samples_buffer[j];
673                 }
674
675                 delete [] temp_samples_buffer;
676                 temp_samples_buffer = 0;
677                 audio_ring_buffers = 0;
678         }
679 }
680
681 void File::delete_temp_frame_buffer()
682 {
683
684         if( temp_frame_buffer ) {
685                 for( int k = 0; k < video_ring_buffers; k++ ) {
686                         for( int i = 0; i < asset->layers; i++ ) {
687                                 for( int j = 0; j < video_buffer_size; j++ ) {
688                                         delete temp_frame_buffer[k][i][j];
689                                 }
690                                 delete [] temp_frame_buffer[k][i];
691                         }
692                         delete [] temp_frame_buffer[k];
693                 }
694
695                 delete [] temp_frame_buffer;
696                 temp_frame_buffer = 0;
697                 video_ring_buffers = 0;
698                 video_buffer_size = 0;
699         }
700 }
701
702 int File::close_file(int ignore_thread)
703 {
704         if( !ignore_thread ) {
705                 stop_audio_thread();
706                 stop_video_thread();
707         }
708         if( file ) {
709 // The file's asset is a copy of the argument passed to open_file so the
710 // user must copy lengths from the file's asset.
711                 if( asset && wr ) {
712                         asset->audio_length = current_sample;
713                         asset->video_length = current_frame;
714                 }
715
716                 file->close_file();
717                 delete file;
718         }
719
720         delete_temp_samples_buffer();
721         delete_temp_frame_buffer();
722         reset_parameters();
723         return 0;
724 }
725
726 int File::get_index(IndexFile *index_file, MainProgressBar *progress_bar)
727 {
728         return !file ? -1 : file->get_index(index_file, progress_bar);
729 }
730
731 int File::start_audio_thread(int buffer_size, int ring_buffers)
732 {
733         this->audio_ring_buffers = ring_buffers;
734
735
736         if( !audio_thread ) {
737                 audio_thread = new FileThread(this, 1, 0);
738                 audio_thread->start_writing(buffer_size, 0, ring_buffers, 0);
739         }
740         return 0;
741 }
742
743 int File::start_video_thread(int buffer_size, int color_model,
744                 int ring_buffers, int compressed)
745 {
746         this->video_ring_buffers = ring_buffers;
747         this->video_buffer_size = buffer_size;
748
749         if( !video_thread ) {
750                 video_thread = new FileThread(this, 0, 1);
751                 video_thread->start_writing(buffer_size, color_model,
752                                 ring_buffers, compressed);
753         }
754         return 0;
755 }
756
757 int File::start_video_decode_thread()
758 {
759 // Currently, CR2 is the only one which won't work asynchronously, so
760 // we're not using a virtual function yet.
761         if( !video_thread /* && asset->format != FILE_CR2 */ ) {
762                 video_thread = new FileThread(this, 0, 1);
763                 video_thread->start_reading();
764                 use_cache = 0;
765         }
766         return 0;
767 }
768
769 int File::stop_audio_thread()
770 {
771         if( audio_thread ) {
772                 audio_thread->stop_writing();
773                 delete audio_thread;
774                 audio_thread = 0;
775         }
776         return 0;
777 }
778
779 int File::stop_video_thread()
780 {
781         if( video_thread ) {
782                 video_thread->stop_reading();
783                 video_thread->stop_writing();
784                 delete video_thread;
785                 video_thread = 0;
786         }
787         return 0;
788 }
789
790 FileThread* File::get_video_thread()
791 {
792         return video_thread;
793 }
794
795 int File::set_channel(int channel)
796 {
797         if( file && channel < asset->channels ) {
798                 current_channel = channel;
799                 return 0;
800         }
801         else
802                 return 1;
803 }
804
805 int File::get_channel()
806 {
807         return current_channel;
808 }
809
810 // if no>=0, sets new program
811 //  returns current program
812 int File::set_program(int no)
813 {
814         int result = file ? file->set_program(no) : current_program;
815         current_program = no < 0 ? result : no;
816         return result;
817 }
818
819 int File::get_cell_time(int no, double &time)
820 {
821         return file ? file->get_cell_time(no, time) : -1;
822 }
823
824 int File::get_system_time(int64_t &tm)
825 {
826         return file ? file->get_system_time(tm) : -1;
827 }
828
829 int File::get_audio_for_video(int vstream, int astream, int64_t &channel_mask)
830 {
831         return file ? file->get_audio_for_video(vstream, astream, channel_mask) : -1;
832 }
833
834 int File::get_video_pid(int track)
835 {
836         return file ? file->get_video_pid(track) : -1;
837 }
838
839
840
841 int File::get_video_info(int track, int &pid, double &framerate,
842                 int &width, int &height, char *title)
843 {
844         return !file ? -1 :
845                  file->get_video_info(track, pid, framerate, width, height, title);
846 }
847
848 int File::select_video_stream(Asset *asset, int vstream)
849 {
850         return !file ? -1 :
851                  file->select_video_stream(asset, vstream);
852 }
853
854 int File::select_audio_stream(Asset *asset, int astream)
855 {
856         return !file ? -1 :
857                  file->select_audio_stream(asset, astream);
858 }
859
860
861 int File::get_thumbnail(int stream,
862         int64_t &position, unsigned char *&thumbnail, int &ww, int &hh)
863 {
864         return file->get_thumbnail(stream, position, thumbnail, ww, hh);
865 }
866
867 int File::set_skimming(int track, int skim, skim_fn fn, void *vp)
868 {
869         return file->set_skimming(track, skim, fn, vp);
870 }
871
872 int File::skim_video(int track, void *vp, skim_fn fn)
873 {
874         return file->skim_video(track, vp, fn);
875 }
876
877
878 int File::set_layer(int layer, int is_thread)
879 {
880         if( file && layer < asset->layers ) {
881                 if( !is_thread && video_thread ) {
882                         video_thread->set_layer(layer);
883                 }
884                 else {
885                         current_layer = layer;
886                 }
887                 return 0;
888         }
889         else
890                 return 1;
891 }
892
893 int64_t File::get_audio_length()
894 {
895         int64_t result = asset->audio_length;
896         int64_t base_samplerate = -1;
897         if( result > 0 ) {
898                 if( base_samplerate > 0 )
899                         return (int64_t)((double)result / asset->sample_rate * base_samplerate + 0.5);
900                 else
901                         return result;
902         }
903         else
904                 return -1;
905 }
906
907 int64_t File::get_video_length()
908 {
909         int64_t result = asset->video_length;
910         float base_framerate = -1;
911         if( result > 0 ) {
912                 if( base_framerate > 0 )
913                         return (int64_t)((double)result / asset->frame_rate * base_framerate + 0.5);
914                 else
915                         return result;
916         }
917         else
918                 return -1;  // infinity
919 }
920
921
922 int64_t File::get_video_position()
923 {
924         float base_framerate = -1;
925         if( base_framerate > 0 )
926                 return (int64_t)((double)current_frame / asset->frame_rate * base_framerate + 0.5);
927         else
928                 return current_frame;
929 }
930
931 int64_t File::get_audio_position()
932 {
933 //      int64_t base_samplerate = -1;
934 //      if( base_samplerate > 0 )
935 //      {
936 //              if( normalized_sample_rate == base_samplerate )
937 //                      return normalized_sample;
938 //              else
939 //                      return (int64_t)((double)current_sample /
940 //                              asset->sample_rate *
941 //                              base_samplerate +
942 //                              0.5);
943 //      }
944 //      else
945                 return current_sample;
946 }
947
948
949
950 int File::set_audio_position(int64_t position)
951 {
952         int result = 0;
953
954         if( !file ) return 1;
955
956 #define REPOSITION(x, y) \
957         (labs((x) - (y)) > 1)
958
959         float base_samplerate = asset->sample_rate;
960         current_sample = normalized_sample = position;
961
962 // printf("File::set_audio_position %d normalized_sample=%ld\n",
963 // __LINE__,
964 // normalized_sample);
965                 result = file->set_audio_position(current_sample);
966
967                 if( result )
968                         printf("File::set_audio_position position=%jd"
969                                 " base_samplerate=%f asset=%p asset->sample_rate=%d\n",
970                                 position, base_samplerate, asset, asset->sample_rate);
971
972 //printf("File::set_audio_position %d %d %d\n", current_channel, current_sample, position);
973
974         return result;
975 }
976
977 int File::set_video_position(int64_t position,
978         int is_thread)
979 {
980         int result = 0;
981         if( !file ) return 0;
982
983 // Convert to file's rate
984 //      if( base_framerate > 0 )
985 //              position = (int64_t)((double)position /
986 //                      base_framerate *
987 //                      asset->frame_rate +
988 //                      0.5);
989
990
991         if( video_thread && !is_thread ) {
992 // Call thread.  Thread calls this again to set the file state.
993                 video_thread->set_video_position(position);
994         }
995         else
996         if( current_frame != position ) {
997                 if( file ) {
998                         current_frame = position;
999                         result = file->set_video_position(current_frame);
1000                 }
1001         }
1002
1003         return result;
1004 }
1005
1006 // No resampling here.
1007 int File::write_samples(Samples **buffer, int64_t len)
1008 {
1009         int result = 1;
1010
1011         if( file ) {
1012                 write_lock->lock("File::write_samples");
1013
1014 // Convert to arrays for backwards compatability
1015                 double *temp[asset->channels];
1016                 for( int i = 0; i < asset->channels; i++ ) {
1017                         temp[i] = buffer[i]->get_data();
1018                 }
1019
1020                 result = file->write_samples(temp, len);
1021                 current_sample += len;
1022                 normalized_sample += len;
1023                 asset->audio_length += len;
1024                 write_lock->unlock();
1025         }
1026         return result;
1027 }
1028
1029
1030
1031
1032
1033 // Can't put any cmodel abstraction here because the filebase couldn't be
1034 // parallel.
1035 int File::write_frames(VFrame ***frames, int len)
1036 {
1037 //printf("File::write_frames %d\n", __LINE__);
1038 //PRINT_TRACE
1039 // Store the counters in temps so the filebase can choose to overwrite them.
1040         int result;
1041         int current_frame_temp = current_frame;
1042         int video_length_temp = asset->video_length;
1043
1044         write_lock->lock("File::write_frames");
1045
1046 //PRINT_TRACE
1047         result = file->write_frames(frames, len);
1048 //PRINT_TRACE
1049
1050         current_frame = current_frame_temp + len;
1051         asset->video_length = video_length_temp + len;
1052         write_lock->unlock();
1053 //PRINT_TRACE
1054         return result;
1055 }
1056
1057 // Only called by FileThread
1058 int File::write_compressed_frame(VFrame *buffer)
1059 {
1060         int result = 0;
1061         write_lock->lock("File::write_compressed_frame");
1062         result = file->write_compressed_frame(buffer);
1063         current_frame++;
1064         asset->video_length++;
1065         write_lock->unlock();
1066         return result;
1067 }
1068
1069
1070 int File::write_audio_buffer(int64_t len)
1071 {
1072         int result = 0;
1073         if( audio_thread ) {
1074                 result = audio_thread->write_buffer(len);
1075         }
1076         return result;
1077 }
1078
1079 int File::write_video_buffer(int64_t len)
1080 {
1081         int result = 0;
1082         if( video_thread ) {
1083                 result = video_thread->write_buffer(len);
1084         }
1085
1086         return result;
1087 }
1088
1089 Samples** File::get_audio_buffer()
1090 {
1091         if( audio_thread ) return audio_thread->get_audio_buffer();
1092         return 0;
1093 }
1094
1095 VFrame*** File::get_video_buffer()
1096 {
1097         if( video_thread ) {
1098                 VFrame*** result = video_thread->get_video_buffer();
1099
1100                 return result;
1101         }
1102
1103         return 0;
1104 }
1105
1106
1107 int File::read_samples(Samples *samples, int64_t len)
1108 {
1109 // Never try to read more samples than exist in the file
1110         if( asset->audio_length >= 0 && current_sample + len > asset->audio_length ) {
1111                 len = asset->audio_length - current_sample;
1112         }
1113         if( len <= 0 ) return 0;
1114
1115         int result = 0;
1116         const int debug = 0;
1117         if( debug ) PRINT_TRACE
1118
1119         if( debug ) PRINT_TRACE
1120
1121         double *buffer = samples->get_data();
1122
1123         int64_t base_samplerate = asset->sample_rate;
1124
1125         if( file ) {
1126 // Resample recursively calls this with the asset sample rate
1127                 if( base_samplerate == 0 ) base_samplerate = asset->sample_rate;
1128
1129                 if( debug ) PRINT_TRACE
1130                 result = file->read_samples(buffer, len);
1131
1132                 if( debug ) PRINT_TRACE
1133                 current_sample += len;
1134
1135                 normalized_sample += len;
1136         }
1137         if( debug ) PRINT_TRACE
1138
1139         return result;
1140 }
1141
1142 int File::read_frame(VFrame *frame, int is_thread)
1143 {
1144         const int debug = 0;
1145 //printf("File::read_frame pos=%jd cache=%d 1frame=%d\n",
1146 // current_frame, use_cache, asset->single_frame);
1147         if( video_thread && !is_thread ) return video_thread->read_frame(frame);
1148         if( !file ) return 1;
1149         if( debug ) PRINT_TRACE
1150         int result = 0;
1151         int supported_colormodel = colormodel_supported(frame->get_color_model());
1152         int advance_position = 1;
1153         int cache_active = use_cache || asset->single_frame ? 1 : 0;
1154         int64_t cache_position = !asset->single_frame ? current_frame : -1;
1155
1156 // Test cache
1157         if( cache_active && frame_cache->get_frame(frame, cache_position,
1158                         current_layer, asset->frame_rate) ) {
1159 // Can't advance position if cache used.
1160 //printf("File::read_frame %d\n", __LINE__);
1161                 advance_position = 0;
1162         }
1163 // Need temp
1164         else if( frame->get_color_model() != BC_COMPRESSED &&
1165                 (supported_colormodel != frame->get_color_model() ||
1166                 (!file->can_scale_input() &&
1167                         (frame->get_w() != asset->width ||
1168                          frame->get_h() != asset->height))) ) {
1169
1170 //                      printf("File::read_frame %d\n", __LINE__);
1171 // Can't advance position here because it needs to be added to cache
1172                 if( temp_frame ) {
1173                         if( !temp_frame->params_match(asset->width, asset->height, supported_colormodel) ) {
1174                                 delete temp_frame;
1175                                 temp_frame = 0;
1176                         }
1177                 }
1178
1179                 if( !temp_frame ) {
1180                         temp_frame = new VFrame(asset->width, asset->height, supported_colormodel, 0);
1181                         temp_frame->clear_frame();
1182                 }
1183
1184 //                      printf("File::read_frame %d\n", __LINE__);
1185                 temp_frame->copy_stacks(frame);
1186                 result = file->read_frame(temp_frame);
1187                 if( !result )
1188                         frame->transfer_from(temp_frame);
1189                 else if( result && frame->get_status() > 0 )
1190                         frame->set_status(-1);
1191 //printf("File::read_frame %d\n", __LINE__);
1192         }
1193         else {
1194 // Can't advance position here because it needs to be added to cache
1195 //printf("File::read_frame %d\n", __LINE__);
1196                 result = file->read_frame(frame);
1197                 if( result && frame->get_status() > 0 )
1198                         frame->set_status(-1);
1199 //for( int i = 0; i < 100 * 1000; i++ ) ((float*)frame->get_rows()[0])[i] = 1.0;
1200         }
1201
1202         if( result && !current_frame )
1203                 frame->clear_frame();
1204
1205         if( cache_active && advance_position && frame->get_status() > 0 )
1206                 frame_cache->put_frame(frame, cache_position,
1207                         current_layer, asset->frame_rate, 1, 0);
1208 //printf("File::read_frame %d\n", __LINE__);
1209
1210         if( advance_position ) current_frame++;
1211         if( debug ) PRINT_TRACE
1212         return 0;
1213 }
1214
1215 int File::can_copy_from(Asset *asset, int64_t position, int output_w, int output_h)
1216 {
1217         if( asset && file ) {
1218                 return asset->width == output_w &&
1219                         asset->height == output_h &&
1220                         file->can_copy_from(asset, position);
1221         }
1222         return 0;
1223 }
1224
1225 // Fill in queries about formats when adding formats here.
1226
1227
1228 int File::strtoformat(const char *format)
1229 {
1230         if( !strcasecmp(format, _(AC3_NAME)) ) return FILE_AC3;
1231         if( !strcasecmp(format, _(SCENE_NAME)) ) return FILE_SCENE;
1232         if( !strcasecmp(format, _(WAV_NAME)) ) return FILE_WAV;
1233         if( !strcasecmp(format, _(PCM_NAME)) ) return FILE_PCM;
1234         if( !strcasecmp(format, _(AU_NAME)) ) return FILE_AU;
1235         if( !strcasecmp(format, _(AIFF_NAME)) ) return FILE_AIFF;
1236         if( !strcasecmp(format, _(SND_NAME)) ) return FILE_SND;
1237         if( !strcasecmp(format, _(PNG_NAME)) ) return FILE_PNG;
1238         if( !strcasecmp(format, _(PNG_LIST_NAME)) ) return FILE_PNG_LIST;
1239         if( !strcasecmp(format, _(PPM_NAME)) ) return FILE_PPM;
1240         if( !strcasecmp(format, _(PPM_LIST_NAME)) ) return FILE_PPM_LIST;
1241         if( !strcasecmp(format, _(TIFF_NAME)) ) return FILE_TIFF;
1242         if( !strcasecmp(format, _(TIFF_LIST_NAME)) ) return FILE_TIFF_LIST;
1243         if( !strcasecmp(format, _(JPEG_NAME)) ) return FILE_JPEG;
1244         if( !strcasecmp(format, _(JPEG_LIST_NAME)) ) return FILE_JPEG_LIST;
1245         if( !strcasecmp(format, _(EXR_NAME)) ) return FILE_EXR;
1246         if( !strcasecmp(format, _(EXR_LIST_NAME)) ) return FILE_EXR_LIST;
1247         if( !strcasecmp(format, _(FLAC_NAME)) ) return FILE_FLAC;
1248         if( !strcasecmp(format, _(GIF_NAME)) ) return FILE_GIF;
1249         if( !strcasecmp(format, _(GIF_LIST_NAME)) ) return FILE_GIF_LIST;
1250         if( !strcasecmp(format, _(CR2_NAME)) ) return FILE_CR2;
1251         if( !strcasecmp(format, _(CR2_LIST_NAME)) ) return FILE_CR2_LIST;
1252         if( !strcasecmp(format, _(MPEG_NAME)) ) return FILE_MPEG;
1253         if( !strcasecmp(format, _(AMPEG_NAME)) ) return FILE_AMPEG;
1254         if( !strcasecmp(format, _(VMPEG_NAME)) ) return FILE_VMPEG;
1255         if( !strcasecmp(format, _(TGA_NAME)) ) return FILE_TGA;
1256         if( !strcasecmp(format, _(TGA_LIST_NAME)) ) return FILE_TGA_LIST;
1257         if( !strcasecmp(format, _(OGG_NAME)) ) return FILE_OGG;
1258         if( !strcasecmp(format, _(VORBIS_NAME)) ) return FILE_VORBIS;
1259         if( !strcasecmp(format, _(RAWDV_NAME)) ) return FILE_RAWDV;
1260         if( !strcasecmp(format, _(FFMPEG_NAME)) ) return FILE_FFMPEG;
1261         if( !strcasecmp(format, _(DBASE_NAME)) ) return FILE_DB;
1262         if( !strcasecmp(format, _(REF_NAME)) ) return FILE_REF;
1263
1264         return 0;
1265 }
1266
1267
1268 const char* File::formattostr(int format)
1269 {
1270         switch( format ) {
1271         case FILE_SCENE:        return _(SCENE_NAME);
1272         case FILE_AC3:          return _(AC3_NAME);
1273         case FILE_WAV:          return _(WAV_NAME);
1274         case FILE_PCM:          return _(PCM_NAME);
1275         case FILE_AU:           return _(AU_NAME);
1276         case FILE_AIFF:         return _(AIFF_NAME);
1277         case FILE_SND:          return _(SND_NAME);
1278         case FILE_PNG:          return _(PNG_NAME);
1279         case FILE_PNG_LIST:     return _(PNG_LIST_NAME);
1280         case FILE_PPM:          return _(PPM_NAME);
1281         case FILE_PPM_LIST:     return _(PPM_LIST_NAME);
1282         case FILE_JPEG:         return _(JPEG_NAME);
1283         case FILE_JPEG_LIST:    return _(JPEG_LIST_NAME);
1284         case FILE_CR2:          return _(CR2_NAME);
1285         case FILE_CR2_LIST:     return _(CR2_LIST_NAME);
1286         case FILE_FLAC:         return _(FLAC_NAME);
1287         case FILE_GIF:          return _(GIF_NAME);
1288         case FILE_GIF_LIST:     return _(GIF_LIST_NAME);
1289         case FILE_EXR:          return _(EXR_NAME);
1290         case FILE_EXR_LIST:     return _(EXR_LIST_NAME);
1291 #ifdef HAVE_LIBZMPEG
1292         case FILE_MPEG:         return _(MPEG_NAME);
1293 #endif
1294         case FILE_AMPEG:        return _(AMPEG_NAME);
1295         case FILE_VMPEG:        return _(VMPEG_NAME);
1296         case FILE_TGA:          return _(TGA_NAME);
1297         case FILE_TGA_LIST:     return _(TGA_LIST_NAME);
1298         case FILE_TIFF:         return _(TIFF_NAME);
1299         case FILE_TIFF_LIST:    return _(TIFF_LIST_NAME);
1300         case FILE_OGG:          return _(OGG_NAME);
1301         case FILE_VORBIS:       return _(VORBIS_NAME);
1302         case FILE_RAWDV:        return _(RAWDV_NAME);
1303         case FILE_FFMPEG:       return _(FFMPEG_NAME);
1304         case FILE_DB:           return _(DBASE_NAME);
1305         case FILE_REF:          return _(REF_NAME);
1306         }
1307         return _("Unknown");
1308 }
1309
1310 int File::strtobits(const char *bits)
1311 {
1312         if( !strcasecmp(bits, _(NAME_8BIT)) ) return BITSLINEAR8;
1313         if( !strcasecmp(bits, _(NAME_16BIT)) ) return BITSLINEAR16;
1314         if( !strcasecmp(bits, _(NAME_24BIT)) ) return BITSLINEAR24;
1315         if( !strcasecmp(bits, _(NAME_32BIT)) ) return BITSLINEAR32;
1316         if( !strcasecmp(bits, _(NAME_ULAW)) ) return BITSULAW;
1317         if( !strcasecmp(bits, _(NAME_ADPCM)) ) return BITS_ADPCM;
1318         if( !strcasecmp(bits, _(NAME_FLOAT)) ) return BITSFLOAT;
1319         return BITSLINEAR16;
1320 }
1321
1322 const char* File::bitstostr(int bits)
1323 {
1324 //printf("File::bitstostr\n");
1325         switch( bits ) {
1326         case BITSLINEAR8:       return (NAME_8BIT);
1327         case BITSLINEAR16:      return (NAME_16BIT);
1328         case BITSLINEAR24:      return (NAME_24BIT);
1329         case BITSLINEAR32:      return (NAME_32BIT);
1330         case BITSULAW:          return (NAME_ULAW);
1331         case BITS_ADPCM:        return (NAME_ADPCM);
1332         case BITSFLOAT:         return (NAME_FLOAT);
1333         }
1334         return _("Unknown");
1335 }
1336
1337
1338
1339 int File::str_to_byteorder(const char *string)
1340 {
1341         if( !strcasecmp(string, _("Lo Hi")) ) return 1;
1342         return 0;
1343 }
1344
1345 const char* File::byteorder_to_str(int byte_order)
1346 {
1347         if( byte_order ) return _("Lo Hi");
1348         return _("Hi Lo");
1349 }
1350
1351 int File::bytes_per_sample(int bits)
1352 {
1353         switch( bits ) {
1354         case BITSLINEAR8:       return 1;
1355         case BITSLINEAR16:      return 2;
1356         case BITSLINEAR24:      return 3;
1357         case BITSLINEAR32:      return 4;
1358         case BITSULAW:          return 1;
1359         }
1360         return 1;
1361 }
1362
1363
1364 int File::get_best_colormodel(int driver, int vstream)
1365 {
1366         return file ? file->get_best_colormodel(driver, vstream) :
1367                 get_best_colormodel(asset, driver);
1368 }
1369
1370 int File::get_best_colormodel(Asset *asset, int driver)
1371 {
1372         switch( asset->format ) {
1373 #ifdef HAVE_DV
1374         case FILE_RAWDV:        return FileDV::get_best_colormodel(asset, driver);
1375 #endif
1376 #ifdef HAVE_LIBZMPEG
1377         case FILE_MPEG:         return FileMPEG::get_best_colormodel(asset, driver);
1378 #endif
1379         case FILE_JPEG:
1380         case FILE_JPEG_LIST:    return FileJPEG::get_best_colormodel(asset, driver);
1381 #ifdef HAVE_OPENEXR
1382         case FILE_EXR:
1383         case FILE_EXR_LIST:     return FileEXR::get_best_colormodel(asset, driver);
1384 #endif
1385         case FILE_PNG:
1386         case FILE_PNG_LIST:     return FilePNG::get_best_colormodel(asset, driver);
1387         case FILE_PPM:
1388         case FILE_PPM_LIST:     return FilePPM::get_best_colormodel(asset, driver);
1389         case FILE_TGA:
1390         case FILE_TGA_LIST:     return FileTGA::get_best_colormodel(asset, driver);
1391         case FILE_CR2:
1392         case FILE_CR2_LIST:     return FileCR2::get_best_colormodel(asset, driver);
1393 #ifdef HAVE_COMMERCIAL
1394         case FILE_DB:           return FileDB::get_best_colormodel(asset, driver);
1395 #endif
1396         case FILE_FFMPEG:       return FileFFMPEG::get_best_colormodel(asset, driver);
1397         case FILE_REF:          return FileREF::get_best_colormodel(asset, driver);
1398         }
1399
1400         return BC_RGB888;
1401 }
1402
1403
1404 int File::colormodel_supported(int colormodel)
1405 {
1406         if( file )
1407                 return file->colormodel_supported(colormodel);
1408
1409         return BC_RGB888;
1410 }
1411
1412
1413 int64_t File::file_memory_usage()
1414 {
1415         return file ? file->base_memory_usage() : 0;
1416 }
1417
1418 int64_t File::get_memory_usage()
1419 {
1420         int64_t result = 0;
1421
1422         result += file_memory_usage();
1423         if( temp_frame ) result += temp_frame->get_data_size();
1424         result += frame_cache->get_memory_usage();
1425         if( video_thread ) result += video_thread->get_memory_usage();
1426
1427         if( result < MIN_CACHEITEM_SIZE ) result = MIN_CACHEITEM_SIZE;
1428         return result;
1429 }
1430
1431
1432 int File::renders_video(int format)
1433 {
1434         switch( format ) {
1435         case FILE_OGG:
1436         case FILE_JPEG:
1437         case FILE_JPEG_LIST:
1438         case FILE_CR2:
1439         case FILE_CR2_LIST:
1440         case FILE_EXR:
1441         case FILE_EXR_LIST:
1442         case FILE_GIF:
1443         case FILE_GIF_LIST:
1444         case FILE_PNG:
1445         case FILE_PNG_LIST:
1446         case FILE_PPM:
1447         case FILE_PPM_LIST:
1448         case FILE_TGA:
1449         case FILE_TGA_LIST:
1450         case FILE_TIFF:
1451         case FILE_TIFF_LIST:
1452         case FILE_VMPEG:
1453         case FILE_RAWDV:
1454         case FILE_FFMPEG:
1455                 return 1;
1456         }
1457         return 0;
1458 }
1459 int File::renders_video(Asset *asset)
1460 {
1461         return asset->format == FILE_FFMPEG ?
1462                 FFMPEG::renders_video(asset->fformat) :
1463                 renders_video(asset->format);
1464 }
1465
1466 int File::renders_audio(int format)
1467 {
1468         switch( format ) {
1469         case FILE_AC3:
1470         case FILE_FLAC:
1471         case FILE_PCM:
1472         case FILE_WAV:
1473         case FILE_OGG:
1474         case FILE_VORBIS:
1475         case FILE_AMPEG:
1476         case FILE_AU:
1477         case FILE_AIFF:
1478         case FILE_SND:
1479         case FILE_RAWDV:
1480         case FILE_FFMPEG:
1481                 return 1;
1482         }
1483         return 0;
1484 }
1485 int File::renders_audio(Asset *asset)
1486 {
1487         return asset->format == FILE_FFMPEG ?
1488                 FFMPEG::renders_audio(asset->fformat) :
1489                 renders_audio(asset->format);
1490 }
1491
1492 int File::is_image_render(int format)
1493 {
1494         switch( format ) {
1495         case FILE_EXR:
1496         case FILE_JPEG:
1497         case FILE_PNG:
1498         case FILE_PPM:
1499         case FILE_TGA:
1500         case FILE_TIFF:
1501                 return 1;
1502         }
1503
1504         return 0;
1505 }
1506
1507 const char* File::get_tag(int format)
1508 {
1509         switch( format ) {
1510         case FILE_AC3:          return "ac3";
1511         case FILE_AIFF:         return "aif";
1512         case FILE_AMPEG:        return "mp3";
1513         case FILE_AU:           return "au";
1514         case FILE_RAWDV:        return "dv";
1515         case FILE_DB:           return "db";
1516         case FILE_EXR:          return "exr";
1517         case FILE_EXR_LIST:     return "exrs";
1518         case FILE_FLAC:         return "flac";
1519         case FILE_JPEG:         return "jpg";
1520         case FILE_JPEG_LIST:    return "jpgs";
1521         case FILE_OGG:          return "ogg";
1522         case FILE_GIF:          return "gif";
1523         case FILE_GIF_LIST:     return "gifs";
1524         case FILE_PCM:          return "pcm";
1525         case FILE_PNG:          return "png";
1526         case FILE_PNG_LIST:     return "pngs";
1527         case FILE_PPM:          return "ppm";
1528         case FILE_PPM_LIST:     return "ppms";
1529         case FILE_TGA:          return "tga";
1530         case FILE_TGA_LIST:     return "tgas";
1531         case FILE_TIFF:         return "tif";
1532         case FILE_TIFF_LIST:    return "tifs";
1533         case FILE_VMPEG:        return "m2v";
1534         case FILE_VORBIS:       return "ogg";
1535         case FILE_WAV:          return "wav";
1536         case FILE_FFMPEG:       return "ffmpg";
1537         case FILE_REF:          return "ref";
1538         }
1539         return 0;
1540 }
1541
1542 const char* File::get_prefix(int format)
1543 {
1544         switch( format ) {
1545         case FILE_PCM:          return "PCM";
1546         case FILE_WAV:          return "WAV";
1547         case FILE_PNG:          return "PNG";
1548         case FILE_PPM:          return "PPM";
1549         case FILE_JPEG:         return "JPEG";
1550         case FILE_TIFF:         return "TIFF";
1551         case FILE_GIF:          return "GIF";
1552         case FILE_JPEG_LIST:    return "JPEG_LIST";
1553         case FILE_AU:           return "AU";
1554         case FILE_AIFF:         return "AIFF";
1555         case FILE_SND:          return "SND";
1556         case FILE_TGA_LIST:     return "TGA_LIST";
1557         case FILE_TGA:          return "TGA";
1558         case FILE_MPEG:         return "MPEG";
1559         case FILE_AMPEG:        return "AMPEG";
1560         case FILE_VMPEG:        return "VMPEG";
1561         case FILE_RAWDV:        return "RAWDV";
1562         case FILE_TIFF_LIST:    return "TIFF_LIST";
1563         case FILE_PNG_LIST:     return "PNG_LIST";
1564         case FILE_PPM_LIST:     return "PPM_LIST";
1565         case FILE_AC3:          return "AC3";
1566         case FILE_EXR:          return "EXR";
1567         case FILE_EXR_LIST:     return "EXR_LIST";
1568         case FILE_CR2:          return "CR2";
1569         case FILE_OGG:          return "OGG";
1570         case FILE_VORBIS:       return "VORBIS";
1571         case FILE_FLAC:         return "FLAC";
1572         case FILE_FFMPEG:       return "FFMPEG";
1573         case FILE_SCENE:        return "SCENE";
1574         case FILE_CR2_LIST:     return "CR2_LIST";
1575         case FILE_GIF_LIST:     return "GIF_LIST";
1576         case FILE_DB:           return "DB";
1577         case FILE_REF:          return "REF";
1578         }
1579         return _("UNKNOWN");
1580 }
1581
1582
1583 int File::record_fd()
1584 {
1585         return file ? file->record_fd() : -1;
1586 }
1587
1588
1589 void File::get_exe_path(char *result, char *bnp)
1590 {
1591 // Get executable path, basename
1592         int len = readlink("/proc/self/exe", result, BCTEXTLEN-1);
1593         if( len >= 0 ) {
1594                 result[len] = 0;
1595                 char *ptr = strrchr(result, '/');
1596                 if( ptr ) *ptr++ = 0; else ptr = result;
1597                 if( bnp ) strncpy(bnp, ptr, BCTEXTLEN);
1598         }
1599         else {
1600                 *result = 0;
1601                 if( bnp ) *bnp = 0;
1602         }
1603 }
1604
1605 void File::getenv_path(char *result, const char *path)
1606 {
1607         char *rp = result, *ep = rp + BCTEXTLEN-1;
1608         const char *cp = path;
1609 // any env var can be used here to expand a path as:
1610 //   "path...$id...": and id is a word as alpha,alnum...
1611 //   expands as "path...getenv(id)..."
1612 // CIN_PATH, CIN_LIB are set in main.C,
1613         for( int ch=*cp++; ch && rp < ep; ch=*cp++ ) {
1614                 if( ch == '$' && isalpha(*cp) ) { // scan alpha,alnum...
1615                         const char *bp = cp;  char *p = rp;
1616                         while( p < ep && *bp && (isalnum(*bp) || *bp == '_') ) *p++ = *bp++;
1617                         *p = 0;
1618                         const char *envp = getenv(rp); // read env value
1619                         if( !envp ) continue;
1620                         while( *envp && rp < ep ) *rp++ = *envp++;
1621                         cp = bp;                 // subst id=value
1622                         continue;
1623                 }
1624                 *rp++ = ch;
1625         }
1626         *rp = 0;
1627 }
1628
1629 void File::setenv_path(const char *var, const char *path, int overwrite)
1630 {
1631         char env_path[BCTEXTLEN];
1632         getenv_path(env_path, path);
1633         setenv(var, env_path, overwrite);
1634 }
1635
1636 void File::init_cin_path()
1637 {
1638         char env_path[BCTEXTLEN], env_pkg[BCTEXTLEN];
1639 // these values are advertised for forks/shell scripts
1640         get_exe_path(env_path, env_pkg);
1641         setenv_path("CIN_PATH", env_path, 1);
1642         setenv_path("CIN_PKG", env_pkg, 1);
1643         setenv_path("CIN_DAT", CINDAT_DIR, 0);
1644         setenv_path("CIN_LIB", CINLIB_DIR, 0);
1645         setenv_path("CIN_CONFIG", CONFIG_DIR, 0);
1646         setenv_path("CIN_PLUGIN", PLUGIN_DIR, 0);
1647         setenv_path("CIN_LADSPA", LADSPA_DIR, 0);
1648         setenv_path("CIN_LOCALE", LOCALE_DIR, 0);
1649         setenv_path("CIN_BROWSER", CIN_BROWSER, 0);
1650 }
1651