4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcsignals.h"
26 #include "framecache.h"
27 #include "indexable.h"
39 FrameCacheItem::FrameCacheItem()
44 frame_rate = (double)30000.0 / 1001;
47 FrameCacheItem::~FrameCacheItem()
52 int FrameCacheItem::get_size()
54 if(data) return data->get_data_size() + (path ? strlen(path)+1 : 0);
72 FrameCache::FrameCache()
77 FrameCache::~FrameCache()
82 VFrame* FrameCache::get_frame_ptr(int64_t position, int layer, double frame_rate,
83 int color_model, int w, int h, int source_id)
85 lock->lock("FrameCache::get_frame_ptr");
86 VFrame *vframe = get_vframe(position, w, h, color_model,
87 layer, frame_rate, source_id);
88 if( vframe ) return vframe; // not unlocked
93 VFrame *FrameCache::get_vframe(int64_t position, int w, int h,
94 int color_model, int layer, double frame_rate,
97 FrameCacheItem *item = 0;
98 int ret = frame_exists(position, layer, frame_rate,
99 w, h, color_model, &item, source_id);
100 if( ret && position >= 0 && item )
101 item->age = get_age();
102 return ret && item ? item->data : 0;
105 VFrame *FrameCache::get_frame(int64_t position, int w, int h,
106 int color_model, int layer, double frame_rate,
109 lock->lock("FrameCache::get_frame");
110 VFrame *frame = get_vframe(position, w, h,
111 color_model, layer, frame_rate, source_id);
116 // Returns 1 if frame exists in cache and copies it to the frame argument.
117 int FrameCache::get_frame(VFrame *frame, int64_t position,
118 int layer, double frame_rate, int source_id)
120 lock->lock("FrameCache::get_frame");
121 VFrame *vframe = get_vframe(position,
122 frame->get_w(), frame->get_h(), frame->get_color_model(),
123 layer, frame_rate, source_id);
125 frame->copy_from(vframe);
127 return vframe ? 1 : 0;
131 void FrameCache::put_vframe(VFrame *frame, int64_t position,
132 int layer, double frame_rate, int source_id)
134 FrameCacheItem *item = new FrameCacheItem;
136 item->position = position;
138 item->frame_rate = frame_rate;
139 item->source_id = source_id;
140 item->age = position < 0 ? INT_MAX : get_age();
144 // Puts frame in cache if the frame doesn't already exist.
145 void FrameCache::put_frame(VFrame *frame, int64_t position,
146 int layer, double frame_rate, int use_copy, Indexable *idxbl)
148 int source_id = idxbl ? idxbl->id : -1;
149 lock->lock("FrameCache::put_frame");
150 VFrame *vframe = get_vframe(position,
151 frame->get_w(), frame->get_h(), frame->get_color_model(),
152 layer, frame_rate, source_id);
154 if( use_copy ) frame = new VFrame(*frame);
155 put_vframe(frame, position, layer, frame_rate, source_id);
160 // get vframe for keys, overwrite frame if found
161 int FrameCache::get_cache_frame(VFrame *frame, int64_t position,
162 int layer, double frame_rate)
164 lock->lock("FrameCache::get_cache_frame");
165 VFrame *vframe = get_vframe(position,
166 frame->get_w(), frame->get_h(), frame->get_color_model(),
167 layer, frame_rate, -1);
169 frame->copy_from(vframe);
171 return vframe ? 1 : 0;
174 // adds or replaces vframe, consumes frame if not use_copy
175 void FrameCache::put_cache_frame(VFrame *frame, int64_t position,
176 int layer, double frame_rate, int use_copy)
178 lock->lock("FrameCache::put_cache_frame");
179 FrameCacheItem *item = 0;
180 int w = frame->get_w(), h = frame->get_h();
181 int color_model = frame->get_color_model();
182 int ret = frame_exists(position, layer, frame_rate,
183 w, h, color_model, &item, -1);
185 // do not use shm here, puts too much pressure on 32bit systems
186 VFrame *vframe = new VFrame(w, h, color_model, 0);
187 vframe->copy_from(frame);
195 put_vframe(frame, position, layer, frame_rate, -1);
200 int FrameCache::frame_exists(VFrame *format, int64_t position,
201 int layer, double frame_rate, FrameCacheItem **item_return, int source_id)
203 FrameCacheItem *item = (FrameCacheItem*)get_item(position);
204 for( ; item && item->position == position; item = (FrameCacheItem*)item->next ) {
205 if( !EQUIV(item->frame_rate, frame_rate) ) continue;
206 if( layer != item->layer ) continue;
207 if( !format->equivalent(item->data, 0) ) continue;
208 if( source_id == -1 || item->source_id == -1 ||
209 source_id == item->source_id ) {
217 int FrameCache::frame_exists(int64_t position, int layer, double frame_rate,
218 int w, int h, int color_model, FrameCacheItem **item_return, int source_id)
220 FrameCacheItem *item = (FrameCacheItem*)get_item(position);
221 for( ; item && item->position == position ; item = (FrameCacheItem*)item->next ) {
222 if( !EQUIV(item->frame_rate, frame_rate) ) continue;
223 if( layer != item->layer ) continue;
224 if( color_model != item->data->get_color_model() ) continue;
225 if( w != item->data->get_w() ) continue;
226 if( h != item->data->get_h() ) continue;
227 if( source_id == -1 || item->source_id == -1 ||
228 source_id == item->source_id ) {
237 void FrameCache::dump()
239 // lock->lock("FrameCache::dump");
240 printf("FrameCache::dump 1 %d\n", total());
241 FrameCacheItem *item = (FrameCacheItem *)first;
243 printf(" position=%jd frame_rate=%f age=%d size=%ld\n",
244 item->position, item->frame_rate, item->age,
245 item->data->get_data_size());
246 item = (FrameCacheItem*)item->next;