r370: Heroine Virutal's official release 1.2.1
[cinelerra_cv/mob.git] / hvirtual / cinelerra / framecache.C
blob6717f9bd0d2d0fc3e03f9c5f99771565f0c447c0
1 #include "clip.h"
2 #include "framecache.h"
3 #include "mutex.h"
4 #include "vframe.h"
7 #include <math.h>
9 FrameCacheItem::FrameCacheItem()
11         data = 0;
12         position = 0;
13         frame_rate = (double)30000.0 / 1001;
14         age = 0;
17 FrameCacheItem::~FrameCacheItem()
19         if(data) delete data;
37 FrameCache::FrameCache()
39         lock = new Mutex("FrameCache::lock");
40         max_bytes = 0;
41         current_age = 0;
44 FrameCache::~FrameCache()
46         items.remove_all_objects();
47         delete lock;
51 // Returns 1 if frame exists in cache and copies it to the frame argument.
52 int FrameCache::get_frame(VFrame *frame, 
53         int64_t position,
54         double frame_rate)
56         lock->lock("FrameCache::get_frame");
57         int item_number = -1;
59         if(frame_exists(frame,
60                 position, 
61                 frame_rate,
62                 &item_number))
63         {
64                 FrameCacheItem *item = items.values[item_number];
65                 if(item->data) frame->copy_from(item->data);
66                 item->age = current_age;
67                 current_age++;
68         }
70         lock->unlock();
71         if(item_number >= 0) return 1;
72         return 0;
76 VFrame* FrameCache::get_frame_ptr(int64_t position,
77         double frame_rate,
78         int color_model,
79         int w,
80         int h)
82         lock->lock("FrameCache::get_frame");
83         int item_number = -1;
84         FrameCacheItem *item = 0;
85         if(frame_exists(position,
86                 frame_rate,
87                 color_model,
88                 w,
89                 h,
90                 &item_number))
91         {
92                 item = items.values[item_number];
93                 item->age = current_age;
94                 current_age++;
95         }
98         if(item)
99                 return item->data;
100         else
101         {
102                 lock->unlock();
103                 return 0;
104         }
107 void FrameCache::unlock()
109     lock->unlock();
112 // Puts frame in cache if enough space exists and the frame doesn't already
113 // exist.
114 void FrameCache::put_frame(VFrame *frame, 
115         int64_t position,
116         double frame_rate,
117         int use_copy)
119         lock->lock("FrameCache::put_frame");
120         int item_number = -1;
121         if(frame_exists(frame,
122                 position, 
123                 frame_rate,
124                 &item_number))
125         {
126                 FrameCacheItem *item = items.values[item_number];
127                 item->age = current_age;
128                 current_age++;
129                 lock->unlock();
130                 return;
131         }
134         FrameCacheItem *item = new FrameCacheItem;
136         if(use_copy)
137         {
138                 item->data = new VFrame(*frame);
139         }
140         else
141         {
142                 item->data = frame;
143         }
145         item->position = position;
146         item->frame_rate = frame_rate;
147         item->age = current_age;
149         items.append(item);
150         current_age++;
151         lock->unlock();
157 int FrameCache::frame_exists(VFrame *format,
158         int64_t position, 
159         double frame_rate,
160         int *item_return)
162         for(int i = 0; i < items.total; i++)
163         {
164                 FrameCacheItem *item = items.values[i];
165                 if(item->position == position &&
166                         EQUIV(item->frame_rate, frame_rate) &&
167                         format->equivalent(item->data))
168                 {
169                         *item_return = i;
170                         return 1;
171                 }
172         }
173         return 0;
176 int FrameCache::frame_exists(int64_t position, 
177         double frame_rate,
178         int color_model,
179         int w,
180         int h,
181         int *item_return)
183         for(int i = 0; i < items.total; i++)
184         {
185                 FrameCacheItem *item = items.values[i];
186                 if(item->position == position &&
187                         EQUIV(item->frame_rate, frame_rate) &&
188                         color_model == item->data->get_color_model() &&
189                         w == item->data->get_w() &&
190                         h == item->data->get_h())
191                 {
192                         *item_return = i;
193                         return 1;
194                 }
195         }
196         return 0;
199 // Calculate current size of cache in bytes
200 int64_t FrameCache::get_memory_usage()
202         int64_t result = 0;
203         lock->lock("FrameCache::get_memory_usage");
204         for(int i = 0; i < items.total; i++)
205         {
206                 FrameCacheItem *item = items.values[i];
207                 result += item->data->get_data_size();
208         }
209         lock->unlock();
210         return result;
213 int FrameCache::delete_oldest()
215         int64_t oldest = 0x7fffffff;
216         int oldest_item = -1;
218         lock->lock("FrameCache::delete_oldest");
219         for(int i = 0; i < items.total; i++)
220         {
221                 if(items.values[i]->age < oldest)
222                 {
223                         oldest = items.values[i]->age;
224                         oldest_item = i;
225                 }
226         }
228         if(oldest_item >= 0)
229         {
230                 items.remove_object_number(oldest_item);
231                 lock->unlock();
232                 return 0;
233         }
234         lock->unlock();
235         return 1;
238 void FrameCache::dump()
240         lock->lock("FrameCache::dump");
241         printf("FrameCache::dump 1 %d\n", items.total);
242         for(int i = 0; i < items.total; i++)
243         {
244                 FrameCacheItem *item = items.values[i];
245                 printf("  position=%lld frame_rate=%f age=%d size=%d\n", 
246                         item->position, 
247                         item->frame_rate, 
248                         item->age,
249                         item->data->get_data_size());
250         }
251         lock->unlock();