r860: Merge 2.1:
[cinelerra_cv.git] / cinelerra / framecache.C
blobaf98b3ed433985e055e5daf35eab49d62588b80e
1 #include "bcsignals.h"
2 #include "clip.h"
3 #include "framecache.h"
4 #include "mutex.h"
5 #include "vframe.h"
8 #include <math.h>
9 #include <string.h>
13 FrameCacheItem::FrameCacheItem()
14  : CacheItemBase()
16         data = 0;
17         position = 0;
18         frame_rate = (double)30000.0 / 1001;
21 FrameCacheItem::~FrameCacheItem()
23         delete data;
26 int FrameCacheItem::get_size()
28         if(data) return data->get_data_size() + (path ? strlen(path) : 0);
29         return 0;
46 FrameCache::FrameCache()
47  : CacheBase()
51 FrameCache::~FrameCache()
56 // Returns 1 if frame exists in cache and copies it to the frame argument.
57 int FrameCache::get_frame(VFrame *frame, 
58         int64_t position,
59         double frame_rate)
61         lock->lock("FrameCache::get_frame");
62         FrameCacheItem *result = 0;
64         if(frame_exists(frame,
65                 position, 
66                 frame_rate,
67                 &result))
68         {
69                 if(result->data) 
70                 {
71                         frame->copy_from(result->data);
72                         frame->copy_stacks(result->data);
73                 }
74                 result->age = get_age();
75         }
77         lock->unlock();
78         if(result) return 1;
79         return 0;
83 VFrame* FrameCache::get_frame_ptr(int64_t position,
84         double frame_rate,
85         int color_model,
86         int w,
87         int h)
89         lock->lock("FrameCache::get_frame_ptr");
90         FrameCacheItem *result = 0;
91         if(frame_exists(position,
92                 frame_rate,
93                 color_model,
94                 w,
95                 h,
96                 &result))
97         {
98                 result->age = get_age();
99                 return result->data;
100         }
103         lock->unlock();
104         return 0;
107 // Puts frame in cache if enough space exists and the frame doesn't already
108 // exist.
109 void FrameCache::put_frame(VFrame *frame, 
110         int64_t position,
111         double frame_rate,
112         int use_copy)
114         lock->lock("FrameCache::put_frame");
115         FrameCacheItem *item = 0;
116         if(frame_exists(frame,
117                 position, 
118                 frame_rate,
119                 &item))
120         {
121                 item->age = get_age();
122                 lock->unlock();
123                 return;
124         }
127         item = new FrameCacheItem;
129         if(use_copy)
130         {
131                 item->data = new VFrame(*frame);
132         }
133         else
134         {
135                 item->data = frame;
136         }
138 // Copy metadata
139         item->position = position;
140         item->frame_rate = frame_rate;
141         item->age = get_age();
143         put_item(item);
144         lock->unlock();
150 int FrameCache::frame_exists(VFrame *format,
151         int64_t position, 
152         double frame_rate,
153         FrameCacheItem **item_return)
155         FrameCacheItem *item = (FrameCacheItem*)get_item(position);
156         while(item && item->position == position)
157         {
158                 if(EQUIV(item->frame_rate, frame_rate) &&
159                         format->equivalent(item->data, 1))
160                 {
161                         *item_return = item;
162                         return 1;
163                 }
164                 else
165                         item = (FrameCacheItem*)item->next;
166         }
167         return 0;
170 int FrameCache::frame_exists(int64_t position, 
171         double frame_rate,
172         int color_model,
173         int w,
174         int h,
175         FrameCacheItem **item_return)
177         FrameCacheItem *item = (FrameCacheItem*)get_item(position);
178         while(item && item->position == position)
179         {
180                 if(EQUIV(item->frame_rate, frame_rate) &&
181                         color_model == item->data->get_color_model() &&
182                         w == item->data->get_w() &&
183                         h == item->data->get_h())
184                 {
185                         *item_return = item;
186                         return 1;
187                 }
188                 else
189                         item = (FrameCacheItem*)item->next;
190         }
191         return 0;
195 void FrameCache::dump()
197 //      lock->lock("FrameCache::dump");
198 //      printf("FrameCache::dump 1 %d\n", items.total);
199 //      for(int i = 0; i < items.total; i++)
200 //      {
201 //              FrameCacheItem *item = (FrameCacheItem*)items.values[i];
202 //              printf("  position=%lld frame_rate=%f age=%d size=%d\n", 
203 //                      item->position, 
204 //                      item->frame_rate, 
205 //                      item->age,
206 //                      item->data->get_data_size());
207 //      }
208 //      lock->unlock();