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