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
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
00113
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
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