10 #include "edlsession.h"
12 #include "filesystem.h"
14 #include "preferences.h"
18 // edl came from a command which won't exist anymore
19 CICache::CICache(Preferences *preferences,
20 ArrayList<PluginServer*> *plugindb)
23 this->plugindb = plugindb;
24 this->preferences = preferences;
25 check_out_lock = new Condition(0, "CICache::check_out_lock", 0);
26 total_lock = new Mutex("CICache::total_lock");
33 CICacheItem *item = last;
34 //printf("CICache::~CICache: %s\n", item->asset->path);
36 Garbage::delete_object(item);
38 delete check_out_lock;
47 File* CICache::check_out(Asset_GC asset, EDL *edl, int block)
49 CICacheItem *current, *new_item = 0;
53 // Scan directory for item
55 total_lock->lock("CICache::check_out");
56 for(current = first; current && !got_it; current = NEXT)
58 if(!strcmp(current->asset->path, asset->path))
68 if(!current->checked_out)
71 current->age = EDL::next_id();
72 current->checked_out = 1;
73 current->GarbageObject::add_user();
81 new_item = append(new CICacheItem(this, edl, asset));
85 // opened successfully.
86 new_item->age = EDL::next_id();
87 new_item->checked_out = 1;
88 new_item->GarbageObject::add_user();
90 return new_item->file;
95 remove_pointer(new_item);
96 Garbage::delete_object(new_item);
102 // Try again after blocking
103 total_lock->unlock();
105 check_out_lock->lock("CICache::check_out");
113 int CICache::check_in(Asset_GC asset)
115 CICacheItem *current;
118 total_lock->lock("CICache::check_in");
119 for(current = first; current; current = NEXT)
121 // Need to compare paths because
122 // asset pointers are different
123 if(!strcmp(current->asset->path, asset->path))
125 current->checked_out = 0;
126 current->GarbageObject::remove_user();
127 // Pointer no longer valid here
131 total_lock->unlock();
133 // Release for blocking check_out operations
134 check_out_lock->unlock();
140 void CICache::remove_all()
142 total_lock->lock("CICache::remove_all");
143 CICacheItem *current, *temp;
144 for(current = first; current; current = temp)
146 temp = current->next;
147 // Must not be checked out because we need the pointer to check back in.
148 // Really need to give the user the CacheItem.
149 if(!current->checked_out)
151 //printf("CICache::remove_all: %s\n", current->asset->path);
152 remove_pointer(current);
153 Garbage::delete_object(current);
156 total_lock->unlock();
159 int CICache::delete_entry(char *path)
161 total_lock->lock("CICache::delete_entry");
162 for(CICacheItem *current = first; current; current = NEXT)
164 if(!strcmp(current->asset->path, path))
166 if(!current->checked_out)
168 //printf("CICache::delete_entry: %s\n", current->asset->path);
169 remove_pointer(current);
170 Garbage::delete_object(current);
175 total_lock->unlock();
179 int CICache::delete_entry(Asset_GC asset)
181 total_lock->lock("CICache::delete_entry");
183 CICacheItem *current, *temp;
185 for(current = first; current; current = NEXT)
187 if(!strcmp(current->asset->path, asset->path))
189 if(!current->checked_out)
191 //printf("CICache::delete_entry: %s\n", current->asset->path);
192 remove_pointer(current);
193 Garbage::delete_object(current);
199 total_lock->unlock();
205 CICacheItem *current;
207 // delete old assets if memory usage is exceeded
208 int64_t prev_memory_usage;
209 int64_t memory_usage;
213 memory_usage = get_memory_usage(1);
215 if(memory_usage > preferences->cache_size)
217 //printf("CICache::age 3 %p %lld %lld\n", this, memory_usage, preferences->cache_size);
218 result = delete_oldest();
220 prev_memory_usage = memory_usage;
221 memory_usage = get_memory_usage(0);
222 }while(prev_memory_usage != memory_usage &&
223 memory_usage > preferences->cache_size &&
228 int64_t CICache::get_memory_usage(int use_lock)
230 CICacheItem *current;
232 if(use_lock) total_lock->lock("CICache::get_memory_usage");
233 for(current = first; current; current = NEXT)
235 File *file = current->file;
236 if(file) result += file->get_memory_usage();
238 if(use_lock) total_lock->unlock();
242 int CICache::get_oldest()
244 CICacheItem *current;
245 int oldest = 0x7fffffff;
246 total_lock->lock("CICache::get_oldest");
247 for(current = last; current; current = PREVIOUS)
249 if(current->age < oldest)
251 oldest = current->age;
254 total_lock->unlock();
259 int CICache::delete_oldest()
261 CICacheItem *current;
262 int lowest_age = 0x7fffffff;
263 CICacheItem *oldest = 0;
265 total_lock->lock("CICache::delete_oldest");
267 for(current = last; current; current = PREVIOUS)
269 if(current->age < lowest_age)
272 lowest_age = current->age;
279 // Got the oldest file. Try requesting cache purge.
281 if(!oldest->file || oldest->file->purge_cache())
284 // Delete the file if cache already empty and not checked out.
285 if(!oldest->checked_out)
288 remove_pointer(oldest);
290 Garbage::delete_object(oldest);
296 total_lock->unlock();
302 total_lock->unlock();
303 // nothing was old enough to delete
310 CICacheItem *current;
311 total_lock->lock("CICache::dump");
312 printf("CICache::dump total size %lld\n", get_memory_usage(0));
313 for(current = first; current; current = NEXT)
315 printf("cache item %x asset %x %s age=%d\n",
317 current->asset.get(),
318 current->asset->path,
321 total_lock->unlock();
332 CICacheItem::CICacheItem()
333 : ListItem<CICacheItem>(), GarbageObject("CICacheItem")
338 CICacheItem::CICacheItem(CICache *cache, EDL *edl, Asset_GC asset)
339 : ListItem<CICacheItem>(), GarbageObject("CICacheItem")
342 age = EDL::next_id();
344 this->asset = Asset_GC(new Asset);
346 item_lock = new Condition(1, "CICacheItem::item_lock", 0);
349 // Must copy Asset since this belongs to an EDL which won't exist forever.
350 *this->asset = *asset;
356 file->set_processors(cache->preferences->processors);
357 file->set_preload(edl->session->playback_preload);
358 file->set_subtitle(edl->session->decode_subtitles ?
359 edl->session->subtitle_number : -1);
360 file->set_interpolate_raw(edl->session->interpolate_raw);
361 file->set_white_balance_raw(edl->session->white_balance_raw);
364 // Copy decoding parameters from session to asset so file can see them.
365 this->asset->divx_use_deblocking = edl->session->mpeg4_deblock;
369 if(result = file->open_file(cache->preferences, this->asset, 1, 0, -1, -1))
379 CICacheItem::~CICacheItem()
381 if(file) delete file;
382 if(item_lock) delete item_lock;
387 // c-file-style: "linux"