8 #include "edlsession.h"
10 #include "filesystem.h"
12 #include "preferences.h"
16 // edl came from a command which won't exist anymore
17 CICache::CICache(Preferences *preferences,
18 ArrayList<PluginServer*> *plugindb)
21 this->plugindb = plugindb;
22 this->preferences = preferences;
23 check_out_lock = new Condition(0, "CICache::check_out_lock", 0);
24 total_lock = new Mutex("CICache::total_lock");
31 CICacheItem *item = last;
32 //printf("CICache::~CICache: %s\n", item->asset->path);
34 Garbage::delete_object(item);
36 delete check_out_lock;
45 File* CICache::check_out(Asset *asset, EDL *edl, int block)
47 CICacheItem *current, *new_item = 0;
51 // Scan directory for item
53 total_lock->lock("CICache::check_out");
54 for(current = first; current && !got_it; current = NEXT)
56 if(!strcmp(current->asset->path, asset->path))
66 if(!current->checked_out)
69 current->age = EDL::next_id();
70 current->checked_out = 1;
71 current->GarbageObject::add_user();
79 new_item = append(new CICacheItem(this, edl, asset));
83 // opened successfully.
84 new_item->age = EDL::next_id();
85 new_item->checked_out = 1;
86 new_item->GarbageObject::add_user();
88 return new_item->file;
93 remove_pointer(new_item);
94 Garbage::delete_object(new_item);
100 // Try again after blocking
101 total_lock->unlock();
103 check_out_lock->lock("CICache::check_out");
111 int CICache::check_in(Asset *asset)
113 CICacheItem *current;
116 total_lock->lock("CICache::check_in");
117 for(current = first; current; current = NEXT)
119 // Need to compare paths because
120 // asset pointers are different
121 if(!strcmp(current->asset->path, asset->path))
123 current->checked_out = 0;
124 current->GarbageObject::remove_user();
125 // Pointer no longer valid here
129 total_lock->unlock();
131 // Release for blocking check_out operations
132 check_out_lock->unlock();
138 void CICache::remove_all()
140 total_lock->lock("CICache::remove_all");
141 CICacheItem *current, *temp;
142 for(current = first; current; current = temp)
144 temp = current->next;
145 // Must not be checked out because we need the pointer to check back in.
146 // Really need to give the user the CacheItem.
147 if(!current->checked_out)
149 //printf("CICache::remove_all: %s\n", current->asset->path);
150 remove_pointer(current);
151 Garbage::delete_object(current);
154 total_lock->unlock();
157 int CICache::delete_entry(char *path)
159 total_lock->lock("CICache::delete_entry");
160 for(CICacheItem *current = first; current; current = NEXT)
162 if(!strcmp(current->asset->path, path))
164 if(!current->checked_out)
166 //printf("CICache::delete_entry: %s\n", current->asset->path);
167 remove_pointer(current);
168 Garbage::delete_object(current);
173 total_lock->unlock();
177 int CICache::delete_entry(Asset *asset)
179 total_lock->lock("CICache::delete_entry");
181 CICacheItem *current, *temp;
183 for(current = first; current; current = NEXT)
185 if(!strcmp(current->asset->path, asset->path))
187 if(!current->checked_out)
189 //printf("CICache::delete_entry: %s\n", current->asset->path);
190 remove_pointer(current);
191 Garbage::delete_object(current);
197 total_lock->unlock();
203 CICacheItem *current;
205 // delete old assets if memory usage is exceeded
206 int64_t prev_memory_usage;
207 int64_t memory_usage;
211 memory_usage = get_memory_usage(1);
213 if(memory_usage > preferences->cache_size)
215 //printf("CICache::age 3 %p %lld %lld\n", this, memory_usage, preferences->cache_size);
216 result = delete_oldest();
218 prev_memory_usage = memory_usage;
219 memory_usage = get_memory_usage(0);
220 }while(prev_memory_usage != memory_usage &&
221 memory_usage > preferences->cache_size &&
226 int64_t CICache::get_memory_usage(int use_lock)
228 CICacheItem *current;
230 if(use_lock) total_lock->lock("CICache::get_memory_usage");
231 for(current = first; current; current = NEXT)
233 File *file = current->file;
234 if(file) result += file->get_memory_usage();
236 if(use_lock) total_lock->unlock();
240 int CICache::get_oldest()
242 CICacheItem *current;
243 int oldest = 0x7fffffff;
244 total_lock->lock("CICache::get_oldest");
245 for(current = last; current; current = PREVIOUS)
247 if(current->age < oldest)
249 oldest = current->age;
252 total_lock->unlock();
257 int CICache::delete_oldest()
259 CICacheItem *current;
260 int lowest_age = 0x7fffffff;
261 CICacheItem *oldest = 0;
263 total_lock->lock("CICache::delete_oldest");
265 for(current = last; current; current = PREVIOUS)
267 if(current->age < lowest_age)
270 lowest_age = current->age;
277 // Got the oldest file. Try requesting cache purge.
279 if(!oldest->file || oldest->file->purge_cache())
282 // Delete the file if cache already empty and not checked out.
283 if(!oldest->checked_out)
286 remove_pointer(oldest);
288 Garbage::delete_object(oldest);
294 total_lock->unlock();
300 total_lock->unlock();
301 // nothing was old enough to delete
308 CICacheItem *current;
309 total_lock->lock("CICache::dump");
310 printf("CICache::dump total size %lld\n", get_memory_usage(0));
311 for(current = first; current; current = NEXT)
313 printf("cache item %x asset %x %s age=%d\n",
316 current->asset->path,
319 total_lock->unlock();
330 CICacheItem::CICacheItem()
331 : ListItem<CICacheItem>(), GarbageObject("CICacheItem")
336 CICacheItem::CICacheItem(CICache *cache, EDL *edl, Asset *asset)
337 : ListItem<CICacheItem>(), GarbageObject("CICacheItem")
340 age = EDL::next_id();
342 this->asset = new Asset;
344 item_lock = new Condition(1, "CICacheItem::item_lock", 0);
347 // Must copy Asset since this belongs to an EDL which won't exist forever.
348 *this->asset = *asset;
354 file->set_processors(cache->preferences->processors);
355 file->set_preload(edl->session->playback_preload);
356 file->set_subtitle(edl->session->decode_subtitles ?
357 edl->session->subtitle_number : -1);
358 file->set_interpolate_raw(edl->session->interpolate_raw);
359 file->set_white_balance_raw(edl->session->white_balance_raw);
362 // Copy decoding parameters from session to asset so file can see them.
363 this->asset->divx_use_deblocking = edl->session->mpeg4_deblock;
367 if(result = file->open_file(cache->preferences, this->asset, 1, 0, -1, -1))
377 CICacheItem::~CICacheItem()
379 if(file) delete file;
380 if(asset) Garbage::delete_object(asset);
381 if(item_lock) delete item_lock;