}
-
-
-
-
-
-VResourceThreadItem::VResourceThreadItem(ResourcePixmap *pixmap,
- int pane_number,
- int picon_x,
- int picon_y,
- int picon_w,
- int picon_h,
- double frame_rate,
- int64_t position,
- int layer,
- Indexable *indexable,
- int operation_count)
- : ResourceThreadItem(pixmap,
- pane_number,
- indexable,
- TRACK_VIDEO,
- operation_count)
+VResourceThreadItem::VResourceThreadItem(ResourcePixmap *pixmap, int pane_number,
+ int picon_x, int picon_y, int picon_w, int picon_h,
+ double frame_rate, int64_t position, int layer,
+ Indexable *indexable, int operation_count)
+ : ResourceThreadItem(pixmap, pane_number,
+ indexable, TRACK_VIDEO, operation_count)
{
this->picon_x = picon_x;
this->picon_y = picon_y;
}
-
-
-
-
-
-
-AResourceThreadItem::AResourceThreadItem(ResourcePixmap *pixmap,
- int pane_number,
- Indexable *indexable,
- int x,
- int channel,
- int64_t start,
- int64_t end,
- int operation_count)
- : ResourceThreadItem(pixmap,
- pane_number,
- indexable,
- TRACK_AUDIO,
- operation_count)
+AResourceThreadItem::AResourceThreadItem(ResourcePixmap *pixmap, int pane_number,
+ Indexable *indexable, int x, int channel,
+ int64_t start, int64_t end, int operation_count)
+ : ResourceThreadItem(pixmap, pane_number,
+ indexable, TRACK_AUDIO, operation_count)
{
this->x = x;
this->channel = channel;
{
}
+ResourceAudioThread::ResourceAudioThread(ResourceThread *resource_thread)
+ : ResourceThreadBase(resource_thread)
+{
+ this->resource_thread = resource_thread;
+ audio_buffer = 0;
+ audio_asset = 0;
+ audio_source = 0;
+ for(int i = 0; i < MAXCHANNELS; i++)
+ temp_buffer[i] = 0;
+ timer = new Timer;
+ prev_x = -1;
+ prev_h = 0;
+ prev_l = 0;
+}
+ResourceAudioThread::~ResourceAudioThread()
+{
+ delete audio_buffer;
+ for(int i = 0; i < MAXCHANNELS; i++)
+ delete temp_buffer[i];
+ delete timer;
+ if( audio_asset ) audio_asset->remove_user();
+}
+void ResourceAudioThread::start_draw()
+{
+ prev_x = -1;
+ prev_h = 0;
+ prev_l = 0;
+ ResourceThreadItem *item = items.last;
+// Tag last audio item to cause refresh.
+ if( item ) item->last = 1;
+ timer->update();
+ ResourceThreadBase::start_draw();
+}
+File *ResourceAudioThread::get_audio_source(Asset *asset)
+{
+ MWindow *mwindow = resource_thread->mwindow;
+ if( interrupted ) asset = 0;
+ if( audio_asset && audio_asset != asset && (!asset ||
+ strcmp(audio_asset->path, asset->path)) ) {
+ mwindow->audio_cache->check_in(audio_asset);
+ audio_source = 0;
+ audio_asset->remove_user();
+ audio_asset = 0;
+ }
+ if( !audio_asset && asset ) {
+ audio_asset = asset;
+ audio_asset->add_user();
+ audio_source = mwindow->audio_cache->check_out(asset, mwindow->edl);
+ }
+ return audio_source;
+}
+void ResourceAudioThread::add_wave(ResourcePixmap *pixmap, int pane_number,
+ Indexable *indexable, int x, int channel,
+ int64_t source_start, int64_t source_end)
+{
+ item_lock->lock("ResourceThreadBase::item_lock");
+ items.append(new AResourceThreadItem(pixmap, pane_number,
+ indexable, x, channel, source_start, source_end,
+ resource_thread->operation_count));
+ item_lock->unlock();
+}
+ResourceVideoThread::ResourceVideoThread(ResourceThread *resource_thread)
+ : ResourceThreadBase(resource_thread)
+{
+ this->resource_thread = resource_thread;
+ video_asset = 0;
+ video_source = 0;
+ temp_picon = 0;
+ temp_picon2 = 0;
+}
+ResourceVideoThread::~ResourceVideoThread()
+{
+ delete temp_picon;
+ delete temp_picon2;
+ if( video_asset ) video_asset->remove_user();
+}
+File *ResourceVideoThread::get_video_source(Asset *asset)
+{
+ MWindow *mwindow = resource_thread->mwindow;
+ if( interrupted ) asset = 0;
+ if( video_asset && video_asset != asset && (!asset ||
+ strcmp(video_asset->path, asset->path)) ) {
+ mwindow->video_cache->check_in(video_asset);
+ video_source = 0;
+ video_asset->remove_user();
+ video_asset = 0;
+ }
+ if( !video_asset && asset ) {
+ video_asset = asset;
+ video_asset->add_user();
+ video_source = mwindow->video_cache->check_out(asset, mwindow->edl);
+ }
+ return video_source;
+}
+void ResourceVideoThread::add_picon(ResourcePixmap *pixmap, int pane_number,
+ int picon_x, int picon_y, int picon_w, int picon_h,
+ double frame_rate, int64_t position, int layer,
+ Indexable *indexable)
+{
+ item_lock->lock("ResourceThreadBase::item_lock");
+ items.append(new VResourceThreadItem(pixmap, pane_number,
+ picon_x, picon_y, picon_w, picon_h,
+ frame_rate, position, layer, indexable,
+ resource_thread->operation_count));
+ item_lock->unlock();
+}
-
-ResourceThread::ResourceThread(MWindow *mwindow, MWindowGUI *gui)
+ResourceThreadBase::ResourceThreadBase(ResourceThread *resource_thread)
: Thread(1, 0, 0)
{
-//printf("ResourceThread::ResourceThread %d %p\n", __LINE__, this);
- this->mwindow = mwindow;
- this->gui = gui;
+ this->resource_thread = resource_thread;
interrupted = 1;
done = 1;
- temp_picon = 0;
- temp_picon2 = 0;
- draw_lock = new Condition(0, "ResourceThread::draw_lock", 0);
- item_lock = new Mutex("ResourceThread::item_lock");
- audio_buffer = 0;
- for(int i = 0; i < MAXCHANNELS; i++)
- temp_buffer[i] = 0;
- timer = new Timer;
- prev_x = -1;
- prev_h = 0;
- prev_l = 0;
- operation_count = 0;
+ draw_lock = new Condition(0, "ResourceThreadBase::draw_lock", 0);
+ item_lock = new Mutex("ResourceThreadBase::item_lock");
render_engine = 0;
render_engine_id = -1;
- audio_asset = 0;
- audio_source = 0;
- video_asset = 0;
- video_source = 0;
}
-ResourceThread::~ResourceThread()
+ResourceThreadBase::~ResourceThreadBase()
{
stop();
delete draw_lock;
delete item_lock;
- delete temp_picon;
- delete temp_picon2;
- delete audio_buffer;
- for(int i = 0; i < MAXCHANNELS; i++)
- delete temp_buffer[i];
- delete timer;
delete render_engine;
- if( audio_asset ) audio_asset->remove_user();
- if( video_asset ) video_asset->remove_user();
}
-void ResourceThread::create_objects()
+void ResourceThreadBase::create_objects()
{
done = 0;
Thread::start();
}
-void ResourceThread::add_picon(ResourcePixmap *pixmap,
- int pane_number,
- int picon_x,
- int picon_y,
- int picon_w,
- int picon_h,
- double frame_rate,
- int64_t position,
- int layer,
- Indexable *indexable)
-{
- item_lock->lock("ResourceThread::item_lock");
-
- items.append(new VResourceThreadItem(pixmap,
- pane_number,
- picon_x,
- picon_y,
- picon_w,
- picon_h,
- frame_rate,
- position,
- layer,
- indexable,
- operation_count));
- item_lock->unlock();
-}
-
-void ResourceThread::add_wave(ResourcePixmap *pixmap,
- int pane_number,
- Indexable *indexable,
- int x,
- int channel,
- int64_t source_start,
- int64_t source_end)
-{
- item_lock->lock("ResourceThread::item_lock");
-
- items.append(new AResourceThreadItem(pixmap,
- pane_number,
- indexable,
- x,
- channel,
- source_start,
- source_end,
- operation_count));
- item_lock->unlock();
-}
-
-void ResourceThread::reset(int pane_number)
+void ResourceThreadBase::reset(int pane_number)
{
- item_lock->lock("ResourceThread::reset");
+ item_lock->lock("ResourceThreadBase::reset");
ResourceThreadItem *item = items.first;
while( item ) {
ResourceThreadItem *next_item = item->next;
item_lock->unlock();
}
-
-
-
-
-
-
-
-
-
-void ResourceThread::stop_draw(int reset)
+void ResourceThreadBase::stop_draw(int reset)
{
- if(!interrupted)
- {
+ if( !interrupted ) {
interrupted = 1;
- item_lock->lock("ResourceThread::stop_draw");
-
-//printf("ResourceThread::stop_draw %d %d\n", __LINE__, reset);
+ item_lock->lock("ResourceThreadBase::stop_draw");
+//printf("ResourceThreadBase::stop_draw %d %d\n", __LINE__, reset);
//BC_Signals::dump_stack();
if( reset ) {
ResourceThreadItem *item;
while( (item=items.last) != 0 ) delete item;
- ++operation_count;
}
item_lock->unlock();
- prev_x = -1;
- prev_h = 0;
- prev_l = 0;
}
}
-void ResourceThread::start_draw()
+void ResourceThreadBase::start_draw()
{
interrupted = 0;
-// Tag last audio item to cause refresh.
- ResourceThreadItem *item = items.last;
- while( item && item->data_type!=TRACK_AUDIO ) item = item->previous;
- if( item ) item->last = 1;
- timer->update();
draw_lock->unlock();
}
-void ResourceThread::run()
+void ResourceThreadBase::run()
{
- while(!done)
- {
-
- draw_lock->lock("ResourceThread::run");
- while(!interrupted)
- {
-// Pull off item
- item_lock->lock("ResourceThread::run");
+ MWindow *mwindow = resource_thread->mwindow;
+ while( !done ) {
+ draw_lock->lock("ResourceThreadBase::run");
+ while( !interrupted ) {
+ item_lock->lock("ResourceThreadBase::run");
ResourceThreadItem *item = items.first;
items.remove_pointer(item);
item_lock->unlock();
-//printf("ResourceThread::run %d %d\n", __LINE__, items.size());
- if(!item) break;
-
- switch( item->data_type ) {
- case TRACK_VIDEO:
- do_video((VResourceThreadItem*)item);
- break;
- case TRACK_AUDIO:
- do_audio((AResourceThreadItem*)item);
- break;
- }
-
+ if( !item ) break;
+ draw_item(item);
delete item;
}
-
- get_audio_source(0);
- get_video_source(0);
mwindow->age_caches();
}
}
-void ResourceThread::stop()
+void ResourceThreadBase::stop()
{
if( !done ) {
done = 1;
}
-void ResourceThread::open_render_engine(EDL *nested_edl,
- int do_audio,
- int do_video)
+void ResourceThreadBase::open_render_engine(EDL *nested_edl,
+ int do_audio, int do_video)
{
- if(render_engine && render_engine_id != nested_edl->id)
- {
- delete render_engine;
- render_engine = 0;
+ if( render_engine && render_engine_id != nested_edl->id ) {
+ delete render_engine; render_engine = 0;
}
- if(!render_engine)
- {
+ if( !render_engine ) {
+ MWindow *mwindow = resource_thread->mwindow;
TransportCommand command;
- if(do_audio)
- command.command = NORMAL_FWD;
- else
- command.command = CURRENT_FRAME;
+ command.command = do_audio ? NORMAL_FWD : CURRENT_FRAME;
command.get_edl()->copy_all(nested_edl);
command.change_type = CHANGE_ALL;
command.realtime = 0;
- render_engine = new RenderEngine(0,
- mwindow->preferences, 0, 0);
+ render_engine = new RenderEngine(0, mwindow->preferences, 0, 0);
render_engine_id = nested_edl->id;
render_engine->set_vcache(mwindow->video_cache);
render_engine->set_acache(mwindow->audio_cache);
}
}
-File *ResourceThread::get_audio_source(Asset *asset)
+void ResourceThreadBase::close_render_engine()
{
- if( interrupted ) asset = 0;
-
- if( audio_asset && audio_asset != asset && (!asset ||
- strcmp(audio_asset->path, asset->path)) )
- {
- mwindow->audio_cache->check_in(audio_asset);
- audio_source = 0;
- audio_asset->remove_user();
- audio_asset = 0;
-
- }
- if( !audio_asset && asset )
- {
- audio_asset = asset;
- audio_asset->add_user();
- audio_source = mwindow->audio_cache->check_out(asset, mwindow->edl);
- }
- return audio_source;
+ delete render_engine; render_engine = 0;
+ render_engine_id = -1;
}
-File *ResourceThread::get_video_source(Asset *asset)
+void ResourceVideoThread::draw_item(ResourceThreadItem *item)
{
- if( interrupted ) asset = 0;
-
- if( video_asset && video_asset != asset && (!asset ||
- strcmp(video_asset->path, asset->path)) )
- {
- mwindow->video_cache->check_in(video_asset);
- video_source = 0;
- video_asset->remove_user();
- video_asset = 0;
-
- }
- if( !video_asset && asset )
- {
- video_asset = asset;
- video_asset->add_user();
- video_source = mwindow->video_cache->check_out(asset, mwindow->edl);
- }
- return video_source;
+ do_video((VResourceThreadItem *)item);
}
-void ResourceThread::do_video(VResourceThreadItem *item)
+void ResourceVideoThread::do_video(VResourceThreadItem *item)
{
int source_w = 0;
int source_h = 0;
int source_id = -1;
int source_cmodel = -1;
- if(item->indexable->is_asset)
- {
+ if( item->indexable->is_asset ) {
Asset *asset = (Asset*)item->indexable;
source_w = asset->width;
source_h = asset->height;
source_id = asset->id;
source_cmodel = BC_RGB888;
}
- else
- {
+ else {
EDL *nested_edl = (EDL*)item->indexable;
source_w = nested_edl->session->output_w;
source_h = nested_edl->session->output_h;
source_id = nested_edl->id;
source_cmodel = nested_edl->session->color_model;
}
-
- if(temp_picon &&
- (temp_picon->get_w() != source_w ||
- temp_picon->get_h() != source_h ||
- temp_picon->get_color_model() != source_cmodel))
- {
- delete temp_picon;
- temp_picon = 0;
- }
-
- if(!temp_picon)
- {
- temp_picon = new VFrame(0, -1, source_w, source_h, source_cmodel, -1);
- }
-
-// Get temporary to copy cached frame to
- if(temp_picon2 &&
- (temp_picon2->get_w() != item->picon_w ||
- temp_picon2->get_h() != item->picon_h))
- {
- delete temp_picon2;
- temp_picon2 = 0;
- }
-
- if(!temp_picon2)
- {
- temp_picon2 = new VFrame( item->picon_w, item->picon_h, BC_RGB888, 0);
- }
-
-
+ VFrame::get_temp(temp_picon, source_w, source_h, source_cmodel);
+ VFrame::get_temp(temp_picon2, item->picon_w, item->picon_h, BC_RGB888);
// Search frame cache again.
int need_conversion = 0;
EDL *nested_edl = 0;
Asset *asset = 0;
+ MWindow *mwindow = resource_thread->mwindow;
picon_frame = mwindow->frame_cache->get_frame_ptr(item->position,
item->layer, item->frame_rate, BC_RGB888,
// Unlock the get_frame_ptr command
mwindow->frame_cache->unlock();
}
- else
- if(!item->indexable->is_asset)
- {
+ else if( !item->indexable->is_asset ) {
nested_edl = (EDL*)item->indexable;
open_render_engine(nested_edl, 0, 1);
need_conversion = 1;
}
- else
- {
+ else {
asset = (Asset*)item->indexable;
File *source = get_video_source(asset);
- if(!source)
- return;
+ if(!source) return;
source->set_layer(item->layer);
int64_t normalized_position = (int64_t)(item->position *
- asset->frame_rate /
- item->frame_rate);
- source->set_video_position(normalized_position,
- 0);
-
+ asset->frame_rate / item->frame_rate);
+ source->set_video_position(normalized_position, 0);
source->read_frame(temp_picon);
-
+ get_video_source(0);
need_conversion = 1;
}
- if(need_conversion)
- {
+ if( need_conversion ) {
picon_frame = new VFrame(item->picon_w, item->picon_h, BC_RGB888, 0);
- BC_CModels::transfer(picon_frame->get_rows(), temp_picon->get_rows(),
- 0, 0, 0, 0, 0, 0,
- 0, 0, temp_picon->get_w(), temp_picon->get_h(),
- 0, 0, picon_frame->get_w(), picon_frame->get_h(),
- source_cmodel, BC_RGB888, 0,
- temp_picon->get_bytes_per_line(),
- picon_frame->get_bytes_per_line());
+ picon_frame->transfer_from(temp_picon);
temp_picon2->copy_from(picon_frame);
mwindow->frame_cache->put_frame(picon_frame, item->position, item->layer,
mwindow->edl->session->frame_rate, 0, item->indexable);
}
// Allow escape here
- if(interrupted)
- return;
+ if(interrupted) return;
+ MWindowGUI *gui = mwindow->gui;
// Draw the picon
- mwindow->gui->lock_window("ResourceThread::do_video");
-
+ gui->lock_window("ResourceThreadBase::do_video");
// It was interrupted while waiting.
- if(interrupted)
- {
- mwindow->gui->unlock_window();
+ if( interrupted ) {
+ gui->unlock_window();
return;
}
-
-
// Test for pixmap existence first
- if(item->operation_count == operation_count)
- {
+ if( item->operation_count == resource_thread->operation_count ) {
ArrayList<ResourcePixmap*> &resource_pixmaps = gui->resource_pixmaps;
int i = resource_pixmaps.total;
while( --i >= 0 && resource_pixmaps[i] != item->pixmap );
if( i >= 0 ) {
item->pixmap->draw_vframe(temp_picon2,
- item->picon_x,
- item->picon_y,
- item->picon_w,
- item->picon_h,
- 0,
- 0);
-
- mwindow->gui->update(0, IGNORE_THREAD, 0, 0, 0, 0, 0);
+ item->picon_x, item->picon_y,
+ item->picon_w, item->picon_h, 0, 0);
+ gui->update(0, IGNORE_THREAD, 0, 0, 0, 0, 0);
}
}
- mwindow->gui->unlock_window();
+ gui->unlock_window();
}
#define BUFFERSIZE 65536
-void ResourceThread::do_audio(AResourceThreadItem *item)
+void ResourceAudioThread::draw_item(ResourceThreadItem *item)
+{
+ do_audio((AResourceThreadItem *)item);
+}
+
+void ResourceAudioThread::do_audio(AResourceThreadItem *item)
{
// Search again
- WaveCacheItem *wave_item;
- double high = 0;
- double low = 0;
- const int debug = 0;
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
- if((wave_item = mwindow->wave_cache->get_wave(item->indexable->id,
- item->channel, item->start, item->end)))
- {
+ double high = 0, low = 0;
+ MWindow *mwindow = resource_thread->mwindow;
+ WaveCacheItem * wave_item =
+ mwindow->wave_cache->get_wave(item->indexable->id,
+ item->channel, item->start, item->end);
+ if( wave_item ) {
high = wave_item->high;
low = wave_item->low;
mwindow->wave_cache->unlock();
}
- else
- {
+ else {
int first_sample = 1;
int64_t start = item->start;
int64_t end = item->end;
double *buffer_samples = !audio_buffer ? 0 :
audio_buffer->get_data();
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
- for(int64_t sample = start; sample < end; sample++)
- {
- double value;
+ for( int64_t sample=start; sample<end; ++sample ) {
// Get value from previous buffer
if(audio_buffer &&
item->channel == audio_channel &&
item->indexable->id == audio_asset_id &&
sample >= audio_start &&
- sample < audio_start + audio_samples)
- {
- ;
- }
- else
-// Load new buffer
- {
+ sample < audio_start + audio_samples) {}
+ else { // Load new buffer
if(!audio_buffer) {
audio_buffer = new Samples(BUFFERSIZE);
buffer_samples = audio_buffer->get_data();
int64_t total_samples = item->indexable->get_audio_samples();
int fragment = BUFFERSIZE;
- if(fragment + sample > total_samples)
+ if( fragment + sample > total_samples )
fragment = total_samples - sample;
- if(!item->indexable->is_asset)
- {
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
+ if( !item->indexable->is_asset ) {
open_render_engine((EDL*)item->indexable, 1, 0);
- if(debug) printf("ResourceThread::do_audio %d %p\n", __LINE__, render_engine);
- if(render_engine->arender)
- {
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
+ if( render_engine->arender ) {
int source_channels = item->indexable->get_audio_channels();
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
- for(int i = 0; i < MAXCHANNELS; i++)
- {
- if(i < source_channels &&
- !temp_buffer[i])
- {
+ for( int i=0; i<MAXCHANNELS; ++i ) {
+ if( i<source_channels && !temp_buffer[i] ) {
temp_buffer[i] = new Samples(BUFFERSIZE);
}
- else
- if(i >= source_channels &&
- temp_buffer[i])
- {
- delete temp_buffer[i];
- temp_buffer[i] = 0;
+ else if( i >= source_channels && temp_buffer[i] ) {
+ delete temp_buffer[i]; temp_buffer[i] = 0;
}
}
-
-
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
- render_engine->arender->process_buffer(
- temp_buffer,
- fragment,
- sample);
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
+ render_engine->arender->
+ process_buffer( temp_buffer, fragment, sample);
memcpy(buffer_samples,
temp_buffer[item->channel]->get_data(),
fragment * sizeof(double));
}
- else
- {
- if(debug) printf("ResourceThread::do_audio %d %d\n", __LINE__, fragment);
+ else {
if(fragment > 0) bzero(buffer_samples, sizeof(double) * fragment);
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
-
}
}
- else
- {
+ else {
Asset *asset = (Asset*)item->indexable;
File *source = get_audio_source(asset);
- if(!source)
- return;
-
+ if( !source ) return;
source->set_channel(item->channel);
source->set_audio_position(sample);
source->read_samples(audio_buffer, fragment);
+ get_audio_source(0);
}
-
audio_asset_id = item->indexable->id;
audio_channel = item->channel;
audio_start = sample;
audio_samples = fragment;
}
-
-
- value = buffer_samples[sample - audio_start];
- if(first_sample)
- {
+ double value = buffer_samples[sample - audio_start];
+ if( first_sample ) {
high = low = value;
first_sample = 0;
}
- else
- {
- if(value > high)
- high = value;
- else
- if(value < low)
- low = value;
+ else {
+ if( value > high ) high = value;
+ else if( value < low ) low = value;
}
}
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
// If it's a nested EDL, store all the channels
- mwindow->wave_cache->put_wave(item->indexable,
- item->channel,
- item->start,
- item->end,
- high,
- low);
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
+ mwindow->wave_cache->put_wave(item->indexable, item->channel,
+ item->start, item->end, high, low);
}
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
// Allow escape here
- if(interrupted)
- return;
+ if(interrupted) return;
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
+ MWindowGUI *gui = mwindow->gui;
// Draw the column
- mwindow->gui->lock_window("ResourceThread::do_audio");
- if(interrupted)
- {
- mwindow->gui->unlock_window();
+ gui->lock_window("ResourceThreadBase::do_audio");
+ if( interrupted ) {
+ gui->unlock_window();
return;
}
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
- if(item->operation_count == operation_count)
- {
-
+ if( item->operation_count == resource_thread->operation_count ) {
// Test for pixmap existence first
ArrayList<ResourcePixmap*> &resource_pixmaps = gui->resource_pixmaps;
int i = resource_pixmaps.total;
while( --i >= 0 && resource_pixmaps[i] != item->pixmap );
- if( i >= 0 )
- {
- if(prev_x == item->x - 1)
- {
+ if( i >= 0 ) {
+ if( prev_x == item->x-1 ) {
high = MAX(high, prev_l);
low = MIN(low, prev_h);
}
prev_x = item->x;
prev_h = high;
prev_l = low;
- if(gui->pane[item->pane_number])
+ if( gui->pane[item->pane_number] )
item->pixmap->draw_wave(
gui->pane[item->pane_number]->canvas,
- item->x,
- high,
- low);
- if(timer->get_difference() > 250 || item->last)
- {
- mwindow->gui->update(0, IGNORE_THREAD, 0, 0, 0, 0, 0);
+ item->x, high, low);
+ if( timer->get_difference() > 250 || item->last ) {
+ gui->update(0, IGNORE_THREAD, 0, 0, 0, 0, 0);
timer->update();
}
}
}
- if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
- mwindow->gui->unlock_window();
+ gui->unlock_window();
+}
+ResourceThread::ResourceThread(MWindow *mwindow)
+{
+ this->mwindow = mwindow;
+ audio_thread = 0;
+ video_thread = 0;
+ interrupted = 1;
+ operation_count = 0;
}
+ResourceThread::~ResourceThread()
+{
+ delete audio_thread;
+ delete video_thread;
+}
+void ResourceThread::create_objects()
+{
+ audio_thread = new ResourceAudioThread(this);
+ audio_thread->create_objects();
+ video_thread = new ResourceVideoThread(this);
+ video_thread->create_objects();
+}
+void ResourceThread::stop_draw(int reset)
+{
+ if( !interrupted ) {
+ interrupted = 1;
+ audio_thread->stop_draw(reset);
+ video_thread->stop_draw(reset);
+ ++operation_count;
+ }
+}
+
+void ResourceThread::start_draw()
+{
+ if( interrupted ) {
+ interrupted = 0;
+ audio_thread->start_draw();
+ video_thread->start_draw();
+ }
+}
+
+// Be sure to stop_draw before changing the asset table,
+// closing files.
+void ResourceThread::add_picon(ResourcePixmap *pixmap, int pane_number,
+ int picon_x, int picon_y, int picon_w, int picon_h,
+ double frame_rate, int64_t position, int layer,
+ Indexable *indexable)
+{
+ video_thread->add_picon(pixmap, pane_number,
+ picon_x, picon_y, picon_w, picon_h,
+ frame_rate, position, layer, indexable);
+}
+
+void ResourceThread::add_wave(ResourcePixmap *pixmap, int pane_number,
+ Indexable *indexable, int x, int channel,
+// samples relative to asset rate
+ int64_t source_start, int64_t source_end)
+{
+ audio_thread->add_wave(pixmap, pane_number,
+ indexable, x, channel, source_start, source_end);
+}
+
+void ResourceThread::run()
+{
+ audio_thread->run();
+ video_thread->run();
+}
+
+void ResourceThread::stop()
+{
+ audio_thread->stop();
+ video_thread->stop();
+}
+
+void ResourceThread::reset(int pane_number)
+{
+ audio_thread->reset(pane_number);
+ video_thread->reset(pane_number);
+}
+
+void ResourceThread::close_indexable(Indexable *idxbl)
+{
+ if( audio_thread && audio_thread->render_engine_id == idxbl->id )
+ audio_thread->close_render_engine();
+ if( video_thread && audio_thread->render_engine_id == idxbl->id )
+ video_thread->close_render_engine();
+}
class ResourceThreadItem : public ListItem<ResourceThreadItem>
{
public:
- ResourceThreadItem(ResourcePixmap *pixmap,
- int pane_number,
- Indexable *indexable,
- int data_type,
- int operation_count);
+ ResourceThreadItem(ResourcePixmap *pixmap, int pane_number,
+ Indexable *indexable, int data_type, int operation_count);
virtual ~ResourceThreadItem();
ResourcePixmap *pixmap;
Indexable *indexable;
- int data_type;
- int operation_count;
- int last;
- int pane_number;
+ int data_type, pane_number;
+ int operation_count, last;
};
class AResourceThreadItem : public ResourceThreadItem
{
public:
- AResourceThreadItem(ResourcePixmap *pixmap,
- int pane_number,
- Indexable *indexable,
- int x,
- int channel,
- int64_t start,
- int64_t end,
- int operation_count);
+ AResourceThreadItem(ResourcePixmap *pixmap, int pane_number,
+ Indexable *indexable, int x, int channel,
+ int64_t start, int64_t end, int operation_count);
~AResourceThreadItem();
- int x;
- int channel;
- int64_t start;
- int64_t end;
+ int x, channel;
+ int64_t start, end;
};
class VResourceThreadItem : public ResourceThreadItem
{
public:
- VResourceThreadItem(ResourcePixmap *pixmap,
- int pane_number,
- int picon_x,
- int picon_y,
- int picon_w,
- int picon_h,
- double frame_rate,
- int64_t position,
- int layer,
- Indexable *indexable,
- int operation_count);
+ VResourceThreadItem(ResourcePixmap *pixmap, int pane_number,
+ int picon_x, int picon_y, int picon_w, int picon_h,
+ double frame_rate, int64_t position, int layer,
+ Indexable *indexable, int operation_count);
~VResourceThreadItem();
-
-
- int picon_x;
- int picon_y;
- int picon_w;
- int picon_h;
+ int picon_x, picon_y;
+ int picon_w, picon_h;
double frame_rate;
int64_t position;
int layer;
};
-class ResourceThread : public Thread
+class ResourceThreadBase : public Thread
{
public:
- ResourceThread(MWindow *mwindow, MWindowGUI *gui);
- ~ResourceThread();
-
+ ResourceThreadBase(ResourceThread *resource_thread);
+ ~ResourceThreadBase();
void create_objects();
-// reset - delete all picons. Used for index building.
void stop_draw(int reset);
- void start_draw();
+ virtual void start_draw();
+ virtual void draw_item(ResourceThreadItem *item) = 0;
+ void close_render_engine();
// Be sure to stop_draw before changing the asset table,
// closing files.
- void add_picon(ResourcePixmap *pixmap,
- int pane_number,
- int picon_x,
- int picon_y,
- int picon_w,
- int picon_h,
- double frame_rate,
- int64_t position,
- int layer,
- Indexable *indexable);
-
- void add_wave(ResourcePixmap *pixmap,
- int pane_number,
- Indexable *indexable,
- int x,
- int channel,
-// samples relative to asset rate
- int64_t source_start,
- int64_t source_end);
-
void run();
void stop();
void reset(int pane_number);
- void do_video(VResourceThreadItem *item);
- void do_audio(AResourceThreadItem *item);
-
void open_render_engine(EDL *nested_edl,
- int do_audio,
- int do_video);
+ int do_audio, int do_video);
- File *get_video_source(Asset *asset);
- File *get_audio_source(Asset *asset);
-
- MWindow *mwindow;
- MWindowGUI *gui;
+ ResourceThread *resource_thread;
Condition *draw_lock;
Mutex *item_lock;
List<ResourceThreadItem> items;
int interrupted;
int done;
- VFrame *temp_picon;
- VFrame *temp_picon2;
// Render engine for nested EDL
RenderEngine *render_engine;
// ID of nested EDL being rendered
int render_engine_id;
+};
+
+class ResourceAudioThread : public ResourceThreadBase
+{
+public:
+ ResourceAudioThread(ResourceThread *resource_thread);
+ ~ResourceAudioThread();
+ void start_draw();
+ File *get_audio_source(Asset *asset);
+ void draw_item(ResourceThreadItem *item);
+ void do_audio(AResourceThreadItem *item);
+
+ void add_wave(ResourcePixmap *pixmap, int pane_number,
+ Indexable *indexable, int x, int channel,
+ // samples relative to asset rate
+ int64_t source_start, int64_t source_end);
+
+ ResourceThread *resource_thread;
Asset *audio_asset;
File *audio_source;
- Asset *video_asset;
- File *video_source;
// Current audio buffer for spanning multiple pixels
Samples *audio_buffer;
int prev_x;
double prev_h;
double prev_l;
-// Incremented after every start_draw to prevent overlapping operations
- int operation_count;
+};
+
+class ResourceVideoThread : public ResourceThreadBase
+{
+public:
+ ResourceVideoThread(ResourceThread *resource_thread);
+ ~ResourceVideoThread();
+ File *get_video_source(Asset *asset);
+ void draw_item(ResourceThreadItem *item);
+ void do_video(VResourceThreadItem *item);
+
+// Be sure to stop_draw before changing the asset table,
+// closing files.
+ void add_picon(ResourcePixmap *pixmap, int pane_number,
+ int picon_x, int picon_y, int picon_w, int picon_h,
+ double frame_rate, int64_t position, int layer,
+ Indexable *indexable);
+
+ ResourceThread *resource_thread;
+ Asset *video_asset;
+ File *video_source;
+
+ VFrame *temp_picon;
+ VFrame *temp_picon2;
};
+class ResourceThread
+{
+public:
+ ResourceThread(MWindow *mwindow);
+ ~ResourceThread();
-#endif
+ void create_objects();
+// reset - delete all picons. Used for index building.
+ void stop_draw(int reset);
+ void start_draw();
+
+// Be sure to stop_draw before changing the asset table,
+// closing files.
+ void add_picon(ResourcePixmap *pixmap, int pane_number,
+ int picon_x, int picon_y, int picon_w, int picon_h,
+ double frame_rate, int64_t position, int layer,
+ Indexable *indexable);
+
+ void add_wave(ResourcePixmap *pixmap, int pane_number,
+ Indexable *indexable, int x, int channel,
+// samples relative to asset rate
+ int64_t source_start, int64_t source_end);
+
+ void run();
+ void stop();
+ void reset(int pane_number);
+ void close_indexable(Indexable*);
+ MWindow *mwindow;
+ ResourceAudioThread *audio_thread;
+ ResourceVideoThread *video_thread;
+ int operation_count;
+ int interrupted;
+};
+
+#endif