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