r956: README.BUILD - add more library recommendations
[cinelerra_cv/ct.git] / cinelerra / framecache.C
blob3cea853f70d7e143f3f8822b6bba8d893626ab7f
1 #include "asset.h"
2 #include "bcsignals.h"
3 #include "clip.h"
4 #include "framecache.h"
5 #include "mutex.h"
6 #include "vframe.h"
9 #include <math.h>
10 #include <string.h>
11 #include <unistd.h>
15 FrameCacheItem::FrameCacheItem()
16  : CacheItemBase()
18         data = 0;
19         position = 0;
20         frame_rate = (double)30000.0 / 1001;
23 FrameCacheItem::~FrameCacheItem()
25         delete data;
28 int FrameCacheItem::get_size()
30         if(data) return data->get_data_size() + (path ? strlen(path) : 0);
31         return 0;
48 FrameCache::FrameCache()
49  : CacheBase()
53 FrameCache::~FrameCache()
58 // Returns 1 if frame exists in cache and copies it to the frame argument.
59 int FrameCache::get_frame(VFrame *frame, 
60         int64_t position,
61         int layer,
62         double frame_rate,
63         int asset_id)
65         lock->lock("FrameCache::get_frame");
66         FrameCacheItem *result = 0;
68         if(frame_exists(frame,
69                 position, 
70                 layer,
71                 frame_rate,
72                 &result,
73                 asset_id))
74         {
75                 if(result->data) 
76                 {
77                         frame->copy_from(result->data);
78                         frame->copy_stacks(result->data);
79                 }
80                 result->age = get_age();
81         }
83         lock->unlock();
84         if(result) return 1;
85         return 0;
89 VFrame* FrameCache::get_frame_ptr(int64_t position,
90         int layer,
91         double frame_rate,
92         int color_model,
93         int w,
94         int h,
95         int asset_id)
97         lock->lock("FrameCache::get_frame_ptr");
98         FrameCacheItem *result = 0;
99         if(frame_exists(position,
100                 layer,
101                 frame_rate,
102                 color_model,
103                 w,
104                 h,
105                 &result,
106                 asset_id))
107         {
108                 result->age = get_age();
109                 return result->data;
110         }
113         lock->unlock();
114         return 0;
117 // Puts frame in cache if enough space exists and the frame doesn't already
118 // exist.
119 void FrameCache::put_frame(VFrame *frame, 
120         int64_t position,
121         int layer,
122         double frame_rate,
123         int use_copy,
124         Asset *asset)
126         lock->lock("FrameCache::put_frame");
127         FrameCacheItem *item = 0;
128         if(frame_exists(frame,
129                 position, 
130                 layer,
131                 frame_rate,
132                 &item,
133                 asset ? asset->id : -1))
134         {
135                 item->age = get_age();
136                 lock->unlock();
137                 return;
138         }
141         item = new FrameCacheItem;
143         if(use_copy)
144         {
145                 item->data = new VFrame(*frame);
146         }
147         else
148         {
149                 item->data = frame;
150         }
152 // Copy metadata
153         item->position = position;
154         item->layer = layer;
155         item->frame_rate = frame_rate;
156         if(asset)
157         {
158                 item->asset_id = asset->id;
159                 item->path = strdup(asset->path);
160         }
161         else
162         {
163                 item->asset_id = -1;
164         }
165         item->age = get_age();
167         put_item(item);
168         lock->unlock();
174 int FrameCache::frame_exists(VFrame *format,
175         int64_t position, 
176         int layer,
177         double frame_rate,
178         FrameCacheItem **item_return,
179         int asset_id)
181         FrameCacheItem *item = (FrameCacheItem*)get_item(position);
182         while(item && item->position == position)
183         {
184                 if(EQUIV(item->frame_rate, frame_rate) &&
185                         layer == item->layer &&
186                         format->equivalent(item->data, 1) &&
187                         (asset_id == -1 || item->asset_id == -1 || asset_id == item->asset_id))
188                 {
189                         *item_return = item;
190                         return 1;
191                 }
192                 else
193                         item = (FrameCacheItem*)item->next;
194         }
195         return 0;
198 int FrameCache::frame_exists(int64_t position, 
199         int layer,
200         double frame_rate,
201         int color_model,
202         int w,
203         int h,
204         FrameCacheItem **item_return,
205         int asset_id)
207         FrameCacheItem *item = (FrameCacheItem*)get_item(position);
208         while(item && item->position == position)
209         {
210                 if(EQUIV(item->frame_rate, frame_rate) &&
211                         layer == item->layer &&
212                         color_model == item->data->get_color_model() &&
213                         w == item->data->get_w() &&
214                         h == item->data->get_h() &&
215                         (asset_id == -1 || item->asset_id == -1 || asset_id == item->asset_id))
216                 {
217                         *item_return = item;
218                         return 1;
219                 }
220                 else
221                         item = (FrameCacheItem*)item->next;
222         }
223         return 0;
227 void FrameCache::dump()
229 //      lock->lock("FrameCache::dump");
230 //      printf("FrameCache::dump 1 %d\n", items.total);
231 //      for(int i = 0; i < items.total; i++)
232 //      {
233 //              FrameCacheItem *item = (FrameCacheItem*)items.values[i];
234 //              printf("  position=%lld frame_rate=%f age=%d size=%d\n", 
235 //                      item->position, 
236 //                      item->frame_rate, 
237 //                      item->age,
238 //                      item->data->get_data_size());
239 //      }
240 //      lock->unlock();