initial commit
[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                 file = 0;
799         }
800
801
802
803 // Set extra writing parameters to mandatory settings.
804         if(file && wr) {
805                 if(this->asset->dither) file->set_dither();
806         }
807
808
809
810 // Synchronize header parameters
811         if(file) {
812                 asset->copy_from(this->asset, 1);
813 //asset->dump();
814         }
815
816         if(debug) printf("File::open_file %d file=%p\n", __LINE__, file);
817 // sleep(1);
818
819         return file ? FILE_OK : FILE_NOT_FOUND;
820 }
821
822 void File::delete_temp_samples_buffer()
823 {
824
825         if(temp_samples_buffer) {
826                 for(int j = 0; j < audio_ring_buffers; j++) {
827                         for(int i = 0; i < asset->channels; i++) {
828                                 delete temp_samples_buffer[j][i];
829                         }
830                         delete [] temp_samples_buffer[j];
831                 }
832
833                 delete [] temp_samples_buffer;
834                 temp_samples_buffer = 0;
835                 audio_ring_buffers = 0;
836         }
837 }
838
839 void File::delete_temp_frame_buffer()
840 {
841         
842         if(temp_frame_buffer) {
843                 for(int k = 0; k < video_ring_buffers; k++) {
844                         for(int i = 0; i < asset->layers; i++) {
845                                 for(int j = 0; j < video_buffer_size; j++) {
846                                         delete temp_frame_buffer[k][i][j];
847                                 }
848                                 delete [] temp_frame_buffer[k][i];
849                         }
850                         delete [] temp_frame_buffer[k];
851                 }
852
853                 delete [] temp_frame_buffer;
854                 temp_frame_buffer = 0;
855                 video_ring_buffers = 0;
856                 video_buffer_size = 0;
857         }
858 }
859
860 int File::close_file(int ignore_thread)
861 {
862         const int debug = 0;
863
864 #ifdef USE_FILEFORK
865         if(debug) printf("File::close_file file=%p file_fork=%p %d\n", file, file_fork, __LINE__);
866
867         if(file_fork) {
868                 FileForker this_is(*forked);
869                 file_fork->send_command(FileFork::CLOSE_FILE, 0, 0);
870                 file_fork->read_result();
871
872                 if(asset && wr) {
873                         asset->audio_length = current_sample = *(int64_t*)file_fork->result_data;
874                         asset->video_length = current_frame = *(int64_t*)(file_fork->result_data + sizeof(int64_t));
875                 }
876
877                 if(debug) printf("File::close_file:%d current_sample=" _LD " current_frame=" _LD "\n", 
878                         __LINE__,
879                         current_sample,
880                         current_frame);
881
882                 delete file_fork;
883                 file_fork = 0;
884         }
885 #endif
886
887         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
888
889         if(!ignore_thread) {
890                 stop_audio_thread();
891                 stop_video_thread();
892         }
893
894
895         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
896         if(file) {
897 // The file's asset is a copy of the argument passed to open_file so the
898 // user must copy lengths from the file's asset.
899                 if(asset && wr) {
900                         asset->audio_length = current_sample;
901                         asset->video_length = current_frame;
902                 }
903
904                 file->close_file();
905                 delete file;
906         }
907         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
908
909         delete_temp_samples_buffer();
910         delete_temp_frame_buffer();
911         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
912
913         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
914
915         reset_parameters();
916         if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
917         return 0;
918 }
919
920
921
922 int File::get_index(char *index_path)
923 {
924 #ifdef USE_FILEFORK
925         if(file_fork) {
926                 FileForker this_is(*forked);
927                 file_fork->send_command(FileFork::GET_INDEX, (unsigned char*)index_path, strlen(index_path) + 1);
928                 int result = file_fork->read_result();
929                 return result;
930         }
931 #endif
932
933         if(file) {
934                 return file->get_index(index_path);
935         }
936         return 1;
937 }
938
939
940
941 int File::start_audio_thread(int buffer_size, int ring_buffers)
942 {
943         this->audio_ring_buffers = ring_buffers;
944
945 #ifdef USE_FILEFORK
946         if(file_fork)
947         {
948                 FileForker this_is(*forked);
949                 unsigned char buffer[sizeof(int) * 2];
950                 int *ibfr = (int *)buffer;
951                 ibfr[0] = buffer_size;
952                 ibfr[1] = audio_ring_buffers;
953                 file_fork->send_command(FileFork::START_AUDIO_THREAD, buffer, sizeof(buffer));
954                 int result = file_fork->read_result();
955
956
957 //printf("File::start_audio_thread %d file_fork->result_data=%p\n", __LINE__, file_fork->result_data);
958 // Create server copy of buffer
959                 delete_temp_samples_buffer();
960 //printf("File::start_audio_thread %d\n", __LINE__);
961                 temp_samples_buffer = new Samples**[audio_ring_buffers];
962 //printf("File::start_audio_thread %d\n", __LINE__);
963                 for(int i = 0; i < audio_ring_buffers; i++)
964                 {
965 //printf("File::start_audio_thread %d\n", __LINE__);
966                         temp_samples_buffer[i] = new Samples*[asset->channels];
967 //printf("File::start_audio_thread %d\n", __LINE__);
968                         for(int j = 0; j < asset->channels; j++)
969                         {
970                                 int offset = i * Samples::filefork_size() * asset->channels +
971                                         j * Samples::filefork_size();
972 //printf("File::start_audio_thread %d j=%d offset=%d\n", __LINE__, j, offset);
973                                 temp_samples_buffer[i][j] = new Samples;
974                                 temp_samples_buffer[i][j]->from_filefork(
975                                         file_fork->result_data +
976                                         offset);
977 //printf("File::start_audio_thread %d\n", __LINE__);
978                         }
979                 }
980                 
981                 return result;
982         }
983 #endif
984
985         
986         if(!audio_thread)
987         {
988                 audio_thread = new FileThread(this, 1, 0);
989                 audio_thread->start_writing(buffer_size, 0, ring_buffers, 0);
990         }
991         return 0;
992 }
993
994 int File::start_video_thread(int buffer_size, 
995         int color_model, 
996         int ring_buffers, 
997         int compressed)
998 {
999         this->video_ring_buffers = ring_buffers;
1000         this->video_buffer_size = buffer_size;
1001
1002 #ifdef USE_FILEFORK
1003         if(file_fork)
1004         {
1005                 FileForker this_is(*forked);
1006 // This resets variables
1007                 delete_temp_frame_buffer();
1008
1009                 this->video_ring_buffers = ring_buffers;
1010                 this->video_buffer_size = buffer_size;
1011
1012                 unsigned char buffer[sizeof(int) * 4];
1013                 int *ibfr = (int *)buffer;
1014                 ibfr[0] = buffer_size;
1015                 ibfr[1] = color_model;
1016                 ibfr[2] = video_ring_buffers;
1017                 ibfr[3] = compressed;
1018 // Buffers are allocated
1019                 file_fork->send_command(FileFork::START_VIDEO_THREAD, 
1020                         buffer, 
1021                         sizeof(buffer));
1022                 int result = file_fork->read_result();
1023
1024
1025 // Create server copy of buffer
1026 //printf("File::start_video_thread %d %d\n", __LINE__, video_ring_buffers);
1027                 temp_frame_buffer = new VFrame***[video_ring_buffers];
1028                 for(int i = 0; i < video_ring_buffers; i++)
1029                 {
1030                         temp_frame_buffer[i] = new VFrame**[asset->layers];
1031                         for(int j = 0; j < asset->layers; j++)
1032                         {
1033                                 temp_frame_buffer[i][j] = new VFrame*[video_buffer_size];
1034 //printf("File::start_video_thread %d %p\n", __LINE__, temp_frame_buffer[i][j]);
1035                                 for(int k = 0; k < video_buffer_size; k++)
1036                                 {
1037                                         temp_frame_buffer[i][j][k] = new VFrame;
1038                                         temp_frame_buffer[i][j][k]->from_filefork(file_fork->result_data + 
1039                                                 i * asset->layers * video_buffer_size * VFrame::filefork_size() + 
1040                                                 j * video_buffer_size * VFrame::filefork_size() +
1041                                                 k * VFrame::filefork_size());
1042                                 }
1043                         }
1044                 }
1045
1046
1047                 return result;
1048         }
1049 #endif
1050
1051
1052
1053         if(!video_thread)
1054         {
1055                 video_thread = new FileThread(this, 0, 1);
1056                 video_thread->start_writing(buffer_size, 
1057                         color_model, 
1058                         ring_buffers, 
1059                         compressed);
1060         }
1061         return 0;
1062 }
1063
1064 int File::start_video_decode_thread()
1065 {
1066 #ifdef USE_FILEFORK
1067         if(file_fork)
1068         {
1069                 FileForker this_is(*forked);
1070                 file_fork->send_command(FileFork::START_VIDEO_DECODE_THREAD, 0, 0);
1071                 file_fork->read_result();
1072                 return 0;
1073         }
1074 #endif
1075
1076
1077 // Currently, CR2 is the only one which won't work asynchronously, so
1078 // we're not using a virtual function yet.
1079         if(!video_thread /* && asset->format != FILE_CR2 */)
1080         {
1081                 video_thread = new FileThread(this, 0, 1);
1082                 video_thread->start_reading();
1083                 use_cache = 0;
1084         }
1085         return 0;
1086 }
1087
1088 int File::stop_audio_thread()
1089 {
1090 #ifdef USE_FILEFORK
1091         if(file_fork)
1092         {
1093                 file_fork->send_command(FileFork::STOP_AUDIO_THREAD, 0, 0);
1094                 file_fork->read_result();
1095                 return 0;
1096         }
1097 #endif
1098
1099         if(audio_thread)
1100         {
1101                 audio_thread->stop_writing();
1102                 delete audio_thread;
1103                 audio_thread = 0;
1104         }
1105         return 0;
1106 }
1107
1108 int File::stop_video_thread()
1109 {
1110 #ifdef USE_FILEFORK
1111         if(file_fork)
1112         {
1113                 FileForker this_is(*forked);
1114                 file_fork->send_command(FileFork::STOP_VIDEO_THREAD, 0, 0);
1115                 file_fork->read_result();
1116                 return 0;
1117         }
1118 #endif
1119
1120         if(video_thread)
1121         {
1122                 video_thread->stop_reading();
1123                 video_thread->stop_writing();
1124                 delete video_thread;
1125                 video_thread = 0;
1126         }
1127         return 0;
1128 }
1129
1130 FileThread* File::get_video_thread()
1131 {
1132         return video_thread;
1133 }
1134
1135 int File::set_channel(int channel) 
1136 {
1137 #ifdef USE_FILEFORK
1138         if(file_fork)
1139         {
1140                 FileForker this_is(*forked);
1141 // Set it locally for get_channel
1142                 current_channel = channel;
1143                 file_fork->send_command(FileFork::SET_CHANNEL, (unsigned char*)&channel, sizeof(channel));
1144                 int result = file_fork->read_result();
1145                 return result;
1146         }
1147 #endif
1148
1149         if(file && channel < asset->channels)
1150         {
1151                 current_channel = channel;
1152                 return 0;
1153         }
1154         else
1155                 return 1;
1156 }
1157
1158 int File::get_channel()
1159 {
1160         return current_channel;
1161 }
1162
1163 // if no>=0, sets new program
1164 //  returns current program
1165 int File::set_program(int no)
1166 {
1167 #ifdef USE_FILEFORK
1168         if(file_fork)
1169         {
1170                 FileForker this_is(*forked);
1171                 file_fork->send_command(FileFork::SET_PROGRAM, (unsigned char*)&no, sizeof(no));
1172                 int result = file_fork->read_result();
1173                 current_program = no < 0 ? result : no;
1174                 return result;
1175         }
1176 #endif
1177         int result = file ? file->set_program(no) : current_program;
1178         current_program = no < 0 ? result : no;
1179         return result;
1180 }
1181
1182 int File::get_cell_time(int no, double &time)
1183 {
1184 #ifdef USE_FILEFORK
1185         if(file_fork)
1186         {
1187                 FileForker this_is(*forked);
1188                 file_fork->send_command(FileFork::GET_CELL_TIME, (unsigned char*)&no, sizeof(no));
1189                 int result = file_fork->read_result();
1190                 time = *(double *)file_fork->result_data;
1191                 return result;
1192         }
1193 #endif
1194
1195         return file ? file->get_cell_time(no, time) : -1;
1196 }
1197
1198 int File::get_system_time(int64_t &tm)
1199 {
1200 #ifdef USE_FILEFORK
1201         if(file_fork)
1202         {
1203                 FileForker this_is(*forked);
1204                 file_fork->send_command(FileFork::GET_STT_TIME, 0, 0);
1205                 int result = file_fork->read_result();
1206                 tm = *(int64_t *)file_fork->result_data;
1207                 return result;
1208         }
1209 #endif
1210
1211         return file ? file->get_system_time(tm) : -1;
1212 }
1213
1214 int File::get_audio_for_video(int vstream, int astream, int64_t &channel_mask)
1215 {
1216 #ifdef USE_FILEFORK
1217         if(file_fork)
1218         {
1219                 FileForker this_is(*forked);
1220                 unsigned char buffer[2*sizeof(int)];
1221                 int offset = 0;
1222                 *(int*)(buffer + offset) = vstream;
1223                 offset += sizeof(int);
1224                 *(int*)(buffer + offset) = astream;
1225                 file_fork->send_command(FileFork::GET_AUDIO4VIDEO, buffer, sizeof(buffer));
1226                 int result = file_fork->read_result();
1227                 channel_mask = *(int64_t *)file_fork->result_data;
1228                 return result;
1229         }
1230 #endif
1231
1232         return file ? file->get_audio_for_video(vstream, astream, channel_mask) : -1;
1233 }
1234
1235 int File::get_video_pid(int track)
1236 {
1237 #ifdef USE_FILEFORK
1238         if(file_fork)
1239         {
1240                 FileForker this_is(*forked);
1241                 file_fork->send_command(FileFork::GET_VIDEO_PID,
1242                                 (unsigned char*)&track, sizeof(track));
1243                 int result = file_fork->read_result();
1244                 return result;
1245         }
1246 #endif
1247
1248         return file ? file->get_video_pid(track) : -1;
1249 }
1250
1251
1252
1253 int File::get_video_info(int track, int &pid, double &framerate,
1254                 int &width, int &height, char *title)
1255 {
1256 #ifdef USE_FILEFORK
1257         if(file_fork)
1258         {
1259                 FileForker this_is(*forked);
1260                 file_fork->send_command(FileFork::GET_VIDEO_INFO,
1261                                 (unsigned char*)&track, sizeof(track));
1262                 int result = file_fork->read_result();
1263                 if( !result ) {
1264                         unsigned char *bp = file_fork->result_data;
1265                         framerate = *(double*)bp;  bp += sizeof(framerate);
1266                         pid       = *(int *)  bp;  bp += sizeof(pid);
1267                         width     = *(int *)  bp;  bp += sizeof(width);
1268                         height    = *(int *)  bp;  bp += sizeof(height);
1269                         strcpy(title, (char *)bp);
1270                 }
1271                 return result;
1272         }
1273 #endif
1274
1275         return !file ? -1 :
1276                  file->get_video_info(track, pid, framerate, width, height, title);
1277 }
1278
1279 int File::select_video_stream(Asset *asset, int vstream)
1280 {
1281 #ifdef USE_FILEFORK
1282         if(file_fork)
1283         {
1284                 FileForker this_is(*forked);
1285                 file_fork->send_command(FileFork::SELECT_VIDEO_STREAM,
1286                                 (unsigned char*)&vstream, sizeof(vstream));
1287                 int result = file_fork->read_result();
1288                 if( !result ) {
1289                         unsigned char *bp = file_fork->result_data;
1290                         asset->frame_rate    = *(double*)  bp;  bp += sizeof(asset->frame_rate);
1291                         asset->video_length = *(int64_t *) bp;  bp += sizeof(asset->video_length);
1292                         asset->width        = *(int *)     bp;  bp += sizeof(asset->width);
1293                         asset->height       = *(int *)     bp;  bp += sizeof(asset->height);
1294                 }
1295         }
1296 #endif
1297         return !file ? -1 :
1298                  file->select_video_stream(asset, vstream);
1299 }
1300
1301 int File::select_audio_stream(Asset *asset, int astream)
1302 {
1303 #ifdef USE_FILEFORK
1304         if(file_fork)
1305         {
1306                 FileForker this_is(*forked);
1307                 file_fork->send_command(FileFork::SELECT_AUDIO_STREAM,
1308                                 (unsigned char*)&astream, sizeof(astream));
1309                 int result = file_fork->read_result();
1310                 if( !result ) {
1311                         unsigned char *bp = file_fork->result_data;
1312                         asset->audio_length = *(int64_t *) bp;  bp += sizeof(asset->audio_length);
1313                         asset->sample_rate  = *(int *)     bp;  bp += sizeof(asset->sample_rate);
1314                 }
1315         }
1316 #endif
1317         return !file ? -1 :
1318                  file->select_audio_stream(asset, astream);
1319 }
1320
1321
1322 int File::get_thumbnail(int stream,
1323         int64_t &position, unsigned char *&thumbnail, int &ww, int &hh)
1324 {
1325         return file->get_thumbnail(stream, position, thumbnail, ww, hh);
1326 }
1327
1328 int File::set_skimming(int track, int skim, skim_fn fn, void *vp)
1329 {
1330         return file->set_skimming(track, skim, fn, vp);
1331 }
1332
1333 int File::skim_video(int track, void *vp, skim_fn fn)
1334 {
1335         return file->skim_video(track, vp, fn);
1336 }
1337
1338
1339 int File::set_layer(int layer, int is_thread) 
1340 {
1341 #ifdef USE_FILEFORK
1342 // thread should only call in the fork
1343         if(file_fork && !is_fork && !is_thread)
1344         {
1345                 FileForker this_is(*forked);
1346                 file_fork->send_command(FileFork::SET_LAYER, (unsigned char*)&layer, sizeof(layer));
1347                 int result = file_fork->read_result();
1348                 current_layer = layer;
1349                 return result;
1350         }
1351 #endif
1352
1353         if(file && layer < asset->layers)
1354         {
1355                 if(!is_thread && video_thread)
1356                 {
1357                         video_thread->set_layer(layer);
1358                 }
1359                 else
1360                 {
1361                         current_layer = layer;
1362                 }
1363                 return 0; 
1364         }
1365         else
1366                 return 1;
1367 }
1368
1369 int64_t File::get_audio_length()
1370 {
1371 #ifdef USE_FILEFORK
1372         if(file_fork)
1373         {
1374                 FileForker this_is(*forked);
1375                 file_fork->send_command(FileFork::GET_AUDIO_LENGTH, 0, 0);
1376                 int64_t result = file_fork->read_result();
1377                 return result;
1378         }
1379 #endif
1380
1381         int64_t result = asset->audio_length;
1382         int64_t base_samplerate = -1;
1383         if(result > 0)
1384         {
1385                 if(base_samplerate > 0)
1386                         return (int64_t)((double)result / asset->sample_rate * base_samplerate + 0.5);
1387                 else
1388                         return result;
1389         }
1390         else
1391                 return -1;
1392 }
1393
1394 int64_t File::get_video_length()
1395
1396 #ifdef USE_FILEFORK
1397         if(file_fork)
1398         {
1399                 FileForker this_is(*forked);
1400                 file_fork->send_command(FileFork::GET_VIDEO_LENGTH, 0, 0);
1401                 int64_t result = file_fork->read_result();
1402                 return result;
1403         }
1404 #endif
1405
1406
1407         int64_t result = asset->video_length;
1408         float base_framerate = -1;
1409         if(result > 0)
1410         {
1411                 if(base_framerate > 0)
1412                         return (int64_t)((double)result / asset->frame_rate * base_framerate + 0.5); 
1413                 else
1414                         return result;
1415         }
1416         else
1417                 return -1;  // infinity
1418 }
1419
1420
1421 int64_t File::get_video_position() 
1422 {
1423 #ifdef USE_FILEFORK
1424         if(file_fork)
1425         {
1426                 FileForker this_is(*forked);
1427                 file_fork->send_command(FileFork::GET_VIDEO_POSITION, 0, 0);
1428                 int64_t result = file_fork->read_result();
1429                 return result;
1430         }
1431 #endif
1432
1433         float base_framerate = -1;
1434         if(base_framerate > 0)
1435                 return (int64_t)((double)current_frame / asset->frame_rate * base_framerate + 0.5);
1436         else
1437                 return current_frame;
1438 }
1439
1440 int64_t File::get_audio_position() 
1441 {
1442 #ifdef USE_FILEFORK
1443         if(file_fork)
1444         {
1445                 FileForker this_is(*forked);
1446                 file_fork->send_command(FileFork::GET_AUDIO_POSITION, 0, 0);
1447                 int64_t result = file_fork->read_result();
1448                 return result;
1449         }
1450 #endif
1451
1452
1453 //      int64_t base_samplerate = -1;
1454 //      if(base_samplerate > 0)
1455 //      {
1456 //              if(normalized_sample_rate == base_samplerate)
1457 //                      return normalized_sample;
1458 //              else
1459 //                      return (int64_t)((double)current_sample / 
1460 //                              asset->sample_rate * 
1461 //                              base_samplerate + 
1462 //                              0.5);
1463 //      }
1464 //      else
1465                 return current_sample;
1466 }
1467
1468
1469
1470 int File::set_audio_position(int64_t position) 
1471 {
1472 #ifdef USE_FILEFORK
1473         if(file_fork)
1474         {
1475                 FileForker this_is(*forked);
1476                 file_fork->send_command(FileFork::SET_AUDIO_POSITION, 
1477                         (unsigned char*)&position, 
1478                         sizeof(position));
1479                 int result = file_fork->read_result();
1480                 return result;
1481         }
1482 #endif
1483
1484         int result = 0;
1485
1486         if(!file) return 1;
1487
1488 #define REPOSITION(x, y) \
1489         (labs((x) - (y)) > 1)
1490
1491         float base_samplerate = asset->sample_rate;
1492                 current_sample = normalized_sample = position;
1493
1494 // printf("File::set_audio_position %d normalized_sample=%ld\n", 
1495 // __LINE__, 
1496 // normalized_sample);
1497                 result = file->set_audio_position(current_sample);
1498
1499                 if(result)
1500                         printf("File::set_audio_position position=" _LD
1501                                 " base_samplerate=%f asset=%p asset->sample_rate=%d\n",
1502                                 position, base_samplerate, asset, asset->sample_rate);
1503 //      }
1504
1505 //printf("File::set_audio_position %d %d %d\n", current_channel, current_sample, position);
1506
1507         return result;
1508 }
1509
1510 int File::set_video_position(int64_t position, 
1511         int is_thread) 
1512 {
1513 #ifdef USE_FILEFORK
1514 // Thread should only call in the fork
1515         if(file_fork && !is_fork && !is_thread)
1516         {
1517                 FileForker this_is(*forked);
1518 //printf("File::set_video_position %d %lld\n", __LINE__, position);
1519                 file_fork->send_command(FileFork::SET_VIDEO_POSITION, (unsigned char*)&position, sizeof(position));
1520                 int result = file_fork->read_result();
1521                 return result;
1522         }
1523 #endif
1524
1525         int result = 0;
1526         if(!file) return 0;
1527
1528 // Convert to file's rate
1529 //      if(base_framerate > 0)
1530 //              position = (int64_t)((double)position / 
1531 //                      base_framerate * 
1532 //                      asset->frame_rate + 
1533 //                      0.5);
1534
1535
1536         if(video_thread && !is_thread)
1537         {
1538 // Call thread.  Thread calls this again to set the file state.
1539                 video_thread->set_video_position(position);
1540         }
1541         else
1542         if(current_frame != position)
1543         {
1544                 if(file)
1545                 {
1546                         current_frame = position;
1547                         result = file->set_video_position(current_frame);
1548                 }
1549         }
1550
1551         return result;
1552 }
1553
1554 // No resampling here.
1555 int File::write_samples(Samples **buffer, int64_t len)
1556 {
1557 #ifdef USE_FILEFORK
1558         if(file_fork)
1559         {
1560                 FileForker this_is(*forked);
1561                 int entry_size = Samples::filefork_size();
1562                 int buffer_size = entry_size * asset->channels + sizeof(int64_t);
1563                 unsigned char fork_buffer[buffer_size];
1564                 for(int i = 0; i < asset->channels; i++)
1565                 {
1566                         buffer[i]->to_filefork(fork_buffer + entry_size * i);
1567                 }
1568
1569                 *(int64_t*)(fork_buffer + 
1570                         entry_size * asset->channels) = len;
1571
1572                 file_fork->send_command(FileFork::WRITE_SAMPLES, 
1573                         fork_buffer, 
1574                         buffer_size);
1575                 int result = file_fork->read_result();
1576                 return result;
1577         }
1578 #endif
1579
1580
1581
1582
1583         int result = 1;
1584
1585         if(file)
1586         {
1587                 write_lock->lock("File::write_samples");
1588
1589 // Convert to arrays for backwards compatability
1590                 double *temp[asset->channels];
1591                 for(int i = 0; i < asset->channels; i++)
1592                 {
1593                         temp[i] = buffer[i]->get_data();
1594                 }
1595
1596                 result = file->write_samples(temp, len);
1597                 current_sample += len;
1598                 normalized_sample += len;
1599                 asset->audio_length += len;
1600                 write_lock->unlock();
1601         }
1602         return result;
1603 }
1604
1605
1606
1607
1608
1609 // Can't put any cmodel abstraction here because the filebase couldn't be
1610 // parallel.
1611 int File::write_frames(VFrame ***frames, int len)
1612 {
1613 //printf("File::write_frames %d\n", __LINE__);
1614 #ifdef USE_FILEFORK
1615         if(file_fork)
1616         {
1617                 FileForker this_is(*forked);
1618 //printf("File::write_frames %d\n", __LINE__);
1619                 int entry_size = frames[0][0]->filefork_size();
1620                 unsigned char fork_buffer[entry_size * asset->layers * len + sizeof(int)];
1621                 for(int i = 0; i < asset->layers; i++)
1622                 {
1623                         for(int j = 0; j < len; j++)
1624                         {
1625 // printf("File::write_frames %d " _LD " %d\n", 
1626 // __LINE__, 
1627 // frames[i][j]->get_number(), 
1628 // frames[i][j]->get_keyframe());
1629                                 frames[i][j]->to_filefork(fork_buffer + 
1630                                         sizeof(int) +
1631                                         entry_size * len * i +
1632                                         entry_size * j);
1633                         }
1634                 }
1635
1636                 
1637 //PRINT_TRACE
1638 // Frames per layer
1639                 int *fbfr = (int *)fork_buffer;
1640                 fbfr[0] = len;
1641 //PRINT_TRACE
1642
1643                 file_fork->send_command(FileFork::WRITE_FRAMES, 
1644                         fork_buffer, 
1645                         sizeof(fork_buffer));
1646 //PRINT_TRACE
1647                 int result = file_fork->read_result();
1648
1649
1650 //printf("File::write_frames %d\n", __LINE__);
1651                 return result;
1652         }
1653
1654
1655 #endif // USE_FILEFORK
1656
1657
1658 //PRINT_TRACE
1659 // Store the counters in temps so the filebase can choose to overwrite them.
1660         int result;
1661         int current_frame_temp = current_frame;
1662         int video_length_temp = asset->video_length;
1663
1664         write_lock->lock("File::write_frames");
1665
1666 //PRINT_TRACE
1667         result = file->write_frames(frames, len);
1668 //PRINT_TRACE
1669
1670         current_frame = current_frame_temp + len;
1671         asset->video_length = video_length_temp + len;
1672         write_lock->unlock();
1673 //PRINT_TRACE
1674         return result;
1675 }
1676
1677 // Only called by FileThread
1678 int File::write_compressed_frame(VFrame *buffer)
1679 {
1680         int result = 0;
1681         write_lock->lock("File::write_compressed_frame");
1682         result = file->write_compressed_frame(buffer);
1683         current_frame++;
1684         asset->video_length++;
1685         write_lock->unlock();
1686         return result;
1687 }
1688
1689
1690 int File::write_audio_buffer(int64_t len)
1691 {
1692 #ifdef USE_FILEFORK
1693         if(file_fork)
1694         {
1695                 FileForker this_is(*forked);
1696                 file_fork->send_command(FileFork::WRITE_AUDIO_BUFFER, (unsigned char*)&len, sizeof(len));
1697                 int result = file_fork->read_result();
1698                 return result;
1699         }
1700 #endif
1701
1702         int result = 0;
1703         if(audio_thread)
1704         {
1705                 result = audio_thread->write_buffer(len);
1706         }
1707         return result;
1708 }
1709
1710 int File::write_video_buffer(int64_t len)
1711 {
1712 #ifdef USE_FILEFORK
1713         if(file_fork)
1714         {
1715                 FileForker this_is(*forked);
1716 // Copy over sequence numbers for background rendering
1717 // frame sizes for direct copy
1718 //printf("File::write_video_buffer %d\n", __LINE__);
1719                 int fork_buffer_size = sizeof(int64_t) +
1720                         VFrame::filefork_size() * asset->layers * len;
1721                 unsigned char fork_buffer[fork_buffer_size];
1722                 int64_t *fbfr = (int64_t *)fork_buffer;
1723                 fbfr[0] = len;
1724
1725                 for(int i = 0; i < asset->layers; i++)
1726                 {
1727                         for(int j = 0; j < len; j++)
1728                         {
1729 // Send memory state
1730                                 current_frame_buffer[i][j]->to_filefork(fork_buffer + 
1731                                         sizeof(int64_t) +
1732                                         VFrame::filefork_size() * (len * i + j));
1733 // printf("File::write_video_buffer %d size=%d %d %02x %02x %02x %02x %02x %02x %02x %02x\n", 
1734 // __LINE__, 
1735 // current_frame_buffer[i][j]->get_shmid(),
1736 // current_frame_buffer[i][j]->get_compressed_size(),
1737 // current_frame_buffer[i][j]->get_data()[0],
1738 // current_frame_buffer[i][j]->get_data()[1],
1739 // current_frame_buffer[i][j]->get_data()[2],
1740 // current_frame_buffer[i][j]->get_data()[3],
1741 // current_frame_buffer[i][j]->get_data()[4],
1742 // current_frame_buffer[i][j]->get_data()[5],
1743 // current_frame_buffer[i][j]->get_data()[6],
1744 // current_frame_buffer[i][j]->get_data()[7]);
1745                         }
1746                 }
1747
1748 //printf("File::write_video_buffer %d\n", __LINE__);
1749                 file_fork->send_command(FileFork::WRITE_VIDEO_BUFFER, 
1750                         fork_buffer, 
1751                         fork_buffer_size);
1752 //printf("File::write_video_buffer %d\n", __LINE__);
1753                 int result = file_fork->read_result();
1754 //printf("File::write_video_buffer %d\n", __LINE__);
1755                 return result;
1756         }
1757 #endif
1758
1759         int result = 0;
1760         if(video_thread)
1761         {
1762                 result = video_thread->write_buffer(len);
1763         }
1764
1765         return result;
1766 }
1767
1768 Samples** File::get_audio_buffer()
1769 {
1770 #ifdef USE_FILEFORK
1771         if(file_fork)
1772         {
1773                 FileForker this_is(*forked);
1774                 file_fork->send_command(FileFork::GET_AUDIO_BUFFER, 0, 0);
1775                 int result = file_fork->read_result();
1776
1777 // Read parameters for a Samples buffer & create it in File
1778 //              delete_temp_samples_buffer();
1779 //              if(!temp_samples_buffer) 
1780 //              {
1781 //                      temp_samples_buffer = new Samples**[ring_buffers];
1782 //                      for(int i = 0; i < ring_buffers; i++) temp_samples_buffer[i] = 0;
1783 //              }
1784 //              
1785 //              
1786 //              temp_samples_buffer  = new Samples*[asset->channels];
1787 //              for(int i = 0; i < asset->channels; i++)
1788 //              {
1789 //                      temp_samples_buffer[i] = new Samples;
1790 //                      temp_samples_buffer[i]->from_filefork(file_fork->result_data + 
1791 //                              i * Samples::filefork_size());
1792 //              }
1793
1794                 return temp_samples_buffer[result];
1795         }
1796 #endif
1797
1798         if(audio_thread) return audio_thread->get_audio_buffer();
1799         return 0;
1800 }
1801
1802 VFrame*** File::get_video_buffer()
1803 {
1804 #ifdef USE_FILEFORK
1805         if(file_fork)
1806         {
1807                 FileForker this_is(*forked);
1808
1809                 file_fork->send_command(FileFork::GET_VIDEO_BUFFER, 0, 0);
1810                 int result = file_fork->read_result();
1811
1812 // Read parameters for a VFrame buffer & create it in File
1813 //              delete_temp_frame_buffer();
1814
1815
1816 //              temp_frame_size = *(int*)(file_fork->result_data + 
1817 //                      file_fork->result_bytes - 
1818 //                      sizeof(int));
1819 // 
1820 // //printf("File::get_video_buffer %d %p %d\n", __LINE__, this, asset->layers);
1821 //              temp_frame_buffer = new VFrame**[asset->layers];
1822 // 
1823 //              for(int i = 0; i < asset->layers; i++)
1824 //              {
1825 // 
1826 //                      temp_frame_buffer[i] = new VFrame*[temp_frame_size];
1827 // 
1828 //                      for(int j = 0; j < temp_frame_size; j++)
1829 //                      {
1830 // 
1831 //                              temp_frame_buffer[i][j] = new VFrame;
1832 // printf("File::get_video_buffer %d %p\n", __LINE__, temp_frame_buffer[i][j]);
1833 // 
1834 //                              temp_frame_buffer[i][j]->from_filefork(file_fork->result_data + 
1835 //                                      i * temp_frame_size * VFrame::filefork_size() +
1836 //                                      j * VFrame::filefork_size());
1837 // 
1838 //                      }
1839 //              }
1840 // 
1841
1842                 current_frame_buffer = temp_frame_buffer[result];
1843
1844                 return current_frame_buffer;
1845         }
1846 #endif
1847
1848         if(video_thread) 
1849         {
1850                 VFrame*** result = video_thread->get_video_buffer();
1851
1852                 return result;
1853         }
1854
1855         return 0;
1856 }
1857
1858
1859 int File::read_samples(Samples *samples, int64_t len)
1860 {
1861 // Never try to read more samples than exist in the file
1862         if (current_sample + len > asset->audio_length) {
1863                 len = asset->audio_length - current_sample;
1864         }
1865         if(len <= 0) return 0;
1866
1867         int result = 0;
1868         const int debug = 0;
1869         if(debug) PRINT_TRACE
1870
1871 #ifdef USE_FILEFORK
1872         if(file_fork)
1873         {
1874                 FileForker this_is(*forked);
1875                 int buffer_bytes = Samples::filefork_size() + sizeof(int64_t);
1876                 unsigned char buffer[buffer_bytes];
1877                 samples->to_filefork(buffer);
1878                 *(int64_t*)(buffer + Samples::filefork_size()) = len;
1879                 if(debug) PRINT_TRACE
1880                 file_fork->send_command(FileFork::READ_SAMPLES, 
1881                         buffer, 
1882                         buffer_bytes);
1883                 if(debug) PRINT_TRACE
1884                 int result = file_fork->read_result();
1885
1886 // Crashed
1887                 if(result && !file_fork->child_running())
1888                 {
1889                         delete file_fork;
1890                         result = open_file(preferences, asset, rd, wr);
1891                 }
1892
1893                 return result;
1894         }
1895 #endif
1896
1897         if(debug) PRINT_TRACE
1898
1899         double *buffer = samples->get_data();
1900
1901         int64_t base_samplerate = asset->sample_rate;
1902
1903         if(file)
1904         {
1905 // Resample recursively calls this with the asset sample rate
1906                 if(base_samplerate == 0) base_samplerate = asset->sample_rate;
1907
1908                 if(debug) PRINT_TRACE
1909                 result = file->read_samples(buffer, len);
1910
1911                 if(debug) PRINT_TRACE
1912                 current_sample += len;
1913
1914                 normalized_sample += len;
1915         }
1916         if(debug) PRINT_TRACE
1917
1918         return result;
1919 }
1920
1921
1922 int File::read_frame(VFrame *frame, int is_thread)
1923 {
1924         const int debug = 0;
1925
1926         if(debug) PRINT_TRACE
1927
1928 #ifdef USE_FILEFORK
1929 // is_thread is only true in the fork
1930         if(file_fork && !is_fork && !is_thread)
1931         {
1932                 FileForker this_is(*forked);
1933                 unsigned char fork_buffer[VFrame::filefork_size()];
1934                 if(debug) PRINT_TRACE
1935
1936                 frame->to_filefork(fork_buffer);
1937                 file_fork->send_command(FileFork::READ_FRAME, 
1938                         fork_buffer, 
1939                         VFrame::filefork_size());
1940
1941                 int result = file_fork->read_result();
1942
1943
1944 // Crashed
1945                 if(result && !file_fork->child_running())
1946                 {
1947                         delete file_fork;
1948                         result = open_file(preferences, asset, rd, wr);
1949                 }
1950                 else
1951                 if(!result && 
1952                         frame->get_color_model() == BC_COMPRESSED)
1953                 {
1954 // Get compressed data from socket
1955 //printf("File::read_frame %d %d\n", __LINE__, file_fork->result_bytes);
1956                         int header_size = sizeof(int) * 2;
1957                         if(file_fork->result_bytes > header_size)
1958                         {
1959 //printf("File::read_frame %d %d\n", __LINE__, file_fork->result_bytes);
1960                                 frame->allocate_compressed_data(file_fork->result_bytes - header_size);
1961                                 frame->set_compressed_size(file_fork->result_bytes - header_size);
1962                                 frame->set_keyframe(*(int*)(file_fork->result_data + sizeof(int)));
1963                                 memcpy(frame->get_data(), 
1964                                         file_fork->result_data + header_size,
1965                                         file_fork->result_bytes - header_size);
1966                         }
1967                         else
1968 // Get compressed data size
1969                         {
1970                                 frame->set_compressed_size(*(int*)file_fork->result_data);
1971                                 frame->set_keyframe(*(int*)(file_fork->result_data + sizeof(int)));
1972 //printf("File::read_frame %d %d\n", __LINE__, *(int*)(file_fork->result_data + sizeof(int)));
1973                         }
1974                 }
1975
1976                 return result;
1977         }
1978 #endif
1979
1980
1981 //printf("File::read_frame %d\n", __LINE__);
1982
1983         if(video_thread && !is_thread) return video_thread->read_frame(frame);
1984
1985 //printf("File::read_frame %d\n", __LINE__);
1986         if(debug) PRINT_TRACE
1987         if(file)
1988         {
1989                 if(debug) PRINT_TRACE
1990                 int supported_colormodel = colormodel_supported(frame->get_color_model());
1991                 int advance_position = 1;
1992
1993 // Test cache
1994                 if(use_cache && !is_fork &&
1995                         frame_cache->get_frame(frame,
1996                                 current_frame,
1997                                 current_layer,
1998                                 asset->frame_rate))
1999                 {
2000 // Can't advance position if cache used.
2001 //printf("File::read_frame %d\n", __LINE__);
2002                         advance_position = 0;
2003                 }
2004                 else
2005 // Need temp
2006                 if(frame->get_color_model() != BC_COMPRESSED &&
2007                         (supported_colormodel != frame->get_color_model() ||
2008                         frame->get_w() != asset->width ||
2009                         frame->get_h() != asset->height))
2010                 {
2011
2012 //                      printf("File::read_frame %d\n", __LINE__);
2013 // Can't advance position here because it needs to be added to cache
2014                         if(temp_frame)
2015                         {
2016                                 if(!temp_frame->params_match(asset->width, asset->height, supported_colormodel))
2017                                 {
2018                                         delete temp_frame;
2019                                         temp_frame = 0;
2020                                 }
2021                         }
2022
2023 //                      printf("File::read_frame %d\n", __LINE__);
2024                         if(!temp_frame)
2025                         {
2026                                 temp_frame = new VFrame(0,
2027                                         -1,
2028                                         asset->width,
2029                                         asset->height,
2030                                         supported_colormodel,
2031                                         -1);
2032                         }
2033
2034 //                      printf("File::read_frame %d\n", __LINE__);
2035                         temp_frame->copy_stacks(frame);
2036                         file->read_frame(temp_frame);
2037 //for(int i = 0; i < 1000 * 1000; i++) ((float*)temp_frame->get_rows()[0])[i] = 1.0;
2038 // printf("File::read_frame %d %d %d %d %d %d\n", 
2039 // temp_frame->get_color_model(), 
2040 // temp_frame->get_w(),
2041 // temp_frame->get_h(),
2042 // frame->get_color_model(),
2043 // frame->get_w(),
2044 // frame->get_h());
2045                         BC_CModels::transfer(frame->get_rows(), 
2046                                 temp_frame->get_rows(),
2047                                 frame->get_y(),
2048                                 frame->get_u(),
2049                                 frame->get_v(),
2050                                 temp_frame->get_y(),
2051                                 temp_frame->get_u(),
2052                                 temp_frame->get_v(),
2053                                 0, 
2054                                 0, 
2055                                 temp_frame->get_w(), 
2056                                 temp_frame->get_h(),
2057                                 0, 
2058                                 0, 
2059                                 frame->get_w(), 
2060                                 frame->get_h(),
2061                                 temp_frame->get_color_model(), 
2062                                 frame->get_color_model(),
2063                                 0,
2064                                 temp_frame->get_w(),
2065                                 frame->get_w());
2066 //                      printf("File::read_frame %d\n", __LINE__);
2067                 }
2068                 else
2069                 {
2070 // Can't advance position here because it needs to be added to cache
2071 //printf("File::read_frame %d\n", __LINE__);
2072                         file->read_frame(frame);
2073 //for(int i = 0; i < 100 * 1000; i++) ((float*)frame->get_rows()[0])[i] = 1.0;
2074                 }
2075
2076 //printf("File::read_frame %d use_cache=%d\n", __LINE__, use_cache);
2077                 if(use_cache && !is_fork)
2078                         frame_cache->put_frame(frame,
2079                                 current_frame, current_layer,
2080                                 asset->frame_rate, 1, 0);
2081 //printf("File::read_frame %d\n", __LINE__);
2082
2083                 if(advance_position) current_frame++;
2084                 if(debug) PRINT_TRACE
2085                 return 0;
2086         }
2087         else
2088                 return 1;
2089 }
2090
2091 int File::can_copy_from(Asset *asset, 
2092         int64_t position, 
2093         int output_w, 
2094         int output_h)
2095 {
2096         if(!asset) return 0;
2097
2098 #ifdef USE_FILEFORK
2099         if(file_fork)
2100         {
2101                 FileForker this_is(*forked);
2102                 FileXML xml;
2103                 asset->write(&xml, 1, "");
2104                 xml.terminate_string();
2105                 const char *xml_string = xml.string();
2106                 long xml_length = strlen(xml_string);
2107                 int buffer_size = xml_length + 1 + 
2108                         sizeof(int64_t) +
2109                         sizeof(int) + 
2110                         sizeof(int);
2111                 unsigned char *buffer = new unsigned char[buffer_size];
2112                 *(int64_t*)(buffer) = position;
2113                 *(int*)(buffer + sizeof(int64_t)) = output_w;
2114                 *(int*)(buffer + sizeof(int64_t) + sizeof(int)) = output_h;
2115                 memcpy(buffer + 
2116                         sizeof(int64_t) +
2117                         sizeof(int) + 
2118                         sizeof(int), 
2119                         xml_string, 
2120                         xml_length + 1);
2121
2122                 file_fork->send_command(FileFork::CAN_COPY_FROM, 
2123                         buffer, 
2124                         buffer_size);
2125                 int result = file_fork->read_result();
2126                 return result;
2127         }
2128 #endif
2129
2130
2131         if(file)
2132         {
2133                 return asset->width == output_w &&
2134                         asset->height == output_h &&
2135                         file->can_copy_from(asset, position);
2136         }
2137         else
2138                 return 0;
2139 }
2140
2141 // Fill in queries about formats when adding formats here.
2142
2143
2144 int File::strtoformat(const char *format)
2145 {
2146         return strtoformat(0, format);
2147 }
2148
2149 int File::strtoformat(ArrayList<PluginServer*> *plugindb, const char *format)
2150 {
2151         if(!strcasecmp(format, _(AC3_NAME))) return FILE_AC3;
2152         if(!strcasecmp(format, _(SCENE_NAME))) return FILE_SCENE;
2153         if(!strcasecmp(format, _(WAV_NAME))) return FILE_WAV;
2154         if(!strcasecmp(format, _(PCM_NAME))) return FILE_PCM;
2155         if(!strcasecmp(format, _(AU_NAME))) return FILE_AU;
2156         if(!strcasecmp(format, _(AIFF_NAME))) return FILE_AIFF;
2157         if(!strcasecmp(format, _(SND_NAME))) return FILE_SND;
2158         if(!strcasecmp(format, _(PNG_NAME))) return FILE_PNG;
2159         if(!strcasecmp(format, _(PNG_LIST_NAME))) return FILE_PNG_LIST;
2160         if(!strcasecmp(format, _(TIFF_NAME))) return FILE_TIFF;
2161         if(!strcasecmp(format, _(TIFF_LIST_NAME))) return FILE_TIFF_LIST;
2162         if(!strcasecmp(format, _(JPEG_NAME))) return FILE_JPEG;
2163         if(!strcasecmp(format, _(JPEG_LIST_NAME))) return FILE_JPEG_LIST;
2164         if(!strcasecmp(format, _(EXR_NAME))) return FILE_EXR;
2165         if(!strcasecmp(format, _(EXR_LIST_NAME))) return FILE_EXR_LIST;
2166         if(!strcasecmp(format, _(FLAC_NAME))) return FILE_FLAC;
2167         if(!strcasecmp(format, _(CR2_NAME))) return FILE_CR2;
2168         if(!strcasecmp(format, _(CR2_LIST_NAME))) return FILE_CR2_LIST;
2169         if(!strcasecmp(format, _(MPEG_NAME))) return FILE_MPEG;
2170         if(!strcasecmp(format, _(AMPEG_NAME))) return FILE_AMPEG;
2171         if(!strcasecmp(format, _(VMPEG_NAME))) return FILE_VMPEG;
2172         if(!strcasecmp(format, _(TGA_NAME))) return FILE_TGA;
2173         if(!strcasecmp(format, _(TGA_LIST_NAME))) return FILE_TGA_LIST;
2174         if(!strcasecmp(format, _(MOV_NAME))) return FILE_MOV;
2175         if(!strcasecmp(format, _(AVI_NAME))) return FILE_AVI;
2176         if(!strcasecmp(format, _(AVI_LAVTOOLS_NAME))) return FILE_AVI_LAVTOOLS;
2177         if(!strcasecmp(format, _(AVI_ARNE2_NAME))) return FILE_AVI_ARNE2;
2178         if(!strcasecmp(format, _(AVI_ARNE1_NAME))) return FILE_AVI_ARNE1;
2179         if(!strcasecmp(format, _(AVI_AVIFILE_NAME))) return FILE_AVI_AVIFILE;
2180         if(!strcasecmp(format, _(OGG_NAME))) return FILE_OGG;
2181         if(!strcasecmp(format, _(VORBIS_NAME))) return FILE_VORBIS;
2182         if(!strcasecmp(format, _(RAWDV_NAME))) return FILE_RAWDV;
2183         if(!strcasecmp(format, _(FFMPEG_NAME))) return FILE_FFMPEG;
2184         if(!strcasecmp(format, _(DBASE_NAME))) return FILE_DB;
2185
2186         return 0;
2187 }
2188
2189
2190 const char* File::formattostr(int format)
2191 {
2192         return formattostr(0, format);
2193 }
2194
2195 const char* File::formattostr(ArrayList<PluginServer*> *plugindb, int format)
2196 {
2197         switch(format)
2198         {
2199                 case FILE_SCENE:        return _(SCENE_NAME);
2200                 case FILE_AC3:          return _(AC3_NAME);
2201                 case FILE_WAV:          return _(WAV_NAME);
2202                 case FILE_PCM:          return _(PCM_NAME);
2203                 case FILE_AU:           return _(AU_NAME);
2204                 case FILE_AIFF:         return _(AIFF_NAME);
2205                 case FILE_SND:          return _(SND_NAME);
2206                 case FILE_PNG:          return _(PNG_NAME);
2207                 case FILE_PNG_LIST:     return _(PNG_LIST_NAME);
2208                 case FILE_JPEG:         return _(JPEG_NAME);
2209                 case FILE_JPEG_LIST:    return _(JPEG_LIST_NAME);
2210                 case FILE_CR2:          return _(CR2_NAME);
2211                 case FILE_CR2_LIST:     return _(CR2_LIST_NAME);
2212                 case FILE_FLAC:         return _(FLAC_NAME);
2213                 case FILE_EXR:          return _(EXR_NAME);
2214                 case FILE_EXR_LIST:     return _(EXR_LIST_NAME);
2215                 case FILE_MPEG:         return _(MPEG_NAME);
2216                 case FILE_AMPEG:        return _(AMPEG_NAME);
2217                 case FILE_VMPEG:        return _(VMPEG_NAME);
2218                 case FILE_TGA:          return _(TGA_NAME);
2219                 case FILE_TGA_LIST:     return _(TGA_LIST_NAME);
2220                 case FILE_TIFF:         return _(TIFF_NAME);
2221                 case FILE_TIFF_LIST:    return _(TIFF_LIST_NAME);
2222                 case FILE_MOV:          return _(MOV_NAME);
2223                 case FILE_AVI_LAVTOOLS: return _(AVI_LAVTOOLS_NAME);
2224                 case FILE_AVI:          return _(AVI_NAME);
2225                 case FILE_AVI_ARNE2:    return _(AVI_ARNE2_NAME);
2226                 case FILE_AVI_ARNE1:    return _(AVI_ARNE1_NAME);
2227                 case FILE_AVI_AVIFILE:  return _(AVI_AVIFILE_NAME);
2228                 case FILE_OGG:          return _(OGG_NAME);
2229                 case FILE_VORBIS:       return _(VORBIS_NAME);
2230                 case FILE_RAWDV:        return _(RAWDV_NAME);
2231                 case FILE_FFMPEG:       return _(FFMPEG_NAME);
2232                 case FILE_DB:           return _(DBASE_NAME);
2233         }
2234         return "Unknown";
2235 }
2236
2237 int File::strtobits(const char *bits)
2238 {
2239         if(!strcasecmp(bits, _(NAME_8BIT))) return BITSLINEAR8;
2240         if(!strcasecmp(bits, _(NAME_16BIT))) return BITSLINEAR16;
2241         if(!strcasecmp(bits, _(NAME_24BIT))) return BITSLINEAR24;
2242         if(!strcasecmp(bits, _(NAME_32BIT))) return BITSLINEAR32;
2243         if(!strcasecmp(bits, _(NAME_ULAW))) return BITSULAW;
2244         if(!strcasecmp(bits, _(NAME_ADPCM))) return BITS_ADPCM;
2245         if(!strcasecmp(bits, _(NAME_FLOAT))) return BITSFLOAT;
2246         if(!strcasecmp(bits, _(NAME_IMA4))) return BITSIMA4;
2247         return BITSLINEAR16;
2248 }
2249
2250 const char* File::bitstostr(int bits)
2251 {
2252 //printf("File::bitstostr\n");
2253         switch(bits)
2254         {
2255                 case BITSLINEAR8:       return (NAME_8BIT);
2256                 case BITSLINEAR16:      return (NAME_16BIT);
2257                 case BITSLINEAR24:      return (NAME_24BIT);
2258                 case BITSLINEAR32:      return (NAME_32BIT);
2259                 case BITSULAW:          return (NAME_ULAW);
2260                 case BITS_ADPCM:        return (NAME_ADPCM);
2261                 case BITSFLOAT:         return (NAME_FLOAT);
2262                 case BITSIMA4:          return (NAME_IMA4);
2263         }
2264         return "Unknown";
2265 }
2266
2267
2268
2269 int File::str_to_byteorder(const char *string)
2270 {
2271         if(!strcasecmp(string, _("Lo Hi"))) return 1;
2272         return 0;
2273 }
2274
2275 const char* File::byteorder_to_str(int byte_order)
2276 {
2277         if(byte_order) return _("Lo Hi");
2278         return _("Hi Lo");
2279 }
2280
2281 int File::bytes_per_sample(int bits)
2282 {
2283         switch(bits)
2284         {
2285                 case BITSLINEAR8:       return 1;
2286                 case BITSLINEAR16:      return 2;
2287                 case BITSLINEAR24:      return 3;
2288                 case BITSLINEAR32:      return 4;
2289                 case BITSULAW:          return 1;
2290                 case BITSIMA4:          return 1;
2291         }
2292         return 1;
2293 }
2294
2295
2296
2297
2298
2299 int File::get_best_colormodel(int driver)
2300 {
2301         return get_best_colormodel(asset, driver);
2302 }
2303
2304 int File::get_best_colormodel(Asset *asset, int driver)
2305 {
2306         switch(asset->format)
2307         {
2308                 case FILE_RAWDV:        return FileDV::get_best_colormodel(asset, driver);
2309                 case FILE_MOV:          return FileMOV::get_best_colormodel(asset, driver);
2310                 case FILE_AVI:          return FileMOV::get_best_colormodel(asset, driver);
2311                 case FILE_MPEG:         return FileMPEG::get_best_colormodel(asset, driver);
2312                 case FILE_JPEG:
2313                 case FILE_JPEG_LIST:    return FileJPEG::get_best_colormodel(asset, driver);
2314                 case FILE_EXR:
2315                 case FILE_EXR_LIST:     return FileEXR::get_best_colormodel(asset, driver);
2316                 case FILE_PNG:
2317                 case FILE_PNG_LIST:     return FilePNG::get_best_colormodel(asset, driver);
2318                 case FILE_TGA:
2319                 case FILE_TGA_LIST:     return FileTGA::get_best_colormodel(asset, driver);
2320                 case FILE_CR2:
2321                 case FILE_CR2_LIST:     return FileCR2::get_best_colormodel(asset, driver);
2322                 case FILE_DB:           return FileDB::get_best_colormodel(asset, driver);
2323         }
2324
2325         return BC_RGB888;
2326 }
2327
2328
2329 int File::colormodel_supported(int colormodel)
2330 {
2331 #ifdef USE_FILEFORK
2332         if(file_fork)
2333         {
2334                 FileForker this_is(*forked);
2335                 unsigned char buffer[sizeof(int)];
2336                 int *ibfr = (int *)buffer;
2337                 ibfr[0] = colormodel;
2338
2339                 file_fork->send_command(FileFork::COLORMODEL_SUPPORTED, 
2340                         buffer, 
2341                         sizeof(int));
2342                 int result = file_fork->read_result();
2343                 return result;
2344         }
2345 #endif
2346
2347
2348         if(file)
2349                 return file->colormodel_supported(colormodel);
2350
2351         return BC_RGB888;
2352 }
2353
2354
2355 int64_t File::file_memory_usage()
2356 {
2357         return file ? file->base_memory_usage() : 0;
2358 }
2359
2360 int64_t File::get_memory_usage() 
2361 {
2362         int64_t result = 0;
2363
2364 #ifdef USE_FILEFORK
2365         if(file_fork)
2366         {
2367                 FileForker this_is(*forked);
2368                 file_fork->send_command(FileFork::FILE_MEMORY_USAGE, 0, 0);
2369                 result = file_fork->read_result();
2370         }
2371         else
2372 #endif
2373         result += file_memory_usage();
2374         if(temp_frame) result += temp_frame->get_data_size();
2375         result += frame_cache->get_memory_usage();
2376         if(video_thread) result += video_thread->get_memory_usage();
2377
2378         if(result < MIN_CACHEITEM_SIZE) result = MIN_CACHEITEM_SIZE;
2379         return result;
2380 }
2381
2382
2383 int File::supports_video(ArrayList<PluginServer*> *plugindb, char *format)
2384 {
2385         int format_i = strtoformat(plugindb, format);
2386         
2387         return supports_video(format_i);
2388         return 0;
2389 }
2390
2391 int File::supports_audio(ArrayList<PluginServer*> *plugindb, char *format)
2392 {
2393         int format_i = strtoformat(plugindb, format);
2394
2395         return supports_audio(format_i);
2396         return 0;
2397 }
2398
2399
2400 int File::supports_video(int format)
2401 {
2402 //printf("File::supports_video %d\n", format);
2403         switch(format)
2404         {
2405                 case FILE_OGG:
2406                 case FILE_MOV:
2407                 case FILE_JPEG:
2408                 case FILE_JPEG_LIST:
2409                 case FILE_CR2:
2410                 case FILE_CR2_LIST:
2411                 case FILE_EXR:
2412                 case FILE_EXR_LIST:
2413                 case FILE_PNG:
2414                 case FILE_PNG_LIST:
2415                 case FILE_TGA:
2416                 case FILE_TGA_LIST:
2417                 case FILE_TIFF:
2418                 case FILE_TIFF_LIST:
2419                 case FILE_VMPEG:
2420                 case FILE_AVI_LAVTOOLS:
2421                 case FILE_AVI_ARNE2:
2422                 case FILE_AVI:
2423                 case FILE_AVI_ARNE1:
2424                 case FILE_AVI_AVIFILE:
2425                 case FILE_FFMPEG:
2426                 case FILE_RAWDV:
2427                         return 1;
2428         }
2429         return 0;
2430 }
2431
2432 int File::supports_audio(int format)
2433 {
2434         switch(format)
2435         {
2436                 case FILE_AC3:
2437                 case FILE_FLAC:
2438                 case FILE_PCM:
2439                 case FILE_WAV:
2440                 case FILE_MOV:
2441                 case FILE_OGG:
2442                 case FILE_VORBIS:
2443                 case FILE_AMPEG:
2444                 case FILE_AU:
2445                 case FILE_AIFF:
2446                 case FILE_SND:
2447                 case FILE_AVI:
2448                 case FILE_AVI_LAVTOOLS:
2449                 case FILE_AVI_ARNE2:
2450                 case FILE_AVI_ARNE1:
2451                 case FILE_AVI_AVIFILE:
2452                 case FILE_FFMPEG:
2453                         return 1;
2454         }
2455         return 0;
2456 }
2457
2458 const char* File::get_tag(int format)
2459 {
2460         switch(format)
2461         {
2462                 case FILE_AC3:          return "ac3";
2463                 case FILE_AIFF:         return "aif";
2464                 case FILE_AMPEG:        return "mp3";
2465                 case FILE_AU:           return "au";
2466                 case FILE_AVI:          return "avi";
2467                 case FILE_RAWDV:        return "dv";
2468                 case FILE_DB:           return "db";
2469                 case FILE_EXR:          return "exr";
2470                 case FILE_EXR_LIST:     return "exr";
2471                 case FILE_FLAC:         return "flac";
2472                 case FILE_JPEG:         return "jpg";
2473                 case FILE_JPEG_LIST:    return "jpg";
2474                 case FILE_MOV:          return "mov/mp4";
2475                 case FILE_OGG:          return "ogg";
2476                 case FILE_PCM:          return "pcm";
2477                 case FILE_PNG:          return "png";
2478                 case FILE_PNG_LIST:     return "png";
2479                 case FILE_TGA:          return "tga";
2480                 case FILE_TGA_LIST:     return "tga";
2481                 case FILE_TIFF:         return "tif";
2482                 case FILE_TIFF_LIST:    return "tif";
2483                 case FILE_VMPEG:        return "m2v";
2484                 case FILE_VORBIS:       return "ogg";
2485                 case FILE_WAV:          return "wav";
2486                 case FILE_FFMPEG:       return "media";
2487         }
2488         return 0;
2489 }
2490
2491 const char* File::get_prefix(int format)
2492 {
2493         switch(format) {
2494         case FILE_PCM:          return "PCM";
2495         case FILE_WAV:          return "WAV";
2496         case FILE_MOV:          return "MOV";
2497         case FILE_PNG:          return "PNG";
2498         case FILE_JPEG:         return "JPEG";
2499         case FILE_TIFF:         return "TIFF";
2500         case FILE_GIF:          return "GIF";
2501         case FILE_JPEG_LIST:    return "JPEG_LIST";
2502         case FILE_AU:           return "AU";
2503         case FILE_AIFF:         return "AIFF";
2504         case FILE_SND:          return "SND";
2505         case FILE_AVI_LAVTOOLS: return "AVI_LAVTOOLS";
2506         case FILE_TGA_LIST:     return "TGA_LIST";
2507         case FILE_TGA:          return "TGA";
2508         case FILE_MPEG:         return "MPEG";
2509         case FILE_AMPEG:        return "AMPEG";
2510         case FILE_VMPEG:        return "VMPEG";
2511         case FILE_RAWDV:        return "RAWDV";
2512         case FILE_AVI_ARNE2:    return "AVI_ARNE2";
2513         case FILE_AVI_ARNE1:    return "AVI_ARNE1";
2514         case FILE_AVI_AVIFILE:  return "AVI_AVIFILE";
2515         case FILE_TIFF_LIST:    return "TIFF_LIST";
2516         case FILE_PNG_LIST:     return "PNG_LIST";
2517         case FILE_AVI:          return "AVI";
2518         case FILE_AC3:          return "AC3";
2519         case FILE_EXR:          return "EXR";
2520         case FILE_EXR_LIST:     return "EXR_LIST";
2521         case FILE_CR2:          return "CR2";
2522         case FILE_OGG:          return "OGG";
2523         case FILE_VORBIS:       return "VORBIS";
2524         case FILE_FLAC:         return "FLAC";
2525         case FILE_FFMPEG:       return "FFMPEG";
2526         case FILE_SCENE:        return "SCENE";
2527         case FILE_CR2_LIST:     return "CR2_LIST";
2528         case FILE_GIF_LIST:     return "GIF_LIST";
2529         case FILE_DB:           return "DB";
2530         }
2531         return "UNKNOWN";
2532 }
2533
2534
2535 PackagingEngine *File::new_packaging_engine(Asset *asset)
2536 {
2537         PackagingEngine *result;
2538         switch (asset->format)
2539         {
2540                 case FILE_OGG:
2541                         result = (PackagingEngine*)new PackagingEngineOGG();
2542                         break;
2543                 default:
2544                         result = (PackagingEngine*) new PackagingEngineDefault();
2545                         break;
2546         }
2547
2548         return result;
2549 }
2550
2551
2552 int File::record_fd()
2553 {
2554         return file ? file->record_fd() : -1;
2555 }
2556
2557