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;
39 VResourceThreadItem::VResourceThreadItem(ResourcePixmap *pixmap,
49 : ResourceThreadItem(pixmap, asset, TRACK_VIDEO, operation_count)
51 this->picon_x = picon_x;
52 this->picon_y = picon_y;
53 this->picon_w = picon_w;
54 this->picon_h = picon_h;
55 this->frame_rate = frame_rate;
56 this->position = position;
60 VResourceThreadItem::~VResourceThreadItem()
71 AResourceThreadItem::AResourceThreadItem(ResourcePixmap *pixmap,
78 : ResourceThreadItem(pixmap, asset, TRACK_AUDIO, operation_count)
81 this->channel = channel;
86 AResourceThreadItem::~AResourceThreadItem()
106 ResourceThread::ResourceThread(MWindow *mwindow)
108 this->mwindow = mwindow;
112 draw_lock = new Condition(0, "ResourceThread::draw_lock", 0);
113 // interrupted_lock = new Condition(0, "ResourceThread::interrupted_lock", 0);
114 item_lock = new Mutex("ResourceThread::item_lock");
123 ResourceThread::~ResourceThread()
126 // delete interrupted_lock;
130 delete [] audio_buffer;
134 void ResourceThread::create_objects()
139 void ResourceThread::add_picon(ResourcePixmap *pixmap,
149 item_lock->lock("ResourceThread::item_lock");
151 items.append(new VResourceThreadItem(pixmap,
164 void ResourceThread::add_wave(ResourcePixmap *pixmap,
168 int64_t source_start,
171 item_lock->lock("ResourceThread::item_lock");
173 items.append(new AResourceThreadItem(pixmap,
193 void ResourceThread::stop_draw(int reset)
198 item_lock->lock("ResourceThread::stop_draw");
199 if(reset) items.remove_all_objects();
208 void ResourceThread::start_draw()
211 // Tag last audio item to cause refresh.
212 for(int i = items.total - 1; i >= 0; i--)
214 ResourceThreadItem *item = items.values[i];
215 if(item->data_type == TRACK_AUDIO)
225 void ResourceThread::run()
230 draw_lock->lock("ResourceThread::run");
237 item_lock->lock("ResourceThread::run");
238 int total_items = items.total;
239 ResourceThreadItem *item = 0;
242 item = items.values[0];
243 items.remove_number(0);
247 if(!total_items) break;
250 if(item->data_type == TRACK_VIDEO)
253 do_video((VResourceThreadItem*)item);
256 if(item->data_type == TRACK_AUDIO)
258 do_audio((AResourceThreadItem*)item);
269 void ResourceThread::do_video(VResourceThreadItem *item)
272 (temp_picon->get_w() != item->asset->width ||
273 temp_picon->get_h() != item->asset->height))
281 temp_picon = new VFrame(0,
287 // Get temporary to copy cached frame to
289 (temp_picon2->get_w() != item->picon_w ||
290 temp_picon2->get_h() != item->picon_h))
298 temp_picon2 = new VFrame(0,
306 // Search frame cache again.
308 VFrame *picon_frame = 0;
310 if((picon_frame = mwindow->frame_cache->get_frame_ptr(item->position,
316 item->asset->id)) != 0)
318 temp_picon2->copy_from(picon_frame);
319 // Unlock the get_frame_ptr command
320 mwindow->frame_cache->unlock();
325 File *source = mwindow->video_cache->check_out(item->asset,
331 source->set_layer(item->layer);
332 source->set_video_position(item->position,
335 source->read_frame(temp_picon);
336 picon_frame = new VFrame(0, item->picon_w, item->picon_h, BC_RGB888);
337 cmodel_transfer(picon_frame->get_rows(),
338 temp_picon->get_rows(),
351 picon_frame->get_w(),
352 picon_frame->get_h(),
356 temp_picon->get_bytes_per_line(),
357 picon_frame->get_bytes_per_line());
358 temp_picon2->copy_from(picon_frame);
359 mwindow->frame_cache->put_frame(picon_frame,
362 mwindow->edl->session->frame_rate,
365 mwindow->video_cache->check_in(item->asset);
377 mwindow->gui->lock_window("ResourceThread::do_video");
381 mwindow->gui->unlock_window();
387 // Test for pixmap existence first
388 if(item->operation_count == operation_count)
391 for(int i = 0; i < mwindow->gui->canvas->resource_pixmaps.total; i++)
393 if(mwindow->gui->canvas->resource_pixmaps.values[i] == item->pixmap)
398 item->pixmap->draw_vframe(temp_picon2,
405 mwindow->gui->update(0, 3, 0, 0, 0, 0, 0);
409 mwindow->gui->unlock_window();
413 #define BUFFERSIZE 65536
414 void ResourceThread::do_audio(AResourceThreadItem *item)
417 WaveCacheItem *wave_item;
421 if((wave_item = mwindow->wave_cache->get_wave(item->asset->id,
426 high = wave_item->high;
427 low = wave_item->low;
428 mwindow->wave_cache->unlock();
432 int first_sample = 1;
433 int64_t start = item->start;
434 int64_t end = item->end;
435 if(start == end) end = start + 1;
437 for(int64_t sample = start; sample < end; sample++)
440 // Get value from previous buffer
442 item->channel == audio_channel &&
443 item->asset->id == audio_asset_id &&
444 sample >= audio_start &&
445 sample < audio_start + audio_samples)
452 File *source = mwindow->audio_cache->check_out(item->asset,
457 source->set_channel(item->channel);
458 source->set_audio_position(sample, item->asset->sample_rate);
459 int64_t total_samples = source->get_audio_length(-1);
460 if(!audio_buffer) audio_buffer = new double[BUFFERSIZE];
461 int fragment = BUFFERSIZE;
462 if(fragment + sample > total_samples)
463 fragment = total_samples - sample;
464 source->read_samples(audio_buffer, fragment, item->asset->sample_rate);
465 audio_channel = item->channel;
466 audio_start = sample;
467 audio_samples = fragment;
468 audio_asset_id = item->asset->id;
469 mwindow->audio_cache->check_in(item->asset);
473 value = audio_buffer[sample - audio_start];
489 mwindow->wave_cache->put_wave(item->asset,
502 mwindow->gui->lock_window("ResourceThread::do_audio");
505 mwindow->gui->unlock_window();
509 if(item->operation_count == operation_count)
512 // Test for pixmap existence first
514 for(int i = 0; i < mwindow->gui->canvas->resource_pixmaps.total; i++)
516 if(mwindow->gui->canvas->resource_pixmaps.values[i] == item->pixmap)
522 if(prev_x == item->x - 1)
524 high = MAX(high, prev_l);
525 low = MIN(low, prev_h);
530 item->pixmap->draw_wave(item->x, high, low);
531 if(timer->get_difference() > 250 || item->last)
533 mwindow->gui->update(0, 3, 0, 0, 0, 0, 0);
539 mwindow->gui->unlock_window();
549 // c-file-style: "linux"