Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

framecache.C

Go to the documentation of this file.
00001 #include "clip.h"
00002 #include "framecache.h"
00003 #include "mutex.h"
00004 #include "vframe.h"
00005 
00006 
00007 #include <math.h>
00008 
00009 FrameCacheItem::FrameCacheItem()
00010 {
00011         data = 0;
00012         position = 0;
00013         frame_rate = (double)30000.0 / 1001;
00014         age = 0;
00015 }
00016 
00017 FrameCacheItem::~FrameCacheItem()
00018 {
00019         if(data) delete data;
00020 }
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 FrameCache::FrameCache()
00038 {
00039         lock = new Mutex("FrameCache::lock");
00040         max_bytes = 0;
00041         current_age = 0;
00042 }
00043 
00044 FrameCache::~FrameCache()
00045 {
00046         items.remove_all_objects();
00047         delete lock;
00048 }
00049 
00050 
00051 // Returns 1 if frame exists in cache and copies it to the frame argument.
00052 int FrameCache::get_frame(VFrame *frame, 
00053         int64_t position,
00054         double frame_rate)
00055 {
00056         lock->lock("FrameCache::get_frame");
00057         int item_number = -1;
00058 
00059         if(frame_exists(frame,
00060                 position, 
00061                 frame_rate,
00062                 &item_number))
00063         {
00064                 FrameCacheItem *item = items.values[item_number];
00065                 if(item->data) frame->copy_from(item->data);
00066                 item->age = current_age;
00067                 current_age++;
00068         }
00069 
00070         lock->unlock();
00071         if(item_number >= 0) return 1;
00072         return 0;
00073 }
00074 
00075 
00076 VFrame* FrameCache::get_frame_ptr(int64_t position,
00077         double frame_rate,
00078         int color_model,
00079         int w,
00080         int h)
00081 {
00082         lock->lock("FrameCache::get_frame");
00083         int item_number = -1;
00084         FrameCacheItem *item = 0;
00085         if(frame_exists(position,
00086                 frame_rate,
00087                 color_model,
00088                 w,
00089                 h,
00090                 &item_number))
00091         {
00092                 item = items.values[item_number];
00093                 item->age = current_age;
00094                 current_age++;
00095         }
00096 
00097 
00098         if(item)
00099                 return item->data;
00100         else
00101         {
00102                 lock->unlock();
00103                 return 0;
00104         }
00105 }
00106 
00107 void FrameCache::unlock()
00108 {
00109     lock->unlock();
00110 }
00111 
00112 // Puts frame in cache if enough space exists and the frame doesn't already
00113 // exist.
00114 void FrameCache::put_frame(VFrame *frame, 
00115         int64_t position,
00116         double frame_rate,
00117         int use_copy)
00118 {
00119         lock->lock("FrameCache::put_frame");
00120         int item_number = -1;
00121         if(frame_exists(frame,
00122                 position, 
00123                 frame_rate,
00124                 &item_number))
00125         {
00126                 FrameCacheItem *item = items.values[item_number];
00127                 item->age = current_age;
00128                 current_age++;
00129                 lock->unlock();
00130                 return;
00131         }
00132 
00133 
00134         FrameCacheItem *item = new FrameCacheItem;
00135 
00136         if(use_copy)
00137         {
00138                 item->data = new VFrame(*frame);
00139         }
00140         else
00141         {
00142                 item->data = frame;
00143         }
00144 
00145         item->position = position;
00146         item->frame_rate = frame_rate;
00147         item->age = current_age;
00148 
00149         items.append(item);
00150         current_age++;
00151         lock->unlock();
00152 }
00153 
00154 
00155 
00156 
00157 int FrameCache::frame_exists(VFrame *format,
00158         int64_t position, 
00159         double frame_rate,
00160         int *item_return)
00161 {
00162         for(int i = 0; i < items.total; i++)
00163         {
00164                 FrameCacheItem *item = items.values[i];
00165                 if(item->position == position &&
00166                         EQUIV(item->frame_rate, frame_rate) &&
00167                         format->equivalent(item->data))
00168                 {
00169                         *item_return = i;
00170                         return 1;
00171                 }
00172         }
00173         return 0;
00174 }
00175 
00176 int FrameCache::frame_exists(int64_t position, 
00177         double frame_rate,
00178         int color_model,
00179         int w,
00180         int h,
00181         int *item_return)
00182 {
00183         for(int i = 0; i < items.total; i++)
00184         {
00185                 FrameCacheItem *item = items.values[i];
00186                 if(item->position == position &&
00187                         EQUIV(item->frame_rate, frame_rate) &&
00188                         color_model == item->data->get_color_model() &&
00189                         w == item->data->get_w() &&
00190                         h == item->data->get_h())
00191                 {
00192                         *item_return = i;
00193                         return 1;
00194                 }
00195         }
00196         return 0;
00197 }
00198 
00199 // Calculate current size of cache in bytes
00200 int64_t FrameCache::get_memory_usage()
00201 {
00202         int64_t result = 0;
00203         lock->lock("FrameCache::get_memory_usage");
00204         for(int i = 0; i < items.total; i++)
00205         {
00206                 FrameCacheItem *item = items.values[i];
00207                 result += item->data->get_data_size();
00208         }
00209         lock->unlock();
00210         return result;
00211 }
00212 
00213 int FrameCache::delete_oldest()
00214 {
00215         int64_t oldest = 0x7fffffff;
00216         int oldest_item = -1;
00217 
00218         lock->lock("FrameCache::delete_oldest");
00219         for(int i = 0; i < items.total; i++)
00220         {
00221                 if(items.values[i]->age < oldest)
00222                 {
00223                         oldest = items.values[i]->age;
00224                         oldest_item = i;
00225                 }
00226         }
00227 
00228         if(oldest_item >= 0)
00229         {
00230                 items.remove_object_number(oldest_item);
00231                 lock->unlock();
00232                 return 0;
00233         }
00234         lock->unlock();
00235         return 1;
00236 }
00237 
00238 void FrameCache::dump()
00239 {
00240         lock->lock("FrameCache::dump");
00241         printf("FrameCache::dump 1 %d\n", items.total);
00242         for(int i = 0; i < items.total; i++)
00243         {
00244                 FrameCacheItem *item = items.values[i];
00245                 printf("  position=%lld frame_rate=%f age=%d size=%d\n", 
00246                         item->position, 
00247                         item->frame_rate, 
00248                         item->age,
00249                         item->data->get_data_size());
00250         }
00251         lock->unlock();
00252 }
00253 
00254 
00255 
00256 

Generated on Sun Jan 8 13:38:55 2006 for Cinelerra-svn by  doxygen 1.4.4