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