9 #include "edlsession.h"
11 #include "framecache.h"
14 #include "mwindowgui.h"
15 #include "resourcethread.h"
16 #include "resourcepixmap.h"
17 #include "trackcanvas.h"
19 #include "wavecache.h"
22 ResourceThreadItem::ResourceThreadItem(ResourcePixmap *pixmap,
27 this->data_type = data_type;
28 this->pixmap = pixmap;
30 this->operation_count = operation_count;
31 asset->GarbageObject::add_user();
35 ResourceThreadItem::~ResourceThreadItem()
37 asset->GarbageObject::remove_user();
46 VResourceThreadItem::VResourceThreadItem(ResourcePixmap *pixmap,
56 : ResourceThreadItem(pixmap, asset, TRACK_VIDEO, operation_count)
58 this->picon_x = picon_x;
59 this->picon_y = picon_y;
60 this->picon_w = picon_w;
61 this->picon_h = picon_h;
62 this->frame_rate = frame_rate;
63 this->position = position;
67 VResourceThreadItem::~VResourceThreadItem()
78 AResourceThreadItem::AResourceThreadItem(ResourcePixmap *pixmap,
85 : ResourceThreadItem(pixmap, asset, TRACK_AUDIO, operation_count)
88 this->channel = channel;
93 AResourceThreadItem::~AResourceThreadItem()
113 ResourceThread::ResourceThread(MWindow *mwindow)
115 this->mwindow = mwindow;
119 draw_lock = new Condition(0, "ResourceThread::draw_lock", 0);
120 // interrupted_lock = new Condition(0, "ResourceThread::interrupted_lock", 0);
121 item_lock = new Mutex("ResourceThread::item_lock");
130 ResourceThread::~ResourceThread()
133 // delete interrupted_lock;
137 delete [] audio_buffer;
141 void ResourceThread::create_objects()
146 void ResourceThread::add_picon(ResourcePixmap *pixmap,
156 item_lock->lock("ResourceThread::item_lock");
158 items.append(new VResourceThreadItem(pixmap,
171 void ResourceThread::add_wave(ResourcePixmap *pixmap,
175 int64_t source_start,
178 item_lock->lock("ResourceThread::item_lock");
180 items.append(new AResourceThreadItem(pixmap,
200 void ResourceThread::stop_draw(int reset)
205 item_lock->lock("ResourceThread::stop_draw");
206 if(reset) items.remove_all_objects();
215 void ResourceThread::start_draw()
218 // Tag last audio item to cause refresh.
219 for(int i = items.total - 1; i >= 0; i--)
221 ResourceThreadItem *item = items.values[i];
222 if(item->data_type == TRACK_AUDIO)
232 void ResourceThread::run()
237 draw_lock->lock("ResourceThread::run");
244 item_lock->lock("ResourceThread::run");
245 int total_items = items.total;
246 ResourceThreadItem *item = 0;
249 item = items.values[0];
250 items.remove_number(0);
254 if(!total_items) break;
257 if(item->data_type == TRACK_VIDEO)
260 do_video((VResourceThreadItem*)item);
263 if(item->data_type == TRACK_AUDIO)
265 do_audio((AResourceThreadItem*)item);
276 void ResourceThread::do_video(VResourceThreadItem *item)
279 (temp_picon->get_w() != item->asset->width ||
280 temp_picon->get_h() != item->asset->height))
288 temp_picon = new VFrame(0,
294 // Get temporary to copy cached frame to
296 (temp_picon2->get_w() != item->picon_w ||
297 temp_picon2->get_h() != item->picon_h))
305 temp_picon2 = new VFrame(0,
313 // Search frame cache again.
315 VFrame *picon_frame = 0;
317 if((picon_frame = mwindow->frame_cache->get_frame_ptr(item->position,
323 item->asset->id)) != 0)
325 temp_picon2->copy_from(picon_frame);
326 // Unlock the get_frame_ptr command
327 mwindow->frame_cache->unlock();
332 File *source = mwindow->video_cache->check_out(item->asset,
338 source->set_layer(item->layer);
339 source->set_video_position(item->position,
342 source->read_frame(temp_picon);
343 picon_frame = new VFrame(0, item->picon_w, item->picon_h, BC_RGB888);
344 cmodel_transfer(picon_frame->get_rows(),
345 temp_picon->get_rows(),
358 picon_frame->get_w(),
359 picon_frame->get_h(),
363 temp_picon->get_bytes_per_line(),
364 picon_frame->get_bytes_per_line());
365 temp_picon2->copy_from(picon_frame);
366 mwindow->frame_cache->put_frame(picon_frame,
369 mwindow->edl->session->frame_rate,
372 mwindow->video_cache->check_in(item->asset);
384 mwindow->gui->lock_window("ResourceThread::do_video");
388 mwindow->gui->unlock_window();
394 // Test for pixmap existence first
395 if(item->operation_count == operation_count)
398 for(int i = 0; i < mwindow->gui->canvas->resource_pixmaps.total; i++)
400 if(mwindow->gui->canvas->resource_pixmaps.values[i] == item->pixmap)
405 item->pixmap->draw_vframe(temp_picon2,
412 mwindow->gui->update(0, 3, 0, 0, 0, 0, 0);
416 mwindow->gui->unlock_window();
420 #define BUFFERSIZE 65536
421 void ResourceThread::do_audio(AResourceThreadItem *item)
424 WaveCacheItem *wave_item;
428 if((wave_item = mwindow->wave_cache->get_wave(item->asset->id,
433 high = wave_item->high;
434 low = wave_item->low;
435 mwindow->wave_cache->unlock();
439 int first_sample = 1;
440 int64_t start = item->start;
441 int64_t end = item->end;
442 if(start == end) end = start + 1;
444 for(int64_t sample = start; sample < end; sample++)
447 // Get value from previous buffer
449 item->channel == audio_channel &&
450 item->asset->id == audio_asset_id &&
451 sample >= audio_start &&
452 sample < audio_start + audio_samples)
459 File *source = mwindow->audio_cache->check_out(item->asset,
464 source->set_channel(item->channel);
465 source->set_audio_position(sample, item->asset->sample_rate);
466 int64_t total_samples = source->get_audio_length(-1);
467 if(!audio_buffer) audio_buffer = new double[BUFFERSIZE];
468 int fragment = BUFFERSIZE;
469 if(fragment + sample > total_samples)
470 fragment = total_samples - sample;
471 source->read_samples(audio_buffer, fragment, item->asset->sample_rate);
472 audio_channel = item->channel;
473 audio_start = sample;
474 audio_samples = fragment;
475 audio_asset_id = item->asset->id;
476 mwindow->audio_cache->check_in(item->asset);
480 value = audio_buffer[sample - audio_start];
496 mwindow->wave_cache->put_wave(item->asset,
509 mwindow->gui->lock_window("ResourceThread::do_audio");
512 mwindow->gui->unlock_window();
516 if(item->operation_count == operation_count)
519 // Test for pixmap existence first
521 for(int i = 0; i < mwindow->gui->canvas->resource_pixmaps.total; i++)
523 if(mwindow->gui->canvas->resource_pixmaps.values[i] == item->pixmap)
529 if(prev_x == item->x - 1)
531 high = MAX(high, prev_l);
532 low = MIN(low, prev_h);
537 item->pixmap->draw_wave(item->x, high, low);
538 if(timer->get_difference() > 250 || item->last)
540 mwindow->gui->update(0, 3, 0, 0, 0, 0, 0);
546 mwindow->gui->unlock_window();