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