add LastFrame plugin, add bld_scripts
[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 "filefork.h"
51 #include "filegif.h"
52 #include "file.h"
53 #include "filejpeg.h"
54 #include "filempeg.h"
55 #undef HAVE_STDLIB_H // automake conflict
56 #include "fileogg.h"
57 #include "filepng.h"
58 #include "filescene.h"
59 #include "fileserver.h"
60 #include "filesndfile.h"
61 #include "filetga.h"
62 #include "filethread.h"
63 #include "filetiff.h"
64 #include "filevorbis.h"
65 #include "filexml.h"
66 #include "format.inc"
67 #include "formatwindow.h"
68 #include "formattools.h"
69 #include "framecache.h"
70 #include "language.h"
71 #include "mutex.h"
72 #include "mwindow.h"
73 #include "packagingengine.h"
74 #include "pluginserver.h"
75 #include "preferences.h"
76 #include "samples.h"
77 #include "vframe.h"
78
79 //suppress noref warning
80 void *vorbis0_ov_callbacks[] = {
81  &OV_CALLBACKS_DEFAULT, &OV_CALLBACKS_NOCLOSE,
82  &OV_CALLBACKS_STREAMONLY, &OV_CALLBACKS_STREAMONLY_NOCLOSE,
83 };
84
85 File::File()
86 {
87         cpus = 1;
88         asset = new Asset;
89         format_completion = new Condition(1, "File::format_completion");
90         write_lock = new Condition(1, "File::write_lock");
91         frame_cache = new FrameCache;
92 #ifdef USE_FILEFORK
93         forked = new Mutex("File::forked",0);
94 #endif
95         reset_parameters();
96 }
97
98 File::~File()
99 {
100         if(getting_options)
101         {
102                 if(format_window) format_window->set_done(0);
103                 format_completion->lock("File::~File");
104                 format_completion->unlock();
105         }
106
107         if(temp_frame) delete temp_frame;
108
109
110         close_file(0);
111
112         asset->Garbage::remove_user();
113         delete format_completion;
114         delete write_lock;
115 #ifdef USE_FILEFORK
116         delete forked;
117 #endif
118         delete frame_cache;
119 }
120
121 void File::reset_parameters()
122 {
123 #ifdef USE_FILEFORK
124         file_fork = 0;
125         is_fork = 0;
126 #endif
127
128         file = 0;
129         audio_thread = 0;
130         video_thread = 0;
131         getting_options = 0;
132         format_window = 0;
133         temp_frame = 0;
134         current_sample = 0;
135         current_frame = 0;
136         current_channel = 0;
137         current_program = 0;
138         current_layer = 0;
139         normalized_sample = 0;
140         use_cache = 0;
141         preferences = 0;
142         playback_subtitle = -1;
143         interpolate_raw = 1;
144
145
146         temp_samples_buffer = 0;
147         temp_frame_buffer = 0;
148         current_frame_buffer = 0;
149         audio_ring_buffers = 0;
150         video_ring_buffers = 0;
151         video_buffer_size = 0;
152 }
153
154 int File::raise_window()
155 {
156         if(getting_options && format_window)
157         {
158                 format_window->raise_window();
159                 format_window->flush();
160         }
161         return 0;
162 }
163
164 void File::close_window()
165 {
166         if(getting_options)
167         {
168                 format_window->lock_window("File::close_window");
169                 format_window->set_done(1);
170                 format_window->unlock_window();
171                 getting_options = 0;
172         }
173 }
174
175 int File::get_options(FormatTools *format,
176         int audio_options, int video_options)
177 {
178         BC_WindowBase *parent_window = format->window;
179         //ArrayList<PluginServer*> *plugindb = format->plugindb;
180         Asset *asset = format->asset;
181
182         getting_options = 1;
183         format_completion->lock("File::get_options");
184         switch(asset->format)
185         {
186                 case FILE_AC3:
187                         FileAC3::get_parameters(parent_window,
188                                 asset,
189                                 format_window,
190                                 audio_options,
191                                 video_options);
192                         break;
193                 case FILE_RAWDV:
194                         FileDV::get_parameters(parent_window,
195                                 asset,
196                                 format_window,
197                                 audio_options,
198                                 video_options);
199                         break;
200                 case FILE_PCM:
201                 case FILE_WAV:
202                 case FILE_AU:
203                 case FILE_AIFF:
204                 case FILE_SND:
205                         FileSndFile::get_parameters(parent_window, 
206                                 asset, 
207                                 format_window, 
208                                 audio_options, 
209                                 video_options);
210                         break;
211                 case FILE_FFMPEG:
212                         FileFFMPEG::get_parameters(parent_window, 
213                                 asset, 
214                                 format_window, 
215                                 audio_options, 
216                                 video_options);
217                         break;
218                 case FILE_AMPEG:
219                 case FILE_VMPEG:
220                         FileMPEG::get_parameters(parent_window, 
221                                 asset, 
222                                 format_window, 
223                                 audio_options, 
224                                 video_options);
225                         break;
226                 case FILE_JPEG:
227                 case FILE_JPEG_LIST:
228                         FileJPEG::get_parameters(parent_window, 
229                                 asset, 
230                                 format_window, 
231                                 audio_options, 
232                                 video_options);
233                         break;
234                 case FILE_EXR:
235                 case FILE_EXR_LIST:
236                         FileEXR::get_parameters(parent_window, 
237                                 asset, 
238                                 format_window, 
239                                 audio_options, 
240                                 video_options);
241                         break;
242                 case FILE_FLAC:
243                         FileFLAC::get_parameters(parent_window, 
244                                 asset, 
245                                 format_window, 
246                                 audio_options, 
247                                 video_options);
248                         break;
249                 case FILE_PNG:
250                 case FILE_PNG_LIST:
251                         FilePNG::get_parameters(parent_window, 
252                                 asset, 
253                                 format_window, 
254                                 audio_options, 
255                                 video_options);
256                         break;
257                 case FILE_TGA:
258                 case FILE_TGA_LIST:
259                         FileTGA::get_parameters(parent_window, 
260                                 asset, 
261                                 format_window, 
262                                 audio_options, 
263                                 video_options);
264                         break;
265                 case FILE_TIFF:
266                 case FILE_TIFF_LIST:
267                         FileTIFF::get_parameters(parent_window, 
268                                 asset, 
269                                 format_window, 
270                                 audio_options, 
271                                 video_options);
272                         break;
273                 case FILE_OGG:
274                         FileOGG::get_parameters(parent_window,
275                                 asset,
276                                 format_window,
277                                 audio_options,
278                                 video_options);
279                         break;
280                 default:
281                         break;
282         }
283
284         if(!format_window)
285         {
286                 ErrorBox *errorbox = new ErrorBox(_(PROGRAM_NAME ": Error"),
287                         parent_window->get_abs_cursor_x(1),
288                         parent_window->get_abs_cursor_y(1));
289                 format_window = errorbox;
290                 getting_options = 1;
291                 if(audio_options)
292                         errorbox->create_objects(_("This format doesn't support audio."));
293                 else
294                 if(video_options)
295                         errorbox->create_objects(_("This format doesn't support video."));
296                 errorbox->run_window();
297                 delete errorbox;
298         }
299
300         getting_options = 0;
301         format_window = 0;
302         format_completion->unlock();
303         return 0;
304 }
305
306
307
308
309
310
311
312
313
314
315 int File::set_processors(int cpus)   // Set the number of cpus for certain codecs
316 {
317         if( cpus > 8 )          // mpegvideo max_threads = 16, more causes errs
318                 cpus = 8;       //  8 cpus ought to decode just about anything
319 #ifdef USE_FILEFORK
320         if(file_fork)
321         {
322                 FileForker this_is(*forked);
323                 file_fork->send_command(FileFork::SET_PROCESSORS, (unsigned char*)&cpus, sizeof(cpus));
324                 file_fork->read_result();
325         }
326 #endif
327
328 // Set all instances so gets work.
329         this->cpus = cpus;
330
331         return 0;
332 }
333
334 int File::set_preload(int64_t size)
335 {
336 #ifdef USE_FILEFORK
337         if(file_fork)
338         {
339                 FileForker this_is(*forked);
340                 file_fork->send_command(FileFork::SET_PRELOAD, (unsigned char*)&size, sizeof(size));
341                 file_fork->read_result();
342         }
343
344 #endif
345
346         this->playback_preload = size;
347         return 0;
348 }
349
350 void File::set_subtitle(int value)
351 {
352 #ifdef USE_FILEFORK
353         if(file_fork)
354         {
355                 FileForker this_is(*forked);
356                 file_fork->send_command(FileFork::SET_SUBTITLE, (unsigned char*)&value, sizeof(value));
357                 file_fork->read_result();
358         }
359
360 #endif
361         this->playback_subtitle = value;
362         if( file ) file->set_subtitle(value);
363 }
364
365 void File::set_interpolate_raw(int value)
366 {
367 #ifdef USE_FILEFORK
368         if(file_fork)
369         {
370                 FileForker this_is(*forked);
371                 file_fork->send_command(FileFork::SET_INTERPOLATE_RAW, (unsigned char*)&value, sizeof(value));
372                 file_fork->read_result();
373         }
374
375 #endif
376
377         this->interpolate_raw = value;
378 }
379
380 void File::set_white_balance_raw(int value)
381 {
382 #ifdef USE_FILEFORK
383         if(file_fork)
384         {
385                 FileForker this_is(*forked);
386                 file_fork->send_command(FileFork::SET_WHITE_BALANCE_RAW, (unsigned char*)&value, sizeof(value));
387                 file_fork->read_result();
388         }
389 #endif
390
391         this->white_balance_raw = value;
392 }
393
394
395 void File::set_cache_frames(int value)
396 {
397 // caching only done locally
398         if(!video_thread)
399                 use_cache = value;
400 }
401
402 int File::purge_cache()
403 {
404 // caching only done locally
405         int result = 0;
406         if( frame_cache->cache_items() > 0 )
407         {
408                 frame_cache->remove_all();
409                 result = 1;
410         }
411         return result;
412 }
413
414 int File::delete_oldest()
415 {
416 // caching only done locally
417         return frame_cache->delete_oldest();
418 }
419
420
421
422
423
424
425
426
427
428
429
430 int File::open_file(Preferences *preferences, 
431         Asset *asset, 
432         int rd, 
433         int wr)
434 {
435         int result = 0;
436         const int debug = 0;
437
438         this->preferences = preferences;
439         this->asset->copy_from(asset, 1);
440         this->rd = rd;
441         this->wr = wr;
442         file = 0;
443
444         if(debug) printf("File::open_file %d\n", __LINE__);
445
446 #ifdef USE_FILEFORK
447         if( !is_fork && MWindow::file_server && (rd || wr) ) {
448                 FileForker this_is(*forked);
449 // printf("File::open_file %d file_server=%p rd=%d wr=%d %d\n", 
450 // __LINE__, 
451 // MWindow::file_server,
452 // rd, 
453 // wr, 
454 // asset->ms_quantization);
455                 file_fork = MWindow::file_server->new_filefork();
456 //printf("File::open_file %d\n", __LINE__);
457
458 // Send the asset
459 // Convert to hash table
460                 BC_Hash table;
461                 asset->save_defaults(&table, "", 1, 1, 1, 1, 1);
462 // Convert to string
463                 char *string = 0;
464                 table.save_string(string);
465                 int buffer_size = sizeof(int) * 7 + strlen(string) + 1;
466                 unsigned char *buffer = new unsigned char[buffer_size];
467                 int offset = 0;
468                 *(int*)(buffer + offset) = rd;
469                 offset += sizeof(int);
470                 *(int*)(buffer + offset) = wr;
471                 offset += sizeof(int);
472                 *(int*)(buffer + offset) = cpus;
473                 offset += sizeof(int);
474                 *(int*)(buffer + offset) = white_balance_raw;
475                 offset += sizeof(int);
476                 *(int*)(buffer + offset) = interpolate_raw;
477                 offset += sizeof(int);
478                 *(int*)(buffer + offset) = playback_subtitle;
479                 offset += sizeof(int);
480                 *(int*)(buffer + offset) = current_program;
481                 offset += sizeof(int);
482                 memcpy(buffer + offset, string, strlen(string) + 1);
483 //printf("File::open_file %d\n", __LINE__);
484                 file_fork->send_command(FileFork::OPEN_FILE, 
485                         buffer, 
486                         buffer_size);
487                 delete [] buffer;
488                 free(string);
489 //printf("File::open_file %d\n", __LINE__);
490
491 // Get the updated asset from the fork
492                 result = file_fork->read_result();
493 //printf("File::open_file %d\n", __LINE__);
494                 if(!result)
495                 {
496                         table.load_string((char*)file_fork->result_data);
497
498                         asset->load_defaults(&table, "", 1, 1, 1, 1, 1);
499                         this->asset->load_defaults(&table, "", 1, 1, 1, 1, 1);
500 //this->asset->dump();
501                 }
502 //printf("File::open_file %d\n", __LINE__);
503
504
505 // If it's a scene renderer, close it & reopen it locally to get the 
506 // full OpenGL support.
507 // Just doing 2D for now.  Should be forked in case Festival crashes.
508 //              if(rd && this->asset->format == FILE_SCENE)
509 //              {
510 // //printf("File::open_file %p %d\n", this, __LINE__);
511 //                      close_file(0);
512 // // Lie to get it to work properly
513 //                      is_fork = 1;
514 //              }
515 //              else
516                 {
517                         return result;
518                 }
519         }
520 #endif
521
522
523         if(debug) printf("File::open_file %p %d\n", this, __LINE__);
524
525         switch(this->asset->format)
526         {
527 // get the format now
528 // If you add another format to case 0, you also need to add another case for the
529 // file format #define.
530                 case FILE_UNKNOWN:
531                         if(FileDB::check_sig(this->asset)) {
532 // MediaDb file
533                                 file = new FileDB(this->asset, this);
534                                 break;
535                         }
536 // if early probe enabled
537                         if( preferences->ffmpeg_early_probe &&
538                             FileFFMPEG::check_sig(this->asset)) {
539                                 file = new FileFFMPEG(this->asset, this);
540                                 break;
541                         }
542
543                         FILE *stream;
544                         if(!(stream = fopen(this->asset->path, "rb"))) {
545 // file not found
546                                 return 1;
547                         }
548
549                         char test[16];
550                         result = fread(test, 16, 1, stream);
551
552                         if(FileScene::check_sig(this->asset, test)) {
553 // libsndfile
554                                 fclose(stream);
555                                 file = new FileScene(this->asset, this);
556                                 break;
557                         }
558                         if(FileDV::check_sig(this->asset)) {
559 // libdv
560                                 fclose(stream);
561                                 file = new FileDV(this->asset, this);
562                                 break;
563                         }
564                         if(FileSndFile::check_sig(this->asset)) {
565 // libsndfile
566                                 fclose(stream);
567                                 file = new FileSndFile(this->asset, this);
568                                 break;
569                         }
570                         if(FilePNG::check_sig(this->asset)) {
571 // PNG file
572                                 fclose(stream);
573                                 file = new FilePNG(this->asset, this);
574                                 break;
575                         }
576                         if(FileJPEG::check_sig(this->asset)) {
577 // JPEG file
578                                 fclose(stream);
579                                 file = new FileJPEG(this->asset, this);
580                                 break;
581                         }
582                         if(FileGIF::check_sig(this->asset)) {
583 // GIF file
584                                 fclose(stream);
585                                 file = new FileGIF(this->asset, this);
586                                 break;
587                         }
588                         if(FileEXR::check_sig(this->asset, test)) {
589 // EXR file
590                                 fclose(stream);
591                                 file = new FileEXR(this->asset, this);
592                                 break;
593                         }
594                         if(FileFLAC::check_sig(this->asset, test)) {
595 // FLAC file
596                                 fclose(stream);
597                                 file = new FileFLAC(this->asset, this);
598                                 break;
599                         }
600                         if(FileCR2::check_sig(this->asset)) {
601 // CR2 file
602                                 fclose(stream);
603                                 file = new FileCR2(this->asset, this);
604                                 break;
605                         }
606                         if(FileTGA::check_sig(this->asset)) {
607 // TGA file
608                                 fclose(stream);
609                                 file = new FileTGA(this->asset, this);
610                                 break;
611                         }
612                         if(FileTIFF::check_sig(this->asset)) {
613 // TIFF file
614                                 fclose(stream);
615                                 file = new FileTIFF(this->asset, this);
616                                 break;
617                         }
618                         if(FileOGG::check_sig(this->asset)) {
619 // OGG file
620                                 fclose(stream);
621                                 file = new FileOGG(this->asset, this);
622                                 break;
623                         }
624                         if(FileVorbis::check_sig(this->asset)) {
625 // VorbisFile file
626                                 fclose(stream);
627                                 file = new FileVorbis(this->asset, this);
628                                 break;
629                         }
630                         if(FileMPEG::check_sig(this->asset)) {
631 // MPEG file
632                                 fclose(stream);
633                                 file = new FileMPEG(this->asset, this);
634                                 break;
635                         }
636                         if( test[0] == '<' && (
637                                 !strncmp(&test[1],"EDL>",4) ||
638                                 !strncmp(&test[1],"HTAL>",5) ||
639                                 !strncmp(&test[1],"?xml",4) ) ) {
640 // XML file
641                                 fclose(stream);
642                                 return FILE_IS_XML;
643                         }    // can't load project file
644                         if( !preferences->ffmpeg_early_probe &&
645                             FileFFMPEG::check_sig(this->asset) ) {
646                                 fclose(stream);
647                                 file = new FileFFMPEG(this->asset, this);
648                                 break;
649                         }
650 // PCM file
651                         fclose(stream);
652                         return FILE_UNRECOGNIZED_CODEC;
653                         break;
654
655 // format already determined
656                 case FILE_AC3:
657                         file = new FileAC3(this->asset, this);
658                         break;
659
660                 case FILE_SCENE:
661                         file = new FileScene(this->asset, this);
662                         break;
663
664                 case FILE_FFMPEG:
665                         file = new FileFFMPEG(this->asset, this);
666                         break;
667
668                 case FILE_PCM:
669                 case FILE_WAV:
670                 case FILE_AU:
671                 case FILE_AIFF:
672                 case FILE_SND:
673 //printf("File::open_file 1\n");
674                         file = new FileSndFile(this->asset, this);
675                         break;
676
677                 case FILE_PNG:
678                 case FILE_PNG_LIST:
679                         file = new FilePNG(this->asset, this);
680                         break;
681
682                 case FILE_JPEG:
683                 case FILE_JPEG_LIST:
684                         file = new FileJPEG(this->asset, this);
685                         break;
686
687                 case FILE_GIF:
688                 case FILE_GIF_LIST:
689                         file = new FileGIF(this->asset, this);
690                         break;
691
692                 case FILE_EXR:
693                 case FILE_EXR_LIST:
694                         file = new FileEXR(this->asset, this);
695                         break;
696
697                 case FILE_FLAC:
698                         file = new FileFLAC(this->asset, this);
699                         break;
700
701                 case FILE_CR2:
702                 case FILE_CR2_LIST:
703                         file = new FileCR2(this->asset, this);
704                         break;
705
706                 case FILE_TGA_LIST:
707                 case FILE_TGA:
708                         file = new FileTGA(this->asset, this);
709                         break;
710
711                 case FILE_TIFF:
712                 case FILE_TIFF_LIST:
713                         file = new FileTIFF(this->asset, this);
714                         break;
715
716                 case FILE_DB:
717                         file = new FileDB(this->asset, this);
718                         break;
719
720                 case FILE_MPEG:
721                 case FILE_AMPEG:
722                 case FILE_VMPEG:
723                         file = new FileMPEG(this->asset, this);
724                         break;
725
726                 case FILE_OGG:
727                         file = new FileOGG(this->asset, this);
728                         break;
729
730                 case FILE_VORBIS:
731                         file = new FileVorbis(this->asset, this);
732                         break;
733
734                 case FILE_RAWDV:
735                         file = new FileDV(this->asset, this);
736                         break;
737
738 // try plugins
739                 default:
740                         return 1;
741                         break;
742         }
743
744
745 // Reopen file with correct parser and get header.
746         if(file->open_file(rd, wr)) {
747                 delete file;  file = 0;
748                 return FILE_NOT_FOUND;
749         }
750
751
752
753 // Set extra writing parameters to mandatory settings.
754         if( wr ) {
755                 if(this->asset->dither) file->set_dither();
756         }
757
758         if( rd ) {
759 // one frame image file, no specific length
760                 if( !this->asset->audio_data && this->asset->video_data &&
761                     this->asset->video_length <= 1 )
762                         this->asset->video_length = -1;
763         }
764
765 // Synchronize header parameters
766         asset->copy_from(this->asset, 1);
767 //asset->dump();
768
769         if(debug) printf("File::open_file %d file=%p\n", __LINE__, file);
770 // sleep(1);
771
772         return FILE_OK;
773 }
774
775 void File::delete_temp_samples_buffer()
776 {
777
778         if(temp_samples_buffer) {
779                 for(int j = 0; j < audio_ring_buffers; j++) {
780                         for(int i = 0; i < asset->channels; i++) {
781                                 delete temp_samples_buffer[j][i];
782                         }
783                         delete [] temp_samples_buffer[j];
784                 }
785
786                 delete [] temp_samples_buffer;
787                 temp_samples_buffer = 0;
788                 audio_ring_buffers = 0;
789         }
790 }
791
792 void File::delete_temp_frame_buffer()
793 {
794         
795         if(temp_frame_buffer) {
796                 for(int k = 0; k < video_ring_buffers; k++) {
797                         for(int i = 0; i < asset->layers; i++) {
798                                 for(int j = 0; j < video_buffer_size; j++) {
799                                         delete temp_frame_buffer[k][i][j];
800                                 }
801                                 delete [] temp_frame_buffer[k][i];
802                         }
803                         delete [] temp_frame_buffer[k];
804                 }
805
806                 delete [] temp_frame_buffer;
807                 temp_frame_buffer = 0;
808                 video_ring_buffers = 0;
809                 video_buffer_size = 0;
810         }
811 }
812
813 int File::close_file(int ignore_thread)
814 {
815         const int debug = 0;
816
817 #ifdef USE_FILEFORK
818         if(debug) printf("File::close_file file=%p file_fork=%p %d\n", file, file_fork, __LINE__);
819
820         if(file_fork) {
821                 FileForker this_is(*forked);
822                 file_fork->send_command(FileFork::CLOSE_FILE, 0, 0);
823                 file_fork->read_result();
824
825                 if(asset && wr) {
826                         asset->audio_length = current_sample = *(int64_t*)file_fork->result_data;
827                         asset->video_length = current_frame = *(int64_t*)(file_fork->result_data + sizeof(int64_t));
828                 }
829
830                 if(debug) printf("File::close_file:%d current_sample=" _LD " current_frame=" _LD "\n", 
831                         __LINE__,
832                         current_sample,
833                         current_frame);
834
835                 delete file_fork;
836                 file_fork = 0;
837         }
838 #endif
839
840         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
841
842         if(!ignore_thread) {
843                 stop_audio_thread();
844                 stop_video_thread();
845         }
846
847
848         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
849         if(file) {
850 // The file's asset is a copy of the argument passed to open_file so the
851 // user must copy lengths from the file's asset.
852                 if(asset && wr) {
853                         asset->audio_length = current_sample;
854                         asset->video_length = current_frame;
855                 }
856
857                 file->close_file();
858                 delete file;
859         }
860         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
861
862         delete_temp_samples_buffer();
863         delete_temp_frame_buffer();
864         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
865
866         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
867
868         reset_parameters();
869         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
870         return 0;
871 }
872
873
874
875 int File::get_index(char *index_path)
876 {
877 #ifdef USE_FILEFORK
878         if(file_fork) {
879                 FileForker this_is(*forked);
880                 file_fork->send_command(FileFork::GET_INDEX, (unsigned char*)index_path, strlen(index_path) + 1);
881                 int result = file_fork->read_result();
882                 return result;
883         }
884 #endif
885
886         if(file) {
887                 return file->get_index(index_path);
888         }
889         return 1;
890 }
891
892
893
894 int File::start_audio_thread(int buffer_size, int ring_buffers)
895 {
896         this->audio_ring_buffers = ring_buffers;
897
898 #ifdef USE_FILEFORK
899         if(file_fork)
900         {
901                 FileForker this_is(*forked);
902                 unsigned char buffer[sizeof(int) * 2];
903                 int *ibfr = (int *)buffer;
904                 ibfr[0] = buffer_size;
905                 ibfr[1] = audio_ring_buffers;
906                 file_fork->send_command(FileFork::START_AUDIO_THREAD, buffer, sizeof(buffer));
907                 int result = file_fork->read_result();
908
909
910 //printf("File::start_audio_thread %d file_fork->result_data=%p\n", __LINE__, file_fork->result_data);
911 // Create server copy of buffer
912                 delete_temp_samples_buffer();
913 //printf("File::start_audio_thread %d\n", __LINE__);
914                 temp_samples_buffer = new Samples**[audio_ring_buffers];
915 //printf("File::start_audio_thread %d\n", __LINE__);
916                 for(int i = 0; i < audio_ring_buffers; i++)
917                 {
918 //printf("File::start_audio_thread %d\n", __LINE__);
919                         temp_samples_buffer[i] = new Samples*[asset->channels];
920 //printf("File::start_audio_thread %d\n", __LINE__);
921                         for(int j = 0; j < asset->channels; j++)
922                         {
923                                 int offset = i * Samples::filefork_size() * asset->channels +
924                                         j * Samples::filefork_size();
925 //printf("File::start_audio_thread %d j=%d offset=%d\n", __LINE__, j, offset);
926                                 temp_samples_buffer[i][j] = new Samples;
927                                 temp_samples_buffer[i][j]->from_filefork(
928                                         file_fork->result_data +
929                                         offset);
930 //printf("File::start_audio_thread %d\n", __LINE__);
931                         }
932                 }
933                 
934                 return result;
935         }
936 #endif
937
938         
939         if(!audio_thread)
940         {
941                 audio_thread = new FileThread(this, 1, 0);
942                 audio_thread->start_writing(buffer_size, 0, ring_buffers, 0);
943         }
944         return 0;
945 }
946
947 int File::start_video_thread(int buffer_size, 
948         int color_model, 
949         int ring_buffers, 
950         int compressed)
951 {
952         this->video_ring_buffers = ring_buffers;
953         this->video_buffer_size = buffer_size;
954
955 #ifdef USE_FILEFORK
956         if(file_fork)
957         {
958                 FileForker this_is(*forked);
959 // This resets variables
960                 delete_temp_frame_buffer();
961
962                 this->video_ring_buffers = ring_buffers;
963                 this->video_buffer_size = buffer_size;
964
965                 unsigned char buffer[sizeof(int) * 4];
966                 int *ibfr = (int *)buffer;
967                 ibfr[0] = buffer_size;
968                 ibfr[1] = color_model;
969                 ibfr[2] = video_ring_buffers;
970                 ibfr[3] = compressed;
971 // Buffers are allocated
972                 file_fork->send_command(FileFork::START_VIDEO_THREAD, 
973                         buffer, 
974                         sizeof(buffer));
975                 int result = file_fork->read_result();
976
977
978 // Create server copy of buffer
979 //printf("File::start_video_thread %d %d\n", __LINE__, video_ring_buffers);
980                 temp_frame_buffer = new VFrame***[video_ring_buffers];
981                 for(int i = 0; i < video_ring_buffers; i++)
982                 {
983                         temp_frame_buffer[i] = new VFrame**[asset->layers];
984                         for(int j = 0; j < asset->layers; j++)
985                         {
986                                 temp_frame_buffer[i][j] = new VFrame*[video_buffer_size];
987 //printf("File::start_video_thread %d %p\n", __LINE__, temp_frame_buffer[i][j]);
988                                 for(int k = 0; k < video_buffer_size; k++)
989                                 {
990                                         temp_frame_buffer[i][j][k] = new VFrame;
991                                         temp_frame_buffer[i][j][k]->from_filefork(file_fork->result_data + 
992                                                 i * asset->layers * video_buffer_size * VFrame::filefork_size() + 
993                                                 j * video_buffer_size * VFrame::filefork_size() +
994                                                 k * VFrame::filefork_size());
995                                 }
996                         }
997                 }
998
999
1000                 return result;
1001         }
1002 #endif
1003
1004
1005
1006         if(!video_thread)
1007         {
1008                 video_thread = new FileThread(this, 0, 1);
1009                 video_thread->start_writing(buffer_size, 
1010                         color_model, 
1011                         ring_buffers, 
1012                         compressed);
1013         }
1014         return 0;
1015 }
1016
1017 int File::start_video_decode_thread()
1018 {
1019 #ifdef USE_FILEFORK
1020         if(file_fork)
1021         {
1022                 FileForker this_is(*forked);
1023                 file_fork->send_command(FileFork::START_VIDEO_DECODE_THREAD, 0, 0);
1024                 file_fork->read_result();
1025                 return 0;
1026         }
1027 #endif
1028
1029
1030 // Currently, CR2 is the only one which won't work asynchronously, so
1031 // we're not using a virtual function yet.
1032         if(!video_thread /* && asset->format != FILE_CR2 */)
1033         {
1034                 video_thread = new FileThread(this, 0, 1);
1035                 video_thread->start_reading();
1036                 use_cache = 0;
1037         }
1038         return 0;
1039 }
1040
1041 int File::stop_audio_thread()
1042 {
1043 #ifdef USE_FILEFORK
1044         if(file_fork)
1045         {
1046                 file_fork->send_command(FileFork::STOP_AUDIO_THREAD, 0, 0);
1047                 file_fork->read_result();
1048                 return 0;
1049         }
1050 #endif
1051
1052         if(audio_thread)
1053         {
1054                 audio_thread->stop_writing();
1055                 delete audio_thread;
1056                 audio_thread = 0;
1057         }
1058         return 0;
1059 }
1060
1061 int File::stop_video_thread()
1062 {
1063 #ifdef USE_FILEFORK
1064         if(file_fork)
1065         {
1066                 FileForker this_is(*forked);
1067                 file_fork->send_command(FileFork::STOP_VIDEO_THREAD, 0, 0);
1068                 file_fork->read_result();
1069                 return 0;
1070         }
1071 #endif
1072
1073         if(video_thread)
1074         {
1075                 video_thread->stop_reading();
1076                 video_thread->stop_writing();
1077                 delete video_thread;
1078                 video_thread = 0;
1079         }
1080         return 0;
1081 }
1082
1083 FileThread* File::get_video_thread()
1084 {
1085         return video_thread;
1086 }
1087
1088 int File::set_channel(int channel) 
1089 {
1090 #ifdef USE_FILEFORK
1091         if(file_fork)
1092         {
1093                 FileForker this_is(*forked);
1094 // Set it locally for get_channel
1095                 current_channel = channel;
1096                 file_fork->send_command(FileFork::SET_CHANNEL, (unsigned char*)&channel, sizeof(channel));
1097                 int result = file_fork->read_result();
1098                 return result;
1099         }
1100 #endif
1101
1102         if(file && channel < asset->channels)
1103         {
1104                 current_channel = channel;
1105                 return 0;
1106         }
1107         else
1108                 return 1;
1109 }
1110
1111 int File::get_channel()
1112 {
1113         return current_channel;
1114 }
1115
1116 // if no>=0, sets new program
1117 //  returns current program
1118 int File::set_program(int no)
1119 {
1120 #ifdef USE_FILEFORK
1121         if(file_fork)
1122         {
1123                 FileForker this_is(*forked);
1124                 file_fork->send_command(FileFork::SET_PROGRAM, (unsigned char*)&no, sizeof(no));
1125                 int result = file_fork->read_result();
1126                 current_program = no < 0 ? result : no;
1127                 return result;
1128         }
1129 #endif
1130         int result = file ? file->set_program(no) : current_program;
1131         current_program = no < 0 ? result : no;
1132         return result;
1133 }
1134
1135 int File::get_cell_time(int no, double &time)
1136 {
1137 #ifdef USE_FILEFORK
1138         if(file_fork)
1139         {
1140                 FileForker this_is(*forked);
1141                 file_fork->send_command(FileFork::GET_CELL_TIME, (unsigned char*)&no, sizeof(no));
1142                 int result = file_fork->read_result();
1143                 time = *(double *)file_fork->result_data;
1144                 return result;
1145         }
1146 #endif
1147
1148         return file ? file->get_cell_time(no, time) : -1;
1149 }
1150
1151 int File::get_system_time(int64_t &tm)
1152 {
1153 #ifdef USE_FILEFORK
1154         if(file_fork)
1155         {
1156                 FileForker this_is(*forked);
1157                 file_fork->send_command(FileFork::GET_STT_TIME, 0, 0);
1158                 int result = file_fork->read_result();
1159                 tm = *(int64_t *)file_fork->result_data;
1160                 return result;
1161         }
1162 #endif
1163
1164         return file ? file->get_system_time(tm) : -1;
1165 }
1166
1167 int File::get_audio_for_video(int vstream, int astream, int64_t &channel_mask)
1168 {
1169 #ifdef USE_FILEFORK
1170         if(file_fork)
1171         {
1172                 FileForker this_is(*forked);
1173                 unsigned char buffer[2*sizeof(int)];
1174                 int offset = 0;
1175                 *(int*)(buffer + offset) = vstream;
1176                 offset += sizeof(int);
1177                 *(int*)(buffer + offset) = astream;
1178                 file_fork->send_command(FileFork::GET_AUDIO4VIDEO, buffer, sizeof(buffer));
1179                 int result = file_fork->read_result();
1180                 channel_mask = *(int64_t *)file_fork->result_data;
1181                 return result;
1182         }
1183 #endif
1184
1185         return file ? file->get_audio_for_video(vstream, astream, channel_mask) : -1;
1186 }
1187
1188 int File::get_video_pid(int track)
1189 {
1190 #ifdef USE_FILEFORK
1191         if(file_fork)
1192         {
1193                 FileForker this_is(*forked);
1194                 file_fork->send_command(FileFork::GET_VIDEO_PID,
1195                                 (unsigned char*)&track, sizeof(track));
1196                 int result = file_fork->read_result();
1197                 return result;
1198         }
1199 #endif
1200
1201         return file ? file->get_video_pid(track) : -1;
1202 }
1203
1204
1205
1206 int File::get_video_info(int track, int &pid, double &framerate,
1207                 int &width, int &height, char *title)
1208 {
1209 #ifdef USE_FILEFORK
1210         if(file_fork)
1211         {
1212                 FileForker this_is(*forked);
1213                 file_fork->send_command(FileFork::GET_VIDEO_INFO,
1214                                 (unsigned char*)&track, sizeof(track));
1215                 int result = file_fork->read_result();
1216                 if( !result ) {
1217                         unsigned char *bp = file_fork->result_data;
1218                         framerate = *(double*)bp;  bp += sizeof(framerate);
1219                         pid       = *(int *)  bp;  bp += sizeof(pid);
1220                         width     = *(int *)  bp;  bp += sizeof(width);
1221                         height    = *(int *)  bp;  bp += sizeof(height);
1222                         strcpy(title, (char *)bp);
1223                 }
1224                 return result;
1225         }
1226 #endif
1227
1228         return !file ? -1 :
1229                  file->get_video_info(track, pid, framerate, width, height, title);
1230 }
1231
1232 int File::select_video_stream(Asset *asset, int vstream)
1233 {
1234 #ifdef USE_FILEFORK
1235         if(file_fork)
1236         {
1237                 FileForker this_is(*forked);
1238                 file_fork->send_command(FileFork::SELECT_VIDEO_STREAM,
1239                                 (unsigned char*)&vstream, sizeof(vstream));
1240                 int result = file_fork->read_result();
1241                 if( !result ) {
1242                         unsigned char *bp = file_fork->result_data;
1243                         asset->frame_rate    = *(double*)  bp;  bp += sizeof(asset->frame_rate);
1244                         asset->video_length = *(int64_t *) bp;  bp += sizeof(asset->video_length);
1245                         asset->width        = *(int *)     bp;  bp += sizeof(asset->width);
1246                         asset->height       = *(int *)     bp;  bp += sizeof(asset->height);
1247                 }
1248         }
1249 #endif
1250         return !file ? -1 :
1251                  file->select_video_stream(asset, vstream);
1252 }
1253
1254 int File::select_audio_stream(Asset *asset, int astream)
1255 {
1256 #ifdef USE_FILEFORK
1257         if(file_fork)
1258         {
1259                 FileForker this_is(*forked);
1260                 file_fork->send_command(FileFork::SELECT_AUDIO_STREAM,
1261                                 (unsigned char*)&astream, sizeof(astream));
1262                 int result = file_fork->read_result();
1263                 if( !result ) {
1264                         unsigned char *bp = file_fork->result_data;
1265                         asset->audio_length = *(int64_t *) bp;  bp += sizeof(asset->audio_length);
1266                         asset->sample_rate  = *(int *)     bp;  bp += sizeof(asset->sample_rate);
1267                 }
1268         }
1269 #endif
1270         return !file ? -1 :
1271                  file->select_audio_stream(asset, astream);
1272 }
1273
1274
1275 int File::get_thumbnail(int stream,
1276         int64_t &position, unsigned char *&thumbnail, int &ww, int &hh)
1277 {
1278         return file->get_thumbnail(stream, position, thumbnail, ww, hh);
1279 }
1280
1281 int File::set_skimming(int track, int skim, skim_fn fn, void *vp)
1282 {
1283         return file->set_skimming(track, skim, fn, vp);
1284 }
1285
1286 int File::skim_video(int track, void *vp, skim_fn fn)
1287 {
1288         return file->skim_video(track, vp, fn);
1289 }
1290
1291
1292 int File::set_layer(int layer, int is_thread) 
1293 {
1294 #ifdef USE_FILEFORK
1295 // thread should only call in the fork
1296         if(file_fork && !is_fork && !is_thread)
1297         {
1298                 FileForker this_is(*forked);
1299                 file_fork->send_command(FileFork::SET_LAYER, (unsigned char*)&layer, sizeof(layer));
1300                 int result = file_fork->read_result();
1301                 current_layer = layer;
1302                 return result;
1303         }
1304 #endif
1305
1306         if(file && layer < asset->layers)
1307         {
1308                 if(!is_thread && video_thread)
1309                 {
1310                         video_thread->set_layer(layer);
1311                 }
1312                 else
1313                 {
1314                         current_layer = layer;
1315                 }
1316                 return 0; 
1317         }
1318         else
1319                 return 1;
1320 }
1321
1322 int64_t File::get_audio_length()
1323 {
1324 #ifdef USE_FILEFORK
1325         if(file_fork)
1326         {
1327                 FileForker this_is(*forked);
1328                 file_fork->send_command(FileFork::GET_AUDIO_LENGTH, 0, 0);
1329                 int64_t result = file_fork->read_result();
1330                 return result;
1331         }
1332 #endif
1333
1334         int64_t result = asset->audio_length;
1335         int64_t base_samplerate = -1;
1336         if(result > 0)
1337         {
1338                 if(base_samplerate > 0)
1339                         return (int64_t)((double)result / asset->sample_rate * base_samplerate + 0.5);
1340                 else
1341                         return result;
1342         }
1343         else
1344                 return -1;
1345 }
1346
1347 int64_t File::get_video_length()
1348
1349 #ifdef USE_FILEFORK
1350         if(file_fork)
1351         {
1352                 FileForker this_is(*forked);
1353                 file_fork->send_command(FileFork::GET_VIDEO_LENGTH, 0, 0);
1354                 int64_t result = file_fork->read_result();
1355                 return result;
1356         }
1357 #endif
1358
1359
1360         int64_t result = asset->video_length;
1361         float base_framerate = -1;
1362         if(result > 0)
1363         {
1364                 if(base_framerate > 0)
1365                         return (int64_t)((double)result / asset->frame_rate * base_framerate + 0.5); 
1366                 else
1367                         return result;
1368         }
1369         else
1370                 return -1;  // infinity
1371 }
1372
1373
1374 int64_t File::get_video_position() 
1375 {
1376 #ifdef USE_FILEFORK
1377         if(file_fork)
1378         {
1379                 FileForker this_is(*forked);
1380                 file_fork->send_command(FileFork::GET_VIDEO_POSITION, 0, 0);
1381                 int64_t result = file_fork->read_result();
1382                 return result;
1383         }
1384 #endif
1385
1386         float base_framerate = -1;
1387         if(base_framerate > 0)
1388                 return (int64_t)((double)current_frame / asset->frame_rate * base_framerate + 0.5);
1389         else
1390                 return current_frame;
1391 }
1392
1393 int64_t File::get_audio_position() 
1394 {
1395 #ifdef USE_FILEFORK
1396         if(file_fork)
1397         {
1398                 FileForker this_is(*forked);
1399                 file_fork->send_command(FileFork::GET_AUDIO_POSITION, 0, 0);
1400                 int64_t result = file_fork->read_result();
1401                 return result;
1402         }
1403 #endif
1404
1405
1406 //      int64_t base_samplerate = -1;
1407 //      if(base_samplerate > 0)
1408 //      {
1409 //              if(normalized_sample_rate == base_samplerate)
1410 //                      return normalized_sample;
1411 //              else
1412 //                      return (int64_t)((double)current_sample / 
1413 //                              asset->sample_rate * 
1414 //                              base_samplerate + 
1415 //                              0.5);
1416 //      }
1417 //      else
1418                 return current_sample;
1419 }
1420
1421
1422
1423 int File::set_audio_position(int64_t position) 
1424 {
1425 #ifdef USE_FILEFORK
1426         if(file_fork)
1427         {
1428                 FileForker this_is(*forked);
1429                 file_fork->send_command(FileFork::SET_AUDIO_POSITION, 
1430                         (unsigned char*)&position, 
1431                         sizeof(position));
1432                 int result = file_fork->read_result();
1433                 return result;
1434         }
1435 #endif
1436
1437         int result = 0;
1438
1439         if(!file) return 1;
1440
1441 #define REPOSITION(x, y) \
1442         (labs((x) - (y)) > 1)
1443
1444         float base_samplerate = asset->sample_rate;
1445                 current_sample = normalized_sample = position;
1446
1447 // printf("File::set_audio_position %d normalized_sample=%ld\n", 
1448 // __LINE__, 
1449 // normalized_sample);
1450                 result = file->set_audio_position(current_sample);
1451
1452                 if(result)
1453                         printf("File::set_audio_position position=" _LD
1454                                 " base_samplerate=%f asset=%p asset->sample_rate=%d\n",
1455                                 position, base_samplerate, asset, asset->sample_rate);
1456 //      }
1457
1458 //printf("File::set_audio_position %d %d %d\n", current_channel, current_sample, position);
1459
1460         return result;
1461 }
1462
1463 int File::set_video_position(int64_t position, 
1464         int is_thread) 
1465 {
1466 #ifdef USE_FILEFORK
1467 // Thread should only call in the fork
1468         if(file_fork && !is_fork && !is_thread)
1469         {
1470                 FileForker this_is(*forked);
1471 //printf("File::set_video_position %d %lld\n", __LINE__, position);
1472                 file_fork->send_command(FileFork::SET_VIDEO_POSITION, (unsigned char*)&position, sizeof(position));
1473                 int result = file_fork->read_result();
1474                 return result;
1475         }
1476 #endif
1477
1478         int result = 0;
1479         if(!file) return 0;
1480
1481 // Convert to file's rate
1482 //      if(base_framerate > 0)
1483 //              position = (int64_t)((double)position / 
1484 //                      base_framerate * 
1485 //                      asset->frame_rate + 
1486 //                      0.5);
1487
1488
1489         if(video_thread && !is_thread)
1490         {
1491 // Call thread.  Thread calls this again to set the file state.
1492                 video_thread->set_video_position(position);
1493         }
1494         else
1495         if(current_frame != position)
1496         {
1497                 if(file)
1498                 {
1499                         current_frame = position;
1500                         result = file->set_video_position(current_frame);
1501                 }
1502         }
1503
1504         return result;
1505 }
1506
1507 // No resampling here.
1508 int File::write_samples(Samples **buffer, int64_t len)
1509 {
1510 #ifdef USE_FILEFORK
1511         if(file_fork)
1512         {
1513                 FileForker this_is(*forked);
1514                 int entry_size = Samples::filefork_size();
1515                 int buffer_size = entry_size * asset->channels + sizeof(int64_t);
1516                 unsigned char fork_buffer[buffer_size];
1517                 for(int i = 0; i < asset->channels; i++)
1518                 {
1519                         buffer[i]->to_filefork(fork_buffer + entry_size * i);
1520                 }
1521
1522                 *(int64_t*)(fork_buffer + 
1523                         entry_size * asset->channels) = len;
1524
1525                 file_fork->send_command(FileFork::WRITE_SAMPLES, 
1526                         fork_buffer, 
1527                         buffer_size);
1528                 int result = file_fork->read_result();
1529                 return result;
1530         }
1531 #endif
1532
1533
1534
1535
1536         int result = 1;
1537
1538         if(file)
1539         {
1540                 write_lock->lock("File::write_samples");
1541
1542 // Convert to arrays for backwards compatability
1543                 double *temp[asset->channels];
1544                 for(int i = 0; i < asset->channels; i++)
1545                 {
1546                         temp[i] = buffer[i]->get_data();
1547                 }
1548
1549                 result = file->write_samples(temp, len);
1550                 current_sample += len;
1551                 normalized_sample += len;
1552                 asset->audio_length += len;
1553                 write_lock->unlock();
1554         }
1555         return result;
1556 }
1557
1558
1559
1560
1561
1562 // Can't put any cmodel abstraction here because the filebase couldn't be
1563 // parallel.
1564 int File::write_frames(VFrame ***frames, int len)
1565 {
1566 //printf("File::write_frames %d\n", __LINE__);
1567 #ifdef USE_FILEFORK
1568         if(file_fork)
1569         {
1570                 FileForker this_is(*forked);
1571 //printf("File::write_frames %d\n", __LINE__);
1572                 int entry_size = frames[0][0]->filefork_size();
1573                 unsigned char fork_buffer[entry_size * asset->layers * len + sizeof(int)];
1574                 for(int i = 0; i < asset->layers; i++)
1575                 {
1576                         for(int j = 0; j < len; j++)
1577                         {
1578 // printf("File::write_frames %d " _LD " %d\n", 
1579 // __LINE__, 
1580 // frames[i][j]->get_number(), 
1581 // frames[i][j]->get_keyframe());
1582                                 frames[i][j]->to_filefork(fork_buffer + 
1583                                         sizeof(int) +
1584                                         entry_size * len * i +
1585                                         entry_size * j);
1586                         }
1587                 }
1588
1589                 
1590 //PRINT_TRACE
1591 // Frames per layer
1592                 int *fbfr = (int *)fork_buffer;
1593                 fbfr[0] = len;
1594 //PRINT_TRACE
1595
1596                 file_fork->send_command(FileFork::WRITE_FRAMES, 
1597                         fork_buffer, 
1598                         sizeof(fork_buffer));
1599 //PRINT_TRACE
1600                 int result = file_fork->read_result();
1601
1602
1603 //printf("File::write_frames %d\n", __LINE__);
1604                 return result;
1605         }
1606
1607
1608 #endif // USE_FILEFORK
1609
1610
1611 //PRINT_TRACE
1612 // Store the counters in temps so the filebase can choose to overwrite them.
1613         int result;
1614         int current_frame_temp = current_frame;
1615         int video_length_temp = asset->video_length;
1616
1617         write_lock->lock("File::write_frames");
1618
1619 //PRINT_TRACE
1620         result = file->write_frames(frames, len);
1621 //PRINT_TRACE
1622
1623         current_frame = current_frame_temp + len;
1624         asset->video_length = video_length_temp + len;
1625         write_lock->unlock();
1626 //PRINT_TRACE
1627         return result;
1628 }
1629
1630 // Only called by FileThread
1631 int File::write_compressed_frame(VFrame *buffer)
1632 {
1633         int result = 0;
1634         write_lock->lock("File::write_compressed_frame");
1635         result = file->write_compressed_frame(buffer);
1636         current_frame++;
1637         asset->video_length++;
1638         write_lock->unlock();
1639         return result;
1640 }
1641
1642
1643 int File::write_audio_buffer(int64_t len)
1644 {
1645 #ifdef USE_FILEFORK
1646         if(file_fork)
1647         {
1648                 FileForker this_is(*forked);
1649                 file_fork->send_command(FileFork::WRITE_AUDIO_BUFFER, (unsigned char*)&len, sizeof(len));
1650                 int result = file_fork->read_result();
1651                 return result;
1652         }
1653 #endif
1654
1655         int result = 0;
1656         if(audio_thread)
1657         {
1658                 result = audio_thread->write_buffer(len);
1659         }
1660         return result;
1661 }
1662
1663 int File::write_video_buffer(int64_t len)
1664 {
1665 #ifdef USE_FILEFORK
1666         if(file_fork)
1667         {
1668                 FileForker this_is(*forked);
1669 // Copy over sequence numbers for background rendering
1670 // frame sizes for direct copy
1671 //printf("File::write_video_buffer %d\n", __LINE__);
1672                 int fork_buffer_size = sizeof(int64_t) +
1673                         VFrame::filefork_size() * asset->layers * len;
1674                 unsigned char fork_buffer[fork_buffer_size];
1675                 int64_t *fbfr = (int64_t *)fork_buffer;
1676                 fbfr[0] = len;
1677
1678                 for(int i = 0; i < asset->layers; i++)
1679                 {
1680                         for(int j = 0; j < len; j++)
1681                         {
1682 // Send memory state
1683                                 current_frame_buffer[i][j]->to_filefork(fork_buffer + 
1684                                         sizeof(int64_t) +
1685                                         VFrame::filefork_size() * (len * i + j));
1686 // printf("File::write_video_buffer %d size=%d %d %02x %02x %02x %02x %02x %02x %02x %02x\n", 
1687 // __LINE__, 
1688 // current_frame_buffer[i][j]->get_shmid(),
1689 // current_frame_buffer[i][j]->get_compressed_size(),
1690 // current_frame_buffer[i][j]->get_data()[0],
1691 // current_frame_buffer[i][j]->get_data()[1],
1692 // current_frame_buffer[i][j]->get_data()[2],
1693 // current_frame_buffer[i][j]->get_data()[3],
1694 // current_frame_buffer[i][j]->get_data()[4],
1695 // current_frame_buffer[i][j]->get_data()[5],
1696 // current_frame_buffer[i][j]->get_data()[6],
1697 // current_frame_buffer[i][j]->get_data()[7]);
1698                         }
1699                 }
1700
1701 //printf("File::write_video_buffer %d\n", __LINE__);
1702                 file_fork->send_command(FileFork::WRITE_VIDEO_BUFFER, 
1703                         fork_buffer, 
1704                         fork_buffer_size);
1705 //printf("File::write_video_buffer %d\n", __LINE__);
1706                 int result = file_fork->read_result();
1707 //printf("File::write_video_buffer %d\n", __LINE__);
1708                 return result;
1709         }
1710 #endif
1711
1712         int result = 0;
1713         if(video_thread)
1714         {
1715                 result = video_thread->write_buffer(len);
1716         }
1717
1718         return result;
1719 }
1720
1721 Samples** File::get_audio_buffer()
1722 {
1723 #ifdef USE_FILEFORK
1724         if(file_fork)
1725         {
1726                 FileForker this_is(*forked);
1727                 file_fork->send_command(FileFork::GET_AUDIO_BUFFER, 0, 0);
1728                 int result = file_fork->read_result();
1729
1730 // Read parameters for a Samples buffer & create it in File
1731 //              delete_temp_samples_buffer();
1732 //              if(!temp_samples_buffer) 
1733 //              {
1734 //                      temp_samples_buffer = new Samples**[ring_buffers];
1735 //                      for(int i = 0; i < ring_buffers; i++) temp_samples_buffer[i] = 0;
1736 //              }
1737 //              
1738 //              
1739 //              temp_samples_buffer  = new Samples*[asset->channels];
1740 //              for(int i = 0; i < asset->channels; i++)
1741 //              {
1742 //                      temp_samples_buffer[i] = new Samples;
1743 //                      temp_samples_buffer[i]->from_filefork(file_fork->result_data + 
1744 //                              i * Samples::filefork_size());
1745 //              }
1746
1747                 return temp_samples_buffer[result];
1748         }
1749 #endif
1750
1751         if(audio_thread) return audio_thread->get_audio_buffer();
1752         return 0;
1753 }
1754
1755 VFrame*** File::get_video_buffer()
1756 {
1757 #ifdef USE_FILEFORK
1758         if(file_fork)
1759         {
1760                 FileForker this_is(*forked);
1761
1762                 file_fork->send_command(FileFork::GET_VIDEO_BUFFER, 0, 0);
1763                 int result = file_fork->read_result();
1764
1765 // Read parameters for a VFrame buffer & create it in File
1766 //              delete_temp_frame_buffer();
1767
1768
1769 //              temp_frame_size = *(int*)(file_fork->result_data + 
1770 //                      file_fork->result_bytes - 
1771 //                      sizeof(int));
1772 // 
1773 // //printf("File::get_video_buffer %d %p %d\n", __LINE__, this, asset->layers);
1774 //              temp_frame_buffer = new VFrame**[asset->layers];
1775 // 
1776 //              for(int i = 0; i < asset->layers; i++)
1777 //              {
1778 // 
1779 //                      temp_frame_buffer[i] = new VFrame*[temp_frame_size];
1780 // 
1781 //                      for(int j = 0; j < temp_frame_size; j++)
1782 //                      {
1783 // 
1784 //                              temp_frame_buffer[i][j] = new VFrame;
1785 // printf("File::get_video_buffer %d %p\n", __LINE__, temp_frame_buffer[i][j]);
1786 // 
1787 //                              temp_frame_buffer[i][j]->from_filefork(file_fork->result_data + 
1788 //                                      i * temp_frame_size * VFrame::filefork_size() +
1789 //                                      j * VFrame::filefork_size());
1790 // 
1791 //                      }
1792 //              }
1793 // 
1794
1795                 current_frame_buffer = temp_frame_buffer[result];
1796
1797                 return current_frame_buffer;
1798         }
1799 #endif
1800
1801         if(video_thread) 
1802         {
1803                 VFrame*** result = video_thread->get_video_buffer();
1804
1805                 return result;
1806         }
1807
1808         return 0;
1809 }
1810
1811
1812 int File::read_samples(Samples *samples, int64_t len)
1813 {
1814 // Never try to read more samples than exist in the file
1815         if (current_sample + len > asset->audio_length) {
1816                 len = asset->audio_length - current_sample;
1817         }
1818         if(len <= 0) return 0;
1819
1820         int result = 0;
1821         const int debug = 0;
1822         if(debug) PRINT_TRACE
1823
1824 #ifdef USE_FILEFORK
1825         if(file_fork)
1826         {
1827                 FileForker this_is(*forked);
1828                 int buffer_bytes = Samples::filefork_size() + sizeof(int64_t);
1829                 unsigned char buffer[buffer_bytes];
1830                 samples->to_filefork(buffer);
1831                 *(int64_t*)(buffer + Samples::filefork_size()) = len;
1832                 if(debug) PRINT_TRACE
1833                 file_fork->send_command(FileFork::READ_SAMPLES, 
1834                         buffer, 
1835                         buffer_bytes);
1836                 if(debug) PRINT_TRACE
1837                 int result = file_fork->read_result();
1838
1839 // Crashed
1840                 if(result && !file_fork->child_running())
1841                 {
1842                         delete file_fork;
1843                         result = open_file(preferences, asset, rd, wr);
1844                 }
1845
1846                 return result;
1847         }
1848 #endif
1849
1850         if(debug) PRINT_TRACE
1851
1852         double *buffer = samples->get_data();
1853
1854         int64_t base_samplerate = asset->sample_rate;
1855
1856         if(file)
1857         {
1858 // Resample recursively calls this with the asset sample rate
1859                 if(base_samplerate == 0) base_samplerate = asset->sample_rate;
1860
1861                 if(debug) PRINT_TRACE
1862                 result = file->read_samples(buffer, len);
1863
1864                 if(debug) PRINT_TRACE
1865                 current_sample += len;
1866
1867                 normalized_sample += len;
1868         }
1869         if(debug) PRINT_TRACE
1870
1871         return result;
1872 }
1873
1874
1875 int File::read_frame(VFrame *frame, int is_thread)
1876 {
1877         const int debug = 0;
1878
1879         if(debug) PRINT_TRACE
1880
1881 #ifdef USE_FILEFORK
1882 // is_thread is only true in the fork
1883         if(file_fork && !is_fork && !is_thread)
1884         {
1885                 FileForker this_is(*forked);
1886                 unsigned char fork_buffer[VFrame::filefork_size()];
1887                 if(debug) PRINT_TRACE
1888
1889                 frame->to_filefork(fork_buffer);
1890                 file_fork->send_command(FileFork::READ_FRAME, 
1891                         fork_buffer, 
1892                         VFrame::filefork_size());
1893
1894                 int result = file_fork->read_result();
1895
1896
1897 // Crashed
1898                 if(result && !file_fork->child_running())
1899                 {
1900                         delete file_fork;
1901                         result = open_file(preferences, asset, rd, wr);
1902                 }
1903                 else
1904                 if(!result && 
1905                         frame->get_color_model() == BC_COMPRESSED)
1906                 {
1907 // Get compressed data from socket
1908 //printf("File::read_frame %d %d\n", __LINE__, file_fork->result_bytes);
1909                         int header_size = sizeof(int) * 2;
1910                         if(file_fork->result_bytes > header_size)
1911                         {
1912 //printf("File::read_frame %d %d\n", __LINE__, file_fork->result_bytes);
1913                                 frame->allocate_compressed_data(file_fork->result_bytes - header_size);
1914                                 frame->set_compressed_size(file_fork->result_bytes - header_size);
1915                                 frame->set_keyframe(*(int*)(file_fork->result_data + sizeof(int)));
1916                                 memcpy(frame->get_data(), 
1917                                         file_fork->result_data + header_size,
1918                                         file_fork->result_bytes - header_size);
1919                         }
1920                         else
1921 // Get compressed data size
1922                         {
1923                                 frame->set_compressed_size(*(int*)file_fork->result_data);
1924                                 frame->set_keyframe(*(int*)(file_fork->result_data + sizeof(int)));
1925 //printf("File::read_frame %d %d\n", __LINE__, *(int*)(file_fork->result_data + sizeof(int)));
1926                         }
1927                 }
1928
1929                 return result;
1930         }
1931 #endif
1932
1933
1934 //printf("File::read_frame %d\n", __LINE__);
1935
1936         if(video_thread && !is_thread) return video_thread->read_frame(frame);
1937
1938 //printf("File::read_frame %d\n", __LINE__);
1939         if(debug) PRINT_TRACE
1940         if(file)
1941         {
1942                 if(debug) PRINT_TRACE
1943                 int supported_colormodel = colormodel_supported(frame->get_color_model());
1944                 int advance_position = 1;
1945
1946 // Test cache
1947                 if(use_cache && !is_fork &&
1948                         frame_cache->get_frame(frame,
1949                                 current_frame,
1950                                 current_layer,
1951                                 asset->frame_rate))
1952                 {
1953 // Can't advance position if cache used.
1954 //printf("File::read_frame %d\n", __LINE__);
1955                         advance_position = 0;
1956                 }
1957                 else
1958 // Need temp
1959                 if(frame->get_color_model() != BC_COMPRESSED &&
1960                         (supported_colormodel != frame->get_color_model() ||
1961                         frame->get_w() != asset->width ||
1962                         frame->get_h() != asset->height))
1963                 {
1964
1965 //                      printf("File::read_frame %d\n", __LINE__);
1966 // Can't advance position here because it needs to be added to cache
1967                         if(temp_frame)
1968                         {
1969                                 if(!temp_frame->params_match(asset->width, asset->height, supported_colormodel))
1970                                 {
1971                                         delete temp_frame;
1972                                         temp_frame = 0;
1973                                 }
1974                         }
1975
1976 //                      printf("File::read_frame %d\n", __LINE__);
1977                         if(!temp_frame)
1978                         {
1979                                 temp_frame = new VFrame(0,
1980                                         -1,
1981                                         asset->width,
1982                                         asset->height,
1983                                         supported_colormodel,
1984                                         -1);
1985                         }
1986
1987 //                      printf("File::read_frame %d\n", __LINE__);
1988                         temp_frame->copy_stacks(frame);
1989                         int result = file->read_frame(temp_frame);
1990                         if( result && frame->get_status() > 0 )
1991                                 frame->set_status(-1);
1992 //for(int i = 0; i < 1000 * 1000; i++) ((float*)temp_frame->get_rows()[0])[i] = 1.0;
1993 // printf("File::read_frame %d %d %d %d %d %d\n", 
1994 // temp_frame->get_color_model(), 
1995 // temp_frame->get_w(),
1996 // temp_frame->get_h(),
1997 // frame->get_color_model(),
1998 // frame->get_w(),
1999 // frame->get_h());
2000                         BC_CModels::transfer(frame->get_rows(), 
2001                                 temp_frame->get_rows(),
2002                                 frame->get_y(),
2003                                 frame->get_u(),
2004                                 frame->get_v(),
2005                                 temp_frame->get_y(),
2006                                 temp_frame->get_u(),
2007                                 temp_frame->get_v(),
2008                                 0, 
2009                                 0, 
2010                                 temp_frame->get_w(), 
2011                                 temp_frame->get_h(),
2012                                 0, 
2013                                 0, 
2014                                 frame->get_w(), 
2015                                 frame->get_h(),
2016                                 temp_frame->get_color_model(), 
2017                                 frame->get_color_model(),
2018                                 0,
2019                                 temp_frame->get_w(),
2020                                 frame->get_w());
2021 //                      printf("File::read_frame %d\n", __LINE__);
2022                 }
2023                 else
2024                 {
2025 // Can't advance position here because it needs to be added to cache
2026 //printf("File::read_frame %d\n", __LINE__);
2027                         int result = file->read_frame(frame);
2028                         if( result && frame->get_status() > 0 )
2029                                 frame->set_status(-1);
2030 //for(int i = 0; i < 100 * 1000; i++) ((float*)frame->get_rows()[0])[i] = 1.0;
2031                 }
2032
2033 //printf("File::read_frame %d use_cache=%d\n", __LINE__, use_cache);
2034                 if(use_cache && !is_fork)
2035                         frame_cache->put_frame(frame,
2036                                 current_frame, current_layer,
2037                                 asset->frame_rate, 1, 0);
2038 //printf("File::read_frame %d\n", __LINE__);
2039
2040                 if(advance_position) current_frame++;
2041                 if(debug) PRINT_TRACE
2042                 return 0;
2043         }
2044         else
2045                 return 1;
2046 }
2047
2048 int File::can_copy_from(Asset *asset, 
2049         int64_t position, 
2050         int output_w, 
2051         int output_h)
2052 {
2053         if(!asset) return 0;
2054
2055 #ifdef USE_FILEFORK
2056         if(file_fork)
2057         {
2058                 FileForker this_is(*forked);
2059                 FileXML xml;
2060                 asset->write(&xml, 1, "");
2061                 xml.terminate_string();
2062                 const char *xml_string = xml.string();
2063                 long xml_length = strlen(xml_string);
2064                 int buffer_size = xml_length + 1 + 
2065                         sizeof(int64_t) +
2066                         sizeof(int) + 
2067                         sizeof(int);
2068                 unsigned char *buffer = new unsigned char[buffer_size];
2069                 *(int64_t*)(buffer) = position;
2070                 *(int*)(buffer + sizeof(int64_t)) = output_w;
2071                 *(int*)(buffer + sizeof(int64_t) + sizeof(int)) = output_h;
2072                 memcpy(buffer + 
2073                         sizeof(int64_t) +
2074                         sizeof(int) + 
2075                         sizeof(int), 
2076                         xml_string, 
2077                         xml_length + 1);
2078
2079                 file_fork->send_command(FileFork::CAN_COPY_FROM, 
2080                         buffer, 
2081                         buffer_size);
2082                 int result = file_fork->read_result();
2083                 return result;
2084         }
2085 #endif
2086
2087
2088         if(file)
2089         {
2090                 return asset->width == output_w &&
2091                         asset->height == output_h &&
2092                         file->can_copy_from(asset, position);
2093         }
2094         else
2095                 return 0;
2096 }
2097
2098 // Fill in queries about formats when adding formats here.
2099
2100
2101 int File::strtoformat(const char *format)
2102 {
2103         return strtoformat(0, format);
2104 }
2105
2106 int File::strtoformat(ArrayList<PluginServer*> *plugindb, const char *format)
2107 {
2108         if(!strcasecmp(format, _(AC3_NAME))) return FILE_AC3;
2109         if(!strcasecmp(format, _(SCENE_NAME))) return FILE_SCENE;
2110         if(!strcasecmp(format, _(WAV_NAME))) return FILE_WAV;
2111         if(!strcasecmp(format, _(PCM_NAME))) return FILE_PCM;
2112         if(!strcasecmp(format, _(AU_NAME))) return FILE_AU;
2113         if(!strcasecmp(format, _(AIFF_NAME))) return FILE_AIFF;
2114         if(!strcasecmp(format, _(SND_NAME))) return FILE_SND;
2115         if(!strcasecmp(format, _(PNG_NAME))) return FILE_PNG;
2116         if(!strcasecmp(format, _(PNG_LIST_NAME))) return FILE_PNG_LIST;
2117         if(!strcasecmp(format, _(TIFF_NAME))) return FILE_TIFF;
2118         if(!strcasecmp(format, _(TIFF_LIST_NAME))) return FILE_TIFF_LIST;
2119         if(!strcasecmp(format, _(JPEG_NAME))) return FILE_JPEG;
2120         if(!strcasecmp(format, _(JPEG_LIST_NAME))) return FILE_JPEG_LIST;
2121         if(!strcasecmp(format, _(EXR_NAME))) return FILE_EXR;
2122         if(!strcasecmp(format, _(EXR_LIST_NAME))) return FILE_EXR_LIST;
2123         if(!strcasecmp(format, _(FLAC_NAME))) return FILE_FLAC;
2124         if(!strcasecmp(format, _(CR2_NAME))) return FILE_CR2;
2125         if(!strcasecmp(format, _(CR2_LIST_NAME))) return FILE_CR2_LIST;
2126         if(!strcasecmp(format, _(MPEG_NAME))) return FILE_MPEG;
2127         if(!strcasecmp(format, _(AMPEG_NAME))) return FILE_AMPEG;
2128         if(!strcasecmp(format, _(VMPEG_NAME))) return FILE_VMPEG;
2129         if(!strcasecmp(format, _(TGA_NAME))) return FILE_TGA;
2130         if(!strcasecmp(format, _(TGA_LIST_NAME))) return FILE_TGA_LIST;
2131         if(!strcasecmp(format, _(OGG_NAME))) return FILE_OGG;
2132         if(!strcasecmp(format, _(VORBIS_NAME))) return FILE_VORBIS;
2133         if(!strcasecmp(format, _(RAWDV_NAME))) return FILE_RAWDV;
2134         if(!strcasecmp(format, _(FFMPEG_NAME))) return FILE_FFMPEG;
2135         if(!strcasecmp(format, _(DBASE_NAME))) return FILE_DB;
2136
2137         return 0;
2138 }
2139
2140
2141 const char* File::formattostr(int format)
2142 {
2143         return formattostr(0, format);
2144 }
2145
2146 const char* File::formattostr(ArrayList<PluginServer*> *plugindb, int format)
2147 {
2148         switch(format)
2149         {
2150                 case FILE_SCENE:        return _(SCENE_NAME);
2151                 case FILE_AC3:          return _(AC3_NAME);
2152                 case FILE_WAV:          return _(WAV_NAME);
2153                 case FILE_PCM:          return _(PCM_NAME);
2154                 case FILE_AU:           return _(AU_NAME);
2155                 case FILE_AIFF:         return _(AIFF_NAME);
2156                 case FILE_SND:          return _(SND_NAME);
2157                 case FILE_PNG:          return _(PNG_NAME);
2158                 case FILE_PNG_LIST:     return _(PNG_LIST_NAME);
2159                 case FILE_JPEG:         return _(JPEG_NAME);
2160                 case FILE_JPEG_LIST:    return _(JPEG_LIST_NAME);
2161                 case FILE_CR2:          return _(CR2_NAME);
2162                 case FILE_CR2_LIST:     return _(CR2_LIST_NAME);
2163                 case FILE_FLAC:         return _(FLAC_NAME);
2164                 case FILE_EXR:          return _(EXR_NAME);
2165                 case FILE_EXR_LIST:     return _(EXR_LIST_NAME);
2166                 case FILE_MPEG:         return _(MPEG_NAME);
2167                 case FILE_AMPEG:        return _(AMPEG_NAME);
2168                 case FILE_VMPEG:        return _(VMPEG_NAME);
2169                 case FILE_TGA:          return _(TGA_NAME);
2170                 case FILE_TGA_LIST:     return _(TGA_LIST_NAME);
2171                 case FILE_TIFF:         return _(TIFF_NAME);
2172                 case FILE_TIFF_LIST:    return _(TIFF_LIST_NAME);
2173                 case FILE_OGG:          return _(OGG_NAME);
2174                 case FILE_VORBIS:       return _(VORBIS_NAME);
2175                 case FILE_RAWDV:        return _(RAWDV_NAME);
2176                 case FILE_FFMPEG:       return _(FFMPEG_NAME);
2177                 case FILE_DB:           return _(DBASE_NAME);
2178         }
2179         return _("Unknown");
2180 }
2181
2182 int File::strtobits(const char *bits)
2183 {
2184         if(!strcasecmp(bits, _(NAME_8BIT))) return BITSLINEAR8;
2185         if(!strcasecmp(bits, _(NAME_16BIT))) return BITSLINEAR16;
2186         if(!strcasecmp(bits, _(NAME_24BIT))) return BITSLINEAR24;
2187         if(!strcasecmp(bits, _(NAME_32BIT))) return BITSLINEAR32;
2188         if(!strcasecmp(bits, _(NAME_ULAW))) return BITSULAW;
2189         if(!strcasecmp(bits, _(NAME_ADPCM))) return BITS_ADPCM;
2190         if(!strcasecmp(bits, _(NAME_FLOAT))) return BITSFLOAT;
2191         return BITSLINEAR16;
2192 }
2193
2194 const char* File::bitstostr(int bits)
2195 {
2196 //printf("File::bitstostr\n");
2197         switch(bits)
2198         {
2199                 case BITSLINEAR8:       return (NAME_8BIT);
2200                 case BITSLINEAR16:      return (NAME_16BIT);
2201                 case BITSLINEAR24:      return (NAME_24BIT);
2202                 case BITSLINEAR32:      return (NAME_32BIT);
2203                 case BITSULAW:          return (NAME_ULAW);
2204                 case BITS_ADPCM:        return (NAME_ADPCM);
2205                 case BITSFLOAT:         return (NAME_FLOAT);
2206         }
2207         return _("Unknown");
2208 }
2209
2210
2211
2212 int File::str_to_byteorder(const char *string)
2213 {
2214         if(!strcasecmp(string, _("Lo Hi"))) return 1;
2215         return 0;
2216 }
2217
2218 const char* File::byteorder_to_str(int byte_order)
2219 {
2220         if(byte_order) return _("Lo Hi");
2221         return _("Hi Lo");
2222 }
2223
2224 int File::bytes_per_sample(int bits)
2225 {
2226         switch(bits)
2227         {
2228                 case BITSLINEAR8:       return 1;
2229                 case BITSLINEAR16:      return 2;
2230                 case BITSLINEAR24:      return 3;
2231                 case BITSLINEAR32:      return 4;
2232                 case BITSULAW:          return 1;
2233         }
2234         return 1;
2235 }
2236
2237
2238
2239
2240
2241 int File::get_best_colormodel(int driver)
2242 {
2243         return get_best_colormodel(asset, driver);
2244 }
2245
2246 int File::get_best_colormodel(Asset *asset, int driver)
2247 {
2248         switch(asset->format)
2249         {
2250                 case FILE_RAWDV:        return FileDV::get_best_colormodel(asset, driver);
2251                 case FILE_MPEG:         return FileMPEG::get_best_colormodel(asset, driver);
2252                 case FILE_JPEG:
2253                 case FILE_JPEG_LIST:    return FileJPEG::get_best_colormodel(asset, driver);
2254                 case FILE_EXR:
2255                 case FILE_EXR_LIST:     return FileEXR::get_best_colormodel(asset, driver);
2256                 case FILE_PNG:
2257                 case FILE_PNG_LIST:     return FilePNG::get_best_colormodel(asset, driver);
2258                 case FILE_TGA:
2259                 case FILE_TGA_LIST:     return FileTGA::get_best_colormodel(asset, driver);
2260                 case FILE_CR2:
2261                 case FILE_CR2_LIST:     return FileCR2::get_best_colormodel(asset, driver);
2262                 case FILE_DB:           return FileDB::get_best_colormodel(asset, driver);
2263         }
2264
2265         return BC_RGB888;
2266 }
2267
2268
2269 int File::colormodel_supported(int colormodel)
2270 {
2271 #ifdef USE_FILEFORK
2272         if(file_fork)
2273         {
2274                 FileForker this_is(*forked);
2275                 unsigned char buffer[sizeof(int)];
2276                 int *ibfr = (int *)buffer;
2277                 ibfr[0] = colormodel;
2278
2279                 file_fork->send_command(FileFork::COLORMODEL_SUPPORTED, 
2280                         buffer, 
2281                         sizeof(int));
2282                 int result = file_fork->read_result();
2283                 return result;
2284         }
2285 #endif
2286
2287
2288         if(file)
2289                 return file->colormodel_supported(colormodel);
2290
2291         return BC_RGB888;
2292 }
2293
2294
2295 int64_t File::file_memory_usage()
2296 {
2297         return file ? file->base_memory_usage() : 0;
2298 }
2299
2300 int64_t File::get_memory_usage() 
2301 {
2302         int64_t result = 0;
2303
2304 #ifdef USE_FILEFORK
2305         if(file_fork)
2306         {
2307                 FileForker this_is(*forked);
2308                 file_fork->send_command(FileFork::FILE_MEMORY_USAGE, 0, 0);
2309                 result = file_fork->read_result();
2310         }
2311         else
2312 #endif
2313         result += file_memory_usage();
2314         if(temp_frame) result += temp_frame->get_data_size();
2315         result += frame_cache->get_memory_usage();
2316         if(video_thread) result += video_thread->get_memory_usage();
2317
2318         if(result < MIN_CACHEITEM_SIZE) result = MIN_CACHEITEM_SIZE;
2319         return result;
2320 }
2321
2322
2323 int File::supports_video(ArrayList<PluginServer*> *plugindb, char *format)
2324 {
2325         int format_i = strtoformat(plugindb, format);
2326         
2327         return supports_video(format_i);
2328         return 0;
2329 }
2330
2331 int File::supports_audio(ArrayList<PluginServer*> *plugindb, char *format)
2332 {
2333         int format_i = strtoformat(plugindb, format);
2334
2335         return supports_audio(format_i);
2336         return 0;
2337 }
2338
2339
2340 int File::supports_video(int format)
2341 {
2342 //printf("File::supports_video %d\n", format);
2343         switch(format)
2344         {
2345                 case FILE_OGG:
2346                 case FILE_JPEG:
2347                 case FILE_JPEG_LIST:
2348                 case FILE_CR2:
2349                 case FILE_CR2_LIST:
2350                 case FILE_EXR:
2351                 case FILE_EXR_LIST:
2352                 case FILE_PNG:
2353                 case FILE_PNG_LIST:
2354                 case FILE_TGA:
2355                 case FILE_TGA_LIST:
2356                 case FILE_TIFF:
2357                 case FILE_TIFF_LIST:
2358                 case FILE_VMPEG:
2359                 case FILE_FFMPEG:
2360                 case FILE_RAWDV:
2361                         return 1;
2362         }
2363         return 0;
2364 }
2365
2366 int File::supports_audio(int format)
2367 {
2368         switch(format)
2369         {
2370                 case FILE_AC3:
2371                 case FILE_FLAC:
2372                 case FILE_PCM:
2373                 case FILE_WAV:
2374                 case FILE_OGG:
2375                 case FILE_VORBIS:
2376                 case FILE_AMPEG:
2377                 case FILE_AU:
2378                 case FILE_AIFF:
2379                 case FILE_SND:
2380                 case FILE_FFMPEG:
2381                         return 1;
2382         }
2383         return 0;
2384 }
2385
2386 const char* File::get_tag(int format)
2387 {
2388         switch(format)
2389         {
2390                 case FILE_AC3:          return "ac3";
2391                 case FILE_AIFF:         return "aif";
2392                 case FILE_AMPEG:        return "mp3";
2393                 case FILE_AU:           return "au";
2394                 case FILE_RAWDV:        return "dv";
2395                 case FILE_DB:           return "db";
2396                 case FILE_EXR:          return "exr";
2397                 case FILE_EXR_LIST:     return "exr";
2398                 case FILE_FLAC:         return "flac";
2399                 case FILE_JPEG:         return "jpg";
2400                 case FILE_JPEG_LIST:    return "jpg";
2401                 case FILE_OGG:          return "ogg";
2402                 case FILE_PCM:          return "pcm";
2403                 case FILE_PNG:          return "png";
2404                 case FILE_PNG_LIST:     return "png";
2405                 case FILE_TGA:          return "tga";
2406                 case FILE_TGA_LIST:     return "tga";
2407                 case FILE_TIFF:         return "tif";
2408                 case FILE_TIFF_LIST:    return "tif";
2409                 case FILE_VMPEG:        return "m2v";
2410                 case FILE_VORBIS:       return "ogg";
2411                 case FILE_WAV:          return "wav";
2412                 case FILE_FFMPEG:       return "ffmpg";
2413         }
2414         return 0;
2415 }
2416
2417 const char* File::get_prefix(int format)
2418 {
2419         switch(format) {
2420         case FILE_PCM:          return "PCM";
2421         case FILE_WAV:          return "WAV";
2422         case FILE_PNG:          return "PNG";
2423         case FILE_JPEG:         return "JPEG";
2424         case FILE_TIFF:         return "TIFF";
2425         case FILE_GIF:          return "GIF";
2426         case FILE_JPEG_LIST:    return "JPEG_LIST";
2427         case FILE_AU:           return "AU";
2428         case FILE_AIFF:         return "AIFF";
2429         case FILE_SND:          return "SND";
2430         case FILE_TGA_LIST:     return "TGA_LIST";
2431         case FILE_TGA:          return "TGA";
2432         case FILE_MPEG:         return "MPEG";
2433         case FILE_AMPEG:        return "AMPEG";
2434         case FILE_VMPEG:        return "VMPEG";
2435         case FILE_RAWDV:        return "RAWDV";
2436         case FILE_TIFF_LIST:    return "TIFF_LIST";
2437         case FILE_PNG_LIST:     return "PNG_LIST";
2438         case FILE_AC3:          return "AC3";
2439         case FILE_EXR:          return "EXR";
2440         case FILE_EXR_LIST:     return "EXR_LIST";
2441         case FILE_CR2:          return "CR2";
2442         case FILE_OGG:          return "OGG";
2443         case FILE_VORBIS:       return "VORBIS";
2444         case FILE_FLAC:         return "FLAC";
2445         case FILE_FFMPEG:       return "FFMPEG";
2446         case FILE_SCENE:        return "SCENE";
2447         case FILE_CR2_LIST:     return "CR2_LIST";
2448         case FILE_GIF_LIST:     return "GIF_LIST";
2449         case FILE_DB:           return "DB";
2450         }
2451         return _("UNKNOWN");
2452 }
2453
2454
2455 PackagingEngine *File::new_packaging_engine(Asset *asset)
2456 {
2457         PackagingEngine *result;
2458         switch (asset->format)
2459         {
2460                 case FILE_OGG:
2461                         result = (PackagingEngine*)new PackagingEngineOGG();
2462                         break;
2463                 default:
2464                         result = (PackagingEngine*) new PackagingEngineDefault();
2465                         break;
2466         }
2467
2468         return result;
2469 }
2470
2471
2472 int File::record_fd()
2473 {
2474         return file ? file->record_fd() : -1;
2475 }
2476
2477
2478 void get_exe_path(char *result)
2479 {
2480 // Get executable path
2481         pid_t pid = getpid();
2482         char proc_path[BCTEXTLEN];
2483         int len = 0;
2484         result[0] = 0;
2485         sprintf(proc_path, "/proc/%d/exe", pid);
2486         if((len = readlink(proc_path, result, BCTEXTLEN)) >= 0)
2487         {
2488                 result[len] = 0;
2489 //printf("Preferences::Preferences %d %s\n", __LINE__, result);
2490                 char *ptr = strrchr(result, '/');
2491                 if(ptr) *ptr = 0;
2492         }
2493
2494 }
2495
2496