r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / file.C
blobc806f44433881b9f97a2a35d374ce0a0e6ada837
1 #include "assets.h"
2 #include "byteorder.h"
3 #include "edit.h"
4 #include "errorbox.h"
5 #include "file.h"
6 #include "fileavi.h"
7 #include "filebase.h"
8 #include "filexml.h"
9 #include "filejpeg.h"
10 #include "filemov.h"
11 #include "filempeg.h"
12 #include "filepng.h"
13 #include "filesndfile.h"
14 #include "filetga.h"
15 #include "filethread.h"
16 #include "filetiff.h"
17 #include "filevorbis.h"
18 #include "formatwindow.h"
19 #include "pluginserver.h"
20 #include "resample.h"
21 #include "stringfile.h"
22 #include "vframe.h"
25 #include <libintl.h>
26 #define _(String) gettext(String)
27 #define gettext_noop(String) String
28 #define N_(String) gettext_noop (String)
30  FrameCache::FrameCache(int cache_size) 
31  {
32         cache_enabled = 0;
33         this->cache_size = cache_size;
34         timer.update();
35  }
37  FrameCache::~FrameCache() 
38  {
39         reset();
40  }
42  void FrameCache::reset() 
43  {      
44         change_lock.lock();
45         FrameCacheTree::iterator iterator = cache_tree.begin();
46         while (iterator != cache_tree.end()) {
47                 delete iterator->second;
48                 iterator++;
49         }
50         cache_tree.clear();
51         cache_tree_bytime.clear();
52         change_lock.unlock();
53  }
55  void FrameCache::enable_cache() 
56  {      
57         cache_enabled = 1;
58  }
61  void FrameCache::disable_cache() 
62  {
63         cache_enabled = 0;
64  }
66  void FrameCache::unlock_cache()
67  { 
68         change_lock.unlock();
69  }
71  void FrameCache::lock_cache()
72  { 
73         change_lock.lock();
74  }
76  inline int FrameCache::compare_with_frame(FrameCacheElement *element, 
77                                         int frame_number, 
78                                         int frame_layer,
79                                         int frame_width,
80                                         int frame_height,
81                                         int frame_color_model)
82  {
83         if (    element->frame_number == frame_number && 
84                 element->frame_layer == frame_layer && 
85                 element->frame->get_w() == frame_width && 
86                 element->frame->get_h() == frame_height && 
87                 element->frame->get_color_model() == frame_color_model)
88                         return 1; 
89                 else
90                         return 0;
91  }
93  FrameCacheTree::iterator FrameCache::find_element_byframe(long frame_number, int frame_layer, int frame_width, int frame_height, int frame_color_model)
94  {
95         FrameCacheTree::iterator iterator = cache_tree.find(frame_number);
96         if(iterator != cache_tree.end()) {
97                 do {
98                         if (compare_with_frame(iterator->second, 
99                                                 frame_number, 
100                                                 frame_layer,
101                                                 frame_width,
102                                                 frame_height,
103                                                 frame_color_model))
104                         {
105                                 
106                                 return iterator;
107                         }
108                         iterator++;
109                 } while (iterator->first == frame_number);
110         }
111         return cache_tree.end();
114  FrameCacheTree_ByTime::iterator FrameCache::find_element_bytime(long long frame_time_diff, long frame_number, int frame_layer, int frame_width, int frame_height, int frame_color_model)
116         FrameCacheTree_ByTime::iterator iterator = cache_tree_bytime.find(frame_time_diff);
117         if(iterator != cache_tree_bytime.end()) {
118                 do {    
119                         if (compare_with_frame(iterator->second, 
120                                                 frame_number, 
121                                                 frame_layer,
122                                                 frame_width,
123                                                 frame_height,
124                                                 frame_color_model))
125                         {
126                                 
127                                 return iterator;
128                         }
129                         iterator++;
130                 } while (iterator->first == frame_time_diff);
131         }
132         return cache_tree_bytime.end();
135   
136  // implicitly locks the class, needs to be unlocked after the call
137  // this is the best behaviour, everything else just complicates things and
138  // causes races (because you don't know the state of cache_enabled during the call).
139  VFrame *FrameCache::get_frame(long frame_number, int frame_layer, int frame_width, int frame_height, int frame_color_model)
142         change_lock.lock();
143         if (!cache_enabled) return 0;
144  //     printf("Looking for - frame: %li, layer: %i, w: %i, h:%i, cm: %i\n", frame_number, frame_layer, frame_width, frame_height, frame_color_model);
145         FrameCacheTree::iterator iterator= find_element_byframe(frame_number, 
146                                                                 frame_layer,
147                                                                 frame_width,
148                                                                 frame_height,
149                                                                 frame_color_model);
150         // update timestamp in other tree
151         if (iterator != cache_tree.end())
152         {
153                 FrameCacheElement *cache_element = iterator->second;
154                 FrameCacheTree_ByTime::iterator iterator_bytime;
155                 // this tree node always exists
156                 iterator_bytime = find_element_bytime(cache_element->time_diff,
157                                                                 frame_number, 
158                                                                 frame_layer,
159                                                                 frame_width,
160                                                                 frame_height,
161                                                                 frame_color_model);
162                 if (cache_element != iterator_bytime->second)
163                 {
164                         printf("FrameCache: Something severely wrong in the cache engine!! this: %p\n", this);
165                         dump();
166                         return 0;
167                 };
168  //             printf("Cache hit - frame: %li, layer: %i, w: %i, h:%i, cm: %i\n", frame_number, frame_layer, frame_width, frame_height, frame_color_model);
169                 // delete & replace with new key
170                 cache_tree_bytime.erase(iterator_bytime);
171                 cache_element->time_diff = timer.get_difference();
172                 cache_tree_bytime.insert(std::pair<long long, FrameCacheElement *> (cache_element->time_diff, cache_element)); 
173                 return (cache_element->frame);
174         };
175         return 0;
176  } 
178  void FrameCache::add_frame(long frame_number, int frame_layer, VFrame *frame, int do_not_copy_frame) 
180         
181         if (!cache_enabled) return;
182         change_lock.lock();
183         
184  //     printf("%p, adding frame:  %li, layer: %i, w: %i, h:%i cm:%i\n",this, frame_number, frame_layer, frame->get_w(),frame->get_h(), frame->get_color_model());
185         
186         FrameCacheElement *cache_element;
188         // currently cache size can only grow, not shrink
189         if (cache_tree.size() >= cache_size) 
190         {
191                 // delete the oldest element
192                 FrameCacheTree_ByTime::iterator iterator_bytime = cache_tree_bytime.begin();
193                 cache_element = iterator_bytime->second;
194                 FrameCacheTree::iterator iterator = find_element_byframe(cache_element->frame_number,
195                                                                         cache_element->frame_layer,
196                                                                         cache_element->frame->get_w(),
197                                                                         cache_element->frame->get_h(),
198                                                                         cache_element->frame->get_color_model());
199  //     printf("Deleting oldest frame: - frame: %li, layer: %i, w: %i, h:%i, cm: %i\n", cache_element->frame_number, cache_element->frame_layer, cache_element->frame->get_w(), cache_element->frame->get_h(), cache_element->frame->get_color_model());
200                 delete cache_element->frame;
201                 cache_tree.erase(iterator);
202                 cache_tree_bytime.erase(iterator_bytime);
203         } else
204         {
205                 cache_element = new FrameCacheElement;
206         }
207         
208         if (do_not_copy_frame) 
209         {
210                 cache_element->frame = frame;
211         } else
212         {
213                 cache_element->frame = new VFrame(0,
214                                         frame->get_w(),
215                                         frame->get_h(),
216                                         frame->get_color_model());
217                 cache_element->frame->copy_from(frame);
218         }
219         cache_element->frame_layer = frame_layer;
220         cache_element->frame_number = frame_number;
221         cache_element->time_diff = timer.get_difference();
223  // insert the same data into both trees under different keys
224         
225         cache_tree.insert(std::pair<long, FrameCacheElement *> (cache_element->frame_number, cache_element));
226         cache_tree_bytime.insert(std::pair<long long, FrameCacheElement *> (cache_element->time_diff, cache_element)); 
227         change_lock.unlock();
230  void FrameCache::dump() 
231 {       
232         printf("Dump of frames' cache %p, cache_tree:\n", this);
233         {
234                 FrameCacheTree::iterator iterator = cache_tree.begin();
235                 while (iterator != cache_tree.end()) {
236                         FrameCacheElement *cache_element = iterator->second;
237                         printf("%p, frame: %li, layer: %i, w: %i, h:%i, cm: %i, time_diff: %i\n", cache_element, cache_element->frame_number, cache_element->frame_layer, cache_element->frame->get_w(), cache_element->frame->get_h(), cache_element->frame->get_color_model(), cache_element->time_diff);
238                         iterator++;
239                 }
240         }
241         printf("cache_tree_bytime:\n", this);
242         {
243                 FrameCacheTree_ByTime::iterator iterator = cache_tree_bytime.begin();
244                 while (iterator != cache_tree_bytime.end()) {
245                         FrameCacheElement *cache_element = iterator->second;
246                         printf("%p, frame: %li, layer: %i, w: %i, h:%i, cm: %i, time_diff: %li\n", cache_element, cache_element->frame_number, cache_element->frame_layer, cache_element->frame->get_w(), cache_element->frame->get_h(), cache_element->frame->get_color_model(), cache_element->time_diff);
247                         iterator++;
248                 }
249         }
253 File::File()
255         cpus = 1;
256         asset = new Asset;
257         frames_cache = new FrameCache();
258         reset_parameters();
261 File::~File()
263         if(getting_options)
264         {
265                 if(format_window) format_window->set_done(0);
266                 format_completion.lock();
267                 format_completion.unlock();
268         }
270         if(temp_frame)
271         {
272                 delete temp_frame;
273         }
275         if(return_frame)
276         {
277                 delete return_frame;
278         }
280         close_file();
281         reset_parameters();
282         delete asset;
283         delete frames_cache;
286 void File::reset_parameters()
288         file = 0;
289         audio_thread = 0;
290         video_thread = 0;
291         getting_options = 0;
292         format_window = 0;
293         temp_frame = 0;
294         temp_frame = 0;
295         return_frame = 0;
296         current_sample = 0;
297         current_frame = 0;
298         current_channel = 0;
299         current_layer = 0;
300         normalized_sample = 0;
301         normalized_sample_rate = 0;
302         resample = 0;
303         frames_cache->reset();
307 int File::raise_window()
309         if(format_window)
310         {
311                 format_window->raise_window();
312                 format_window->flush();
313         }
314         return 0;
317 int File::get_options(BC_WindowBase *parent_window, 
318         ArrayList<PluginServer*> *plugindb, 
319         Asset *asset, 
320         int audio_options, 
321         int video_options,
322         int lock_compressor)
324         getting_options = 1;
325         format_completion.lock();
326         switch(asset->format)
327         {
328                 case FILE_PCM:
329                 case FILE_WAV:
330                 case FILE_AU:
331                 case FILE_AIFF:
332                 case FILE_SND:
333                         FileSndFile::get_parameters(parent_window, 
334                                 asset, 
335                                 format_window, 
336                                 audio_options, 
337                                 video_options);
338                         break;
339                 case FILE_MOV:
340                         FileMOV::get_parameters(parent_window, 
341                                 asset, 
342                                 format_window, 
343                                 audio_options, 
344                                 video_options,
345                                 lock_compressor);
346                         break;
347                 case FILE_AMPEG:
348                 case FILE_VMPEG:
349                         FileMPEG::get_parameters(parent_window, 
350                                 asset, 
351                                 format_window, 
352                                 audio_options, 
353                                 video_options);
354                         break;
355                 case FILE_AVI:
356                         FileMOV::get_parameters(parent_window, 
357                                 asset, 
358                                 format_window, 
359                                 audio_options, 
360                                 video_options,
361                                 lock_compressor);
362                         break;
363                 case FILE_AVI_LAVTOOLS:
364                 case FILE_AVI_ARNE2:
365                 case FILE_AVI_ARNE1:
366                 case FILE_AVI_AVIFILE:
367                         FileAVI::get_parameters(parent_window, 
368                                 asset, 
369                                 format_window, 
370                                 audio_options, 
371                                 video_options,
372                                 lock_compressor);
373                         break;
374                 case FILE_JPEG:
375                 case FILE_JPEG_LIST:
376                         FileJPEG::get_parameters(parent_window, 
377                                 asset, 
378                                 format_window, 
379                                 audio_options, 
380                                 video_options);
381                         break;
382                 case FILE_PNG:
383                 case FILE_PNG_LIST:
384                         FilePNG::get_parameters(parent_window, 
385                                 asset, 
386                                 format_window, 
387                                 audio_options, 
388                                 video_options);
389                         break;
390                 case FILE_TGA:
391                 case FILE_TGA_LIST:
392                         FileTGA::get_parameters(parent_window, 
393                                 asset, 
394                                 format_window, 
395                                 audio_options, 
396                                 video_options);
397                         break;
398                 case FILE_TIFF:
399                 case FILE_TIFF_LIST:
400                         FileTIFF::get_parameters(parent_window, 
401                                 asset, 
402                                 format_window, 
403                                 audio_options, 
404                                 video_options);
405                         break;
406                 case FILE_VORBIS:
407                         FileVorbis::get_parameters(parent_window,
408                                 asset,
409                                 format_window,
410                                 audio_options,
411                                 video_options);
412                         break;
413                 default:
414                         break;
415         }
417         if(!format_window)
418         {
419                 ErrorBox *errorbox = new ErrorBox(PROGRAM_NAME ": Error",
420                         parent_window->get_abs_cursor_x(),
421                         parent_window->get_abs_cursor_y());
422                 format_window = errorbox;
423                 getting_options = 1;
424                 if(audio_options)
425                         errorbox->create_objects(_("This format doesn't support audio."));
426                 else
427                 if(video_options)
428                         errorbox->create_objects(_("This format doesn't support video."));
429                 errorbox->run_window();
430                 delete errorbox;
431         }
432         getting_options = 0;
433         format_window = 0;
434         format_completion.unlock();
435         return 0;
438 void File::set_asset(Asset *asset)
440         *this->asset = *asset;
443 int File::set_processors(int cpus)   // Set the number of cpus for certain codecs
445 //printf("File::set_processors 1 %d\n", cpus);
446         this->cpus = cpus;
447         return 0;
450 int File::set_preload(int64_t size)
452         this->playback_preload = size;
453         return 0;
456 int File::open_file(ArrayList<PluginServer*> *plugindb, 
457         Asset *asset, 
458         int rd, 
459         int wr,
460         int64_t base_samplerate,
461         float base_framerate)
463         *this->asset = *asset;
464         file = 0;
467 //printf("File::open_file 1 %s %d\n", asset->path, asset->format);
468         switch(this->asset->format)
469         {
470 // get the format now
471 // If you add another format to case 0, you also need to add another case for the
472 // file format #define.
473                 case FILE_UNKNOWN:
474                         FILE *stream;
475                         if(!(stream = fopen(this->asset->path, "rb")))
476                         {
477 // file not found
478                                 return 1;
479                         }
481                         char test[16];
482                         fread(test, 16, 1, stream);
484 //                      if(FileAVI::check_sig(this->asset))
485 //                      {
486 //                              fclose(stream);
487 //                              file = new FileAVI(this->asset, this);
488 //                      }
489 //                      else
490                         if(FileSndFile::check_sig(this->asset))
491                         {
492 // libsndfile
493                                 fclose(stream);
494                                 file = new FileSndFile(this->asset, this);
495                         }
496                         else
497                         if(FilePNG::check_sig(this->asset))
498                         {
499 // PNG file
500                                 fclose(stream);
501                                 file = new FilePNG(this->asset, this);
502                         }
503                         else
504                         if(FileJPEG::check_sig(this->asset))
505                         {
506 // JPEG file
507                                 fclose(stream);
508                                 file = new FileJPEG(this->asset, this);
509                         }
510                         else
511                         if(FileTGA::check_sig(this->asset))
512                         {
513 // TGA file
514                                 fclose(stream);
515                                 file = new FileTGA(this->asset, this);
516                         }
517                         else
518                         if(FileTIFF::check_sig(this->asset))
519                         {
520 // TIFF file
521                                 fclose(stream);
522                                 file = new FileTIFF(this->asset, this);
523                         }
524                         else
525                         if(FileVorbis::check_sig(this->asset))
526                         {
527 // MPEG file
528                                 fclose(stream);
529                                 file = new FileVorbis(this->asset, this);
530                         }
531                         else
532                         if(FileMPEG::check_sig(this->asset))
533                         {
534 // MPEG file
535                                 fclose(stream);
536                                 file = new FileMPEG(this->asset, this);
537                         }
538                         else
539                         if(test[0] == '<' && test[1] == 'E' && test[2] == 'D' && test[3] == 'L' && test[4] == '>' ||
540                                 test[0] == '<' && test[1] == 'H' && test[2] == 'T' && test[3] == 'A' && test[4] == 'L' && test[5] == '>' ||
541                                 test[0] == '<' && test[1] == '?' && test[2] == 'x' && test[3] == 'm' && test[4] == 'l')
542                         {
543 // XML file
544                                 fclose(stream);
545                                 return FILE_IS_XML;
546                         }    // can't load project file
547                         else
548                         if(FileMOV::check_sig(this->asset))
549                         {
550 // MOV file
551 // should be last because quicktime lacks a magic number
552                                 fclose(stream);
553                                 file = new FileMOV(this->asset, this);
554                         }
555                         else
556                         {
557 // PCM file
558                                 fclose(stream);
559                                 return FILE_UNRECOGNIZED_CODEC;
560                         }   // need more info
561                         break;
563 // format already determined
564                 case FILE_PCM:
565                 case FILE_WAV:
566                 case FILE_AU:
567                 case FILE_AIFF:
568                 case FILE_SND:
569 //printf("File::open_file 1\n");
570                         file = new FileSndFile(this->asset, this);
571                         break;
573                 case FILE_PNG:
574                 case FILE_PNG_LIST:
575                         file = new FilePNG(this->asset, this);
576                         break;
578                 case FILE_JPEG:
579                 case FILE_JPEG_LIST:
580                         file = new FileJPEG(this->asset, this);
581                         break;
583                 case FILE_TGA_LIST:
584                 case FILE_TGA:
585                         file = new FileTGA(this->asset, this);
586                         break;
588                 case FILE_TIFF:
589                 case FILE_TIFF_LIST:
590                         file = new FileTIFF(this->asset, this);
591                         break;
593                 case FILE_MOV:
594                         file = new FileMOV(this->asset, this);
595                         break;
597                 case FILE_MPEG:
598                 case FILE_AMPEG:
599                 case FILE_VMPEG:
600                         file = new FileMPEG(this->asset, this);
601                         break;
603                 case FILE_VORBIS:
604                         file = new FileVorbis(this->asset, this);
605                         break;
607                 case FILE_AVI:
608                         file = new FileMOV(this->asset, this);
609                         break;
611                 case FILE_AVI_LAVTOOLS:
612                 case FILE_AVI_ARNE2:
613                 case FILE_AVI_ARNE1:
614                 case FILE_AVI_AVIFILE:
615                         file = new FileAVI(this->asset, this);
616                         break;
618 // try plugins
619                 default:
620                         return 1;
621                         break;
622         }
623 //printf("File::open_file 2\n");
625 // Reopen file with correct parser and get header.
626         if(file->open_file(rd, wr))
627         {
628                 delete file;
629                 file = 0;
630         }
633 // Set extra writing parameters to mandatory settings.
634         if(file && wr)
635         {
636                 if(this->asset->dither) file->set_dither();
637         }
639 // Synchronize header parameters
640         *asset = *this->asset;
641 //printf("File::open_file 3\n");
643         if(file)
644                 return FILE_OK;
645         else
646                 return FILE_NOT_FOUND;
649 int File::close_file(int ignore_thread)
651         if(!ignore_thread)
652         {
653                 stop_audio_thread();
654                 stop_video_thread();
655         }
657         if(file) 
658         {
659 // The file's asset is a copy of the argument passed to open_file so the
660 // user must copy lengths from the file's asset.
661                 if(asset && file->wr)
662                 {
663                         asset->audio_length = current_sample;
664                         asset->video_length = current_frame;
665                 }
666                 file->close_file();
667                 delete file;
668         }
670         if(resample) delete resample;
672         reset_parameters();
673         return 0;
676 int File::start_audio_thread(int64_t buffer_size, int ring_buffers)
678         audio_thread = new FileThread(this, 1, 0);
679         audio_thread->start_writing(buffer_size, 0, ring_buffers, 0);
680         return 0;
683 int File::start_video_thread(int64_t buffer_size, 
684         int color_model, 
685         int ring_buffers, 
686         int compressed)
688         video_thread = new FileThread(this, 0, 1);
689 //printf("File::start_video_thread 1\n");
690         video_thread->start_writing(buffer_size, 
691                 color_model, 
692                 ring_buffers, 
693                 compressed);
694 //printf("File::start_video_thread 2\n");
695         return 0;
698 int File::stop_audio_thread()
700 //printf("File::stop_audio_thread 1\n");
701         if(audio_thread)
702         {
703                 audio_thread->stop_writing();
704                 delete audio_thread;
705                 audio_thread = 0;
706         }
707         return 0;
710 int File::stop_video_thread()
712 //printf("File::stop_video_thread 1\n");
713         if(video_thread)
714         {
715                 video_thread->stop_writing();
716                 delete video_thread;
717                 video_thread = 0;
718         }
719         return 0;
722 int File::lock_read()
724 //      read_lock.lock();
725         return 0;
728 int File::unlock_read()
730 //      read_lock.unlock();
731         return 0;
734 int File::set_channel(int channel) 
736         if(file && channel < asset->channels)
737         {
738                 current_channel = channel;
739                 return 0;
740         }
741         else
742                 return 1;
745 int File::set_layer(int layer) 
747         if(file && layer < asset->layers)
748         {
749                 current_layer = layer;
750 //printf("File::set_layer 1 %d\n", layer);
751                 return 0; 
752         }
753         else
754                 return 1;
757 int64_t File::get_audio_length(int64_t base_samplerate) 
759         int64_t result = asset->audio_length;
760         if(result > 0)
761         {
762                 if(base_samplerate > 0)
763                         return (int64_t)((double)result / asset->sample_rate * base_samplerate + 0.5);
764                 else
765                         return result;
766         }
767         else
768                 return -1;
771 int64_t File::get_video_length(float base_framerate)
773         int64_t result = asset->video_length;
774         if(result > 0)
775         {
776                 if(base_framerate > 0)
777                         return (int64_t)((double)result / asset->frame_rate * base_framerate + 0.5); 
778                 else
779                         return result;
780         }
781         else
782                 return -1;  // infinity
786 int64_t File::get_video_position(float base_framerate) 
788         if(base_framerate > 0)
789                 return (int64_t)((double)current_frame / asset->frame_rate * base_framerate + 0.5);
790         else
791                 return current_frame;
794 int64_t File::get_audio_position(int64_t base_samplerate) 
796         if(base_samplerate > 0)
797         {
798                 if(normalized_sample_rate == base_samplerate)
799                         return normalized_sample;
800                 else
801                         return (int64_t)((double)current_sample / 
802                                 asset->sample_rate * 
803                                 base_samplerate + 
804                                 0.5);
805         }
806         else
807                 return current_sample;
812 // The base samplerate must be nonzero if the base samplerate in the calling
813 // function is expected to change as this forces the resampler to reset.
815 int File::set_audio_position(int64_t position, float base_samplerate) 
817         int result = 0;
819         if(!file) return 1;
821 #define REPOSITION(x, y) \
822         (labs((x) - (y)) > 1)
826         if((base_samplerate && REPOSITION(normalized_sample, position)) ||
827                 (!base_samplerate && REPOSITION(current_sample, position)))
828         {
829 // Can't reset resampler since one seek operation is done 
830 // for every channel to be read at the same position.
832 // Use a conditional reset for just the case of different base_samplerates
833                 if(base_samplerate > 0)
834                 {
835                         if(normalized_sample_rate &&
836                                 normalized_sample_rate != base_samplerate && 
837                                 resample)
838                                 resample->reset(-1);
840                         normalized_sample = position;
841                         normalized_sample_rate = (int64_t)((base_samplerate > 0) ? 
842                                 base_samplerate : 
843                                 asset->sample_rate);
845 // Convert position to file's rate
846                         if(base_samplerate > 0)
847                                 current_sample = Units::round((double)position / 
848                                         base_samplerate * 
849                                         asset->sample_rate);
850                 }
851                 else
852                 {
853                         current_sample = position;
854                         normalized_sample = Units::round((double)position / 
855                                         asset->sample_rate * 
856                                         normalized_sample_rate);
857 // Can not set the normalized sample rate since this would reset the resampler.
858                 }
860                 result = file->set_audio_position(current_sample);
862                 if(result)
863                         printf("File::set_audio_position position=%d base_samplerate=%f asset=%p asset->sample_rate=%d\n",
864                                 position, base_samplerate, asset, asset->sample_rate);
865         }
867 //printf("File::set_audio_position %d %d %d\n", current_channel, current_sample, position);
869         return result;
872 int File::set_video_position(int64_t position, float base_framerate) 
874         int result = 0;
875         if(!file) return 0;
876 //printf("File::set_video_position 1 %d\n", position);
878 // Convert to file's rate
879         if(base_framerate > 0)
880                 position = (int64_t)((double)position / base_framerate * asset->frame_rate + 0.5);
881 //printf("File::set_video_position 2 %d\n", position);
883         if(current_frame != position && file)
884         {
885                 current_frame = position;
886                 result = file->set_video_position(current_frame);
887         }
888 //printf("File::set_video_position 3 %d\n", result);
890         return result;
893 // No resampling here.
894 int File::write_samples(double **buffer, int64_t len)
896         int result = 1;
897         
898         if(file)
899         {
900                 write_lock.lock();
901                 result = file->write_samples(buffer, len);
902                 current_sample += len;
903                 normalized_sample += len;
904                 asset->audio_length += len;
905                 write_lock.unlock();
906         }
907         return result;
910 // Can't put any cmodel abstraction here because the filebase couldn't be
911 // parallel.
912 int File::write_frames(VFrame ***frames, int len)
914 // Store the counters in temps so the filebase can choose to overwrite them.
915         int result;
916         int current_frame_temp = current_frame;
917         int video_length_temp = asset->video_length;
918         write_lock.lock();
923         result = file->write_frames(frames, len);
929         current_frame = current_frame_temp + len;
930         asset->video_length = video_length_temp + len;
931         write_lock.unlock();
932         return result;
935 int File::write_compressed_frame(VFrame *buffer)
937         int result = 0;
938         write_lock.lock();
939         result = file->write_compressed_frame(buffer);
940         current_frame++;
941         asset->video_length++;
942         write_lock.unlock();
943         return result;
947 int File::write_audio_buffer(int64_t len)
949         int result = 0;
950         if(audio_thread)
951         {
952                 result = audio_thread->write_buffer(len);
953         }
954         return result;
957 int File::write_video_buffer(int64_t len)
959         int result = 0;
960         if(video_thread)
961         {
962                 result = video_thread->write_buffer(len);
963         }
965         return result;
968 double** File::get_audio_buffer()
970         if(audio_thread) return audio_thread->get_audio_buffer();
971         return 0;
974 VFrame*** File::get_video_buffer()
976         if(video_thread) return video_thread->get_video_buffer();
977         return 0;
981 int File::read_samples(double *buffer, int64_t len, int64_t base_samplerate)
983         int result = 0;
984 //printf("File::read_samples 1\n");
986 // Load with resampling 
987         if(file)
988         {
989 // Resample recursively calls this with the asset sample rate
990                 if(base_samplerate == 0) base_samplerate = asset->sample_rate;
992 //printf("File::read_samples 2 %d %d\n", base_samplerate, asset->sample_rate);
993                 if(base_samplerate != asset->sample_rate)
994                 {
995 //printf("File::read_samples 3\n");
996                         if(!resample)
997                         {
998 //printf("File::read_samples 4\n");
999                                 resample = new Resample(this, asset->channels);
1000                         }
1002 //printf("File::read_samples 5\n");
1003                         current_sample += resample->resample(buffer, 
1004                                 len, 
1005                                 asset->sample_rate, 
1006                                 base_samplerate,
1007                                 current_channel,
1008                                 current_sample,
1009                                 normalized_sample);
1010 //printf("File::read_samples 6\n");
1011                 }
1012                 else
1013 // Load directly
1014                 {
1015 //printf("File::read_samples 7\n");
1016                         result = file->read_samples(buffer, len);
1017 //printf("File::read_samples 8\n");
1018                         current_sample += len;
1019                 }
1021                 normalized_sample += len;
1022         }
1023         return result;
1026 int File::read_compressed_frame(VFrame *buffer)
1028         int result = 1;
1029         if(file)
1030                 result = file->read_compressed_frame(buffer);
1031         current_frame++;
1032         return result;
1035 int64_t File::compressed_frame_size()
1037         if(file)
1038                 return file->compressed_frame_size();
1039         else 
1040                 return 0;
1043 // Return a pointer to a frame in the video file for drawing purposes.
1044 // The temporary frame is created by the file handler so that still frame
1045 // files don't have to copy to a new buffer.
1046 VFrame* File::read_frame(int color_model)
1048         VFrame* result = 0;
1049 //printf("File::read_frame 1\n");
1050         if(file)
1051         {
1052 //printf("File::read_frame 2\n");
1053                 if(return_frame && 
1054                         (return_frame->get_w() != asset->width || 
1055                         return_frame->get_h() != asset->height || 
1056                         return_frame->get_color_model() != color_model))
1057                 {
1058                         delete return_frame;
1059                         return_frame = 0;
1060                 }
1062 //printf("File::read_frame 3\n");
1063                 if(!return_frame)
1064                 {
1065                         return_frame = new VFrame(0,
1066                                 asset->width,
1067                                 asset->height,
1068                                 color_model);
1069                 }
1070 //printf("File::read_frame 4\n");
1072                 read_frame(return_frame);
1073 //printf("File::read_frame 5\n");
1074                 result = return_frame;
1075         }
1076 //printf("File::read_frame 6\n");
1077         return result;
1081 int File::read_frame(VFrame *frame)
1083         if(file)
1084         {
1085 //printf("File::read_frame 1\n");
1086                 int supported_colormodel = colormodel_supported(frame->get_color_model());
1088 //printf("File::read_frame 1 %d %d\n", supported_colormodel, frame->get_color_model());
1089 // Need temp
1090 //printf("File::read_frame 2\n");
1091                 if(frame->get_color_model() != BC_COMPRESSED &&
1092                         (supported_colormodel != frame->get_color_model() ||
1093                         frame->get_w() != asset->width ||
1094                         frame->get_h() != asset->height))
1095                 {
1096 //printf("File::read_frame 3\n");
1097                         if(temp_frame)
1098                         {
1099                                 if(!temp_frame->params_match(asset->width, asset->height, supported_colormodel))
1100                                 {
1101                                         delete temp_frame;
1102                                         temp_frame = 0;
1103                                 }
1104                         }
1105 //printf("File::read_frame 4 %p %d %d %d\n", asset , asset->width, asset->height, supported_colormodel);
1107                         if(!temp_frame)
1108                         {
1109                                 temp_frame = new VFrame(0,
1110                                         asset->width,
1111                                         asset->height,
1112                                         supported_colormodel);
1113                         }
1114                         
1115 //printf("File::read_frame 5 %d %d\n", 
1116 //      temp_frame->get_color_model(), 
1117 //      frame->get_color_model());
1118                         VFrame *temp_frame2 = frames_cache->get_frame(current_frame, current_layer, asset->width, asset->height, supported_colormodel);
1119                         if (temp_frame2) 
1120                         {
1121                                 delete temp_frame;
1122                                 frame->copy_from(temp_frame2);
1123                                 // cache is implicitly locked on cache hit
1124                                 frames_cache->unlock_cache();
1125                         } else
1126                         {
1127                                 frames_cache->unlock_cache();
1128                                 file->read_frame(temp_frame);
1130                                 cmodel_transfer(frame->get_rows(), 
1131                                         temp_frame->get_rows(),
1132                                         0,
1133                                         0,
1134                                         0,
1135                                         0,
1136                                         0,
1137                                         0,
1138                                         0, 
1139                                         0, 
1140                                         temp_frame->get_w(), 
1141                                         temp_frame->get_h(),
1142                                         0, 
1143                                         0, 
1144                                         frame->get_w(), 
1145                                         frame->get_h(),
1146                                         temp_frame->get_color_model(), 
1147                                         frame->get_color_model(),
1148                                         0,
1149                                         temp_frame->get_w(),
1150                                         frame->get_w());
1151 printf("File::read_frame 6\n");
1152                                 frames_cache->add_frame(current_frame, current_layer, frame);
1153                                 current_frame++;
1154                         }
1155                 }
1156                 else
1157                 {
1158 //printf("File::read_frame 7\n");
1159                         VFrame *temp_frame2 = frames_cache->get_frame(current_frame, current_layer, asset->width, asset->height, frame->get_color_model());
1160                         if (temp_frame2) 
1161                         {
1162                                 frame->copy_from(temp_frame2);
1163                                 frames_cache->unlock_cache();
1164                         } else
1165                         {
1166                                 frames_cache->unlock_cache();
1167                                 file->read_frame(frame);
1168                                 frames_cache->add_frame(current_frame, current_layer, frame);
1169                                 current_frame++;
1170                         }
1171 //printf("File::read_frame 8\n");
1172                 }
1174 //printf("File::read_frame 9\n");
1175 //printf("File::read_frame 2 %d\n", supported_colormodel);
1176                 return 0;
1177         }
1178         else
1179                 return 1;
1182 int File::can_copy_from(Edit *edit, int64_t position, int output_w, int output_h)
1184         if(file)
1185         {
1186                 return edit->asset->width == output_w &&
1187                         edit->asset->height == output_h &&
1188                         file->can_copy_from(edit, position);
1189         }
1190         else
1191                 return 0;
1194 // Fill in queries about formats when adding formats here.
1198 int File::strtoformat(ArrayList<PluginServer*> *plugindb, char *format)
1200         if(!strcasecmp(format, _(WAV_NAME))) return FILE_WAV;
1201         else
1202         if(!strcasecmp(format, _(PCM_NAME))) return FILE_PCM;
1203         else
1204         if(!strcasecmp(format, _(AU_NAME))) return FILE_AU;
1205         else
1206         if(!strcasecmp(format, _(AIFF_NAME))) return FILE_AIFF;
1207         else
1208         if(!strcasecmp(format, _(SND_NAME))) return FILE_SND;
1209         else
1210         if(!strcasecmp(format, _(PNG_NAME))) return FILE_PNG;
1211         else
1212         if(!strcasecmp(format, _(PNG_LIST_NAME))) return FILE_PNG_LIST;
1213         else
1214         if(!strcasecmp(format, _(TIFF_NAME))) return FILE_TIFF;
1215         else
1216         if(!strcasecmp(format, _(TIFF_LIST_NAME))) return FILE_TIFF_LIST;
1217         else
1218         if(!strcasecmp(format, _(JPEG_NAME))) return FILE_JPEG;
1219         else
1220         if(!strcasecmp(format, _(JPEG_LIST_NAME))) return FILE_JPEG_LIST;
1221         else
1222         if(!strcasecmp(format, _(MPEG_NAME))) return FILE_MPEG;
1223         else
1224         if(!strcasecmp(format, _(AMPEG_NAME))) return FILE_AMPEG;
1225         else
1226         if(!strcasecmp(format, _(VMPEG_NAME))) return FILE_VMPEG;
1227         else
1228         if(!strcasecmp(format, _(TGA_NAME))) return FILE_TGA;
1229         else
1230         if(!strcasecmp(format, _(TGA_LIST_NAME))) return FILE_TGA_LIST;
1231         else
1232         if(!strcasecmp(format, _(MOV_NAME))) return FILE_MOV;
1233         else
1234         if(!strcasecmp(format, _(AVI_NAME))) return FILE_AVI;
1235         else
1236         if(!strcasecmp(format, _(AVI_LAVTOOLS_NAME))) return FILE_AVI_LAVTOOLS;
1237         else
1238         if(!strcasecmp(format, _(AVI_ARNE2_NAME))) return FILE_AVI_ARNE2;
1239         else
1240         if(!strcasecmp(format, _(AVI_ARNE1_NAME))) return FILE_AVI_ARNE1;
1241         else
1242         if(!strcasecmp(format, _(AVI_AVIFILE_NAME))) return FILE_AVI_AVIFILE;
1243         else
1244         if(!strcasecmp(format, _(VORBIS_NAME))) return FILE_VORBIS;
1246         return 0;
1249 char* File::formattostr(ArrayList<PluginServer*> *plugindb, int format)
1251         switch(format)
1252         {
1253                 case FILE_WAV:
1254                         return _(WAV_NAME);
1255                         break;
1256                 case FILE_PCM:
1257                         return _(PCM_NAME);
1258                         break;
1259                 case FILE_AU:
1260                         return _(AU_NAME);
1261                         break;
1262                 case FILE_AIFF:
1263                         return _(AIFF_NAME);
1264                         break;
1265                 case FILE_SND:
1266                         return _(SND_NAME);
1267                         break;
1268                 case FILE_PNG:
1269                         return _(PNG_NAME);
1270                         break;
1271                 case FILE_PNG_LIST:
1272                         return _(PNG_LIST_NAME);
1273                         break;
1274                 case FILE_JPEG:
1275                         return _(JPEG_NAME);
1276                         break;
1277                 case FILE_JPEG_LIST:
1278                         return _(JPEG_LIST_NAME);
1279                         break;
1280                 case FILE_MPEG:
1281                         return _(MPEG_NAME);
1282                         break;
1283                 case FILE_AMPEG:
1284                         return _(AMPEG_NAME);
1285                         break;
1286                 case FILE_VMPEG:
1287                         return _(VMPEG_NAME);
1288                         break;
1289                 case FILE_TGA:
1290                         return _(TGA_NAME);
1291                         break;
1292                 case FILE_TGA_LIST:
1293                         return _(TGA_LIST_NAME);
1294                         break;
1295                 case FILE_TIFF:
1296                         return _(TIFF_NAME);
1297                         break;
1298                 case FILE_TIFF_LIST:
1299                         return _(TIFF_LIST_NAME);
1300                         break;
1301                 case FILE_MOV:
1302                         return _(MOV_NAME);
1303                         break;
1304                 case FILE_AVI_LAVTOOLS:
1305                         return _(AVI_LAVTOOLS_NAME);
1306                         break;
1307                 case FILE_AVI:
1308                         return _(AVI_NAME);
1309                         break;
1310                 case FILE_AVI_ARNE2:
1311                         return _(AVI_ARNE2_NAME);
1312                         break;
1313                 case FILE_AVI_ARNE1:
1314                         return _(AVI_ARNE1_NAME);
1315                         break;
1316                 case FILE_AVI_AVIFILE:
1317                         return _(AVI_AVIFILE_NAME);
1318                         break;
1319                 case FILE_VORBIS:
1320                         return _(VORBIS_NAME);
1321                         break;
1323                 default:
1324                         return _("Unknown");
1325                         break;
1326         }
1327         return "Unknown";
1330 int File::strtobits(char *bits)
1332         if(!strcasecmp(bits, _(NAME_8BIT))) return BITSLINEAR8;
1333         if(!strcasecmp(bits, _(NAME_16BIT))) return BITSLINEAR16;
1334         if(!strcasecmp(bits, _(NAME_24BIT))) return BITSLINEAR24;
1335         if(!strcasecmp(bits, _(NAME_32BIT))) return BITSLINEAR32;
1336         if(!strcasecmp(bits, _(NAME_ULAW))) return BITSULAW;
1337         if(!strcasecmp(bits, _(NAME_ADPCM))) return BITS_ADPCM;
1338         if(!strcasecmp(bits, _(NAME_FLOAT))) return BITSFLOAT;
1339         if(!strcasecmp(bits, _(NAME_IMA4))) return BITSIMA4;
1340         return BITSLINEAR16;
1343 char* File::bitstostr(int bits)
1345 //printf("File::bitstostr\n");
1346         switch(bits)
1347         {
1348                 case BITSLINEAR8:
1349                         return (NAME_8BIT);
1350                         break;
1351                 case BITSLINEAR16:
1352                         return (NAME_16BIT);
1353                         break;
1354                 case BITSLINEAR24:
1355                         return (NAME_24BIT);
1356                         break;
1357                 case BITSLINEAR32:
1358                         return (NAME_32BIT);
1359                         break;
1360                 case BITSULAW:
1361                         return (NAME_ULAW);
1362                         break;
1363                 case BITS_ADPCM:
1364                         return (NAME_ADPCM);
1365                         break;
1366                 case BITSFLOAT:
1367                         return (NAME_FLOAT);
1368                         break;
1369                 case BITSIMA4:
1370                         return (NAME_IMA4);
1371                         break;
1372         }
1373         return "Unknown";
1378 int File::str_to_byteorder(char *string)
1380         if(!strcasecmp(string, _("Lo Hi"))) return 1;
1381         return 0;
1384 char* File::byteorder_to_str(int byte_order)
1386         if(byte_order) return _("Lo Hi");
1387         return _("Hi Lo");
1390 int File::bytes_per_sample(int bits)
1392         switch(bits)
1393         {
1394                 case BITSLINEAR8:
1395                         return 1;
1396                         break;
1397                 case BITSLINEAR16:
1398                         return 2;
1399                         break;
1400                 case BITSLINEAR24:
1401                         return 3;
1402                         break;
1403                 case BITSLINEAR32:
1404                         return 4;
1405                         break;
1406                 case BITSULAW:
1407                         return 1;
1408                         break;
1409                 case BITSIMA4:
1410                         return 1;
1411                         break;
1412         }
1413         return 1;
1420 int File::get_best_colormodel(int driver)
1422         return get_best_colormodel(asset, driver);
1425 int File::get_best_colormodel(Asset *asset, int driver)
1427         switch(asset->format)
1428         {
1429                 case FILE_MOV:
1430                         return FileMOV::get_best_colormodel(asset, driver);
1431                         break;
1432                 
1433                 case FILE_MPEG:
1434                         return FileMPEG::get_best_colormodel(asset, driver);
1435                         break;
1436                 
1437                 case FILE_JPEG:
1438                 case FILE_JPEG_LIST:
1439                         return FileJPEG::get_best_colormodel(asset, driver);
1440                         break;
1441                 
1442                 case FILE_PNG:
1443                 case FILE_PNG_LIST:
1444                         return FilePNG::get_best_colormodel(asset, driver);
1445                         break;
1446                 
1447                 case FILE_TGA:
1448                 case FILE_TGA_LIST:
1449                         return FileTGA::get_best_colormodel(asset, driver);
1450                         break;
1451         }
1453         return BC_RGB888;
1457 int File::colormodel_supported(int colormodel)
1459         if(file)
1460                 return file->colormodel_supported(colormodel);
1462         return BC_RGB888;
1469 int File::supports_video(ArrayList<PluginServer*> *plugindb, char *format)
1471         int i, format_i = strtoformat(plugindb, format);
1472         
1473         return supports_video(format_i);
1475 //      for(i = 0; i < plugindb->total; i++)
1476 //      {       
1477 //              if(plugindb->values[i]->fileio && 
1478 //                      !strcmp(plugindb->values[i]->title, format))
1479 //              {
1480 //                      if(plugindb->values[i]->video) return 1;
1481 //              }
1482 //      }
1484         return 0;
1487 int File::supports_audio(ArrayList<PluginServer*> *plugindb, char *format)
1489         int i, format_i = strtoformat(plugindb, format);
1491         return supports_audio(format_i);
1493 //      for(i = 0; i < plugindb->total; i++)
1494 //      {       
1495 //              if(plugindb->values[i]->fileio && 
1496 //                      !strcmp(plugindb->values[i]->title, format))
1497 //              {
1498 //                      if(plugindb->values[i]->audio) return 1;
1499 //              }
1500 //      }
1502         return 0;
1506 int File::supports_video(int format)
1508 //printf("File::supports_video %d\n", format);
1509         switch(format)
1510         {
1511                 case FILE_MOV:
1512                 case FILE_JPEG:
1513                 case FILE_JPEG_LIST:
1514                 case FILE_PNG:
1515                 case FILE_PNG_LIST:
1516                 case FILE_TGA:
1517                 case FILE_TGA_LIST:
1518                 case FILE_TIFF:
1519                 case FILE_TIFF_LIST:
1520                 case FILE_VMPEG:
1521                 case FILE_AVI_LAVTOOLS:
1522                 case FILE_AVI_ARNE2:
1523                 case FILE_AVI:
1524                 case FILE_AVI_ARNE1:
1525                 case FILE_AVI_AVIFILE:
1526                         return 1;
1527                         break;
1529                 default:
1530                         return 0;
1531                         break;
1532         }
1535 int File::supports_audio(int format)
1537         switch(format)
1538         {
1539                 case FILE_PCM:
1540                 case FILE_WAV:
1541                 case FILE_MOV:
1542                 case FILE_AMPEG:
1543                 case FILE_VORBIS:
1544                 case FILE_AU:
1545                 case FILE_AIFF:
1546                 case FILE_SND:
1547                 case FILE_AVI:
1548                 case FILE_AVI_LAVTOOLS:
1549                 case FILE_AVI_ARNE2:
1550                 case FILE_AVI_ARNE1:
1551                 case FILE_AVI_AVIFILE:
1552                         return 1;
1553                 
1554                 default:
1555                         return 0;
1556                         break;
1557         }