split resource_thread update into separate audio/video threads, boxblur layout tweaks
authorGood Guy <[email protected]>
Sun, 26 Apr 2020 01:41:57 +0000 (19:41 -0600)
committerGood Guy <[email protected]>
Sun, 26 Apr 2020 01:41:57 +0000 (19:41 -0600)
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindowgui.C
cinelerra-5.1/cinelerra/resourcethread.C
cinelerra-5.1/cinelerra/resourcethread.h
cinelerra-5.1/plugins/boxblur/boxblur.C

index 8c0dd6c0049d1317bbe0aba96587e53d617589dd..8b93262c4e6930cd53027d40c9b3b5f2309d1c67 100644 (file)
@@ -4456,11 +4456,7 @@ void MWindow::remove_from_caches(Indexable *idxbl)
                delete gui->render_engine;
                gui->render_engine = 0;
        }
-       if( gui->resource_thread->render_engine_id == idxbl->id ) {
-               gui->resource_thread->render_engine_id = -1;
-               delete gui->resource_thread->render_engine;
-               gui->resource_thread->render_engine = 0;
-       }
+       gui->resource_thread->close_indexable(idxbl);
        if( !idxbl->is_asset ) return;
        Asset *asset = (Asset *)idxbl;
        audio_cache->delete_entry(asset);
index a9e93c6419a18f5a3f061358ee6ec94bcd195598..7b92aa3258ae2a6635b163b0aaaff3a80329e418 100644 (file)
@@ -159,7 +159,7 @@ void MWindowGUI::create_objects()
        lock_window("MWindowGUI::create_objects");
        const int debug = 0;
 
-       resource_thread = new ResourceThread(mwindow, this);
+       resource_thread = new ResourceThread(mwindow);
        resource_thread->create_objects();
 
 
@@ -1809,6 +1809,7 @@ void MWindowGUI::delete_y_pane(int cursor_y)
 
 void MWindowGUI::stop_pane_drag()
 {
+       if( !dragging_pane ) return;
        dragging_pane = 0;
        resource_thread->stop_draw(0);
 
index 895dd506c3f963ab20e5576f5289ce16ac83c348..27794d27c388884101fe939f80d3d8507abe3301 100644 (file)
@@ -71,27 +71,12 @@ ResourceThreadItem::~ResourceThreadItem()
 }
 
 
-
-
-
-
-
-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;
@@ -107,25 +92,11 @@ VResourceThreadItem::~VResourceThreadItem()
 }
 
 
-
-
-
-
-
-
-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;
@@ -137,124 +108,157 @@ AResourceThreadItem::~AResourceThreadItem()
 {
 }
 
+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;
@@ -264,82 +268,46 @@ void ResourceThread::reset(int pane_number)
        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;
@@ -350,28 +318,21 @@ void ResourceThread::stop()
 }
 
 
-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);
@@ -379,103 +340,40 @@ void ResourceThread::open_render_engine(EDL *nested_edl,
        }
 }
 
-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.
 
@@ -483,6 +381,7 @@ void ResourceThread::do_video(VResourceThreadItem *item)
        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,
@@ -495,9 +394,7 @@ void ResourceThread::do_video(VResourceThreadItem *item)
 // 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);
 
@@ -512,97 +409,77 @@ void ResourceThread::do_video(VResourceThreadItem *item)
 
                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;
@@ -610,22 +487,14 @@ void ResourceThread::do_audio(AResourceThreadItem *item)
                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();
@@ -633,151 +502,185 @@ void ResourceThread::do_audio(AResourceThreadItem *item)
 
                                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();
+}
 
index 51f462c9941cc69eb3ec862591c4a40c5b8b4d09..1f8fada53dfbe31e69aa3a541b20807666770545 100644 (file)
 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;
@@ -190,11 +153,66 @@ public:
        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
index 006439af39a3b8e998b7dede327185fc4ac7ad23..9c5d5bcf3cdd78f9e97b1e3dc6083d061ffd8da8 100644 (file)
@@ -421,7 +421,7 @@ BoxBlurPower::BoxBlurPower(BoxBlurWindow *gui, int x, int y, int w,
 }
 
 BoxBlurWindow::BoxBlurWindow(BoxBlurEffect *plugin)
- : PluginClientWindow(plugin, xS(360), yS(246), xS(360), yS(246), 0)
+ : PluginClientWindow(plugin, xS(360), yS(260), xS(360), yS(260), 0)
 {
        this->plugin = plugin;
        blur_horz = 0;
@@ -445,13 +445,14 @@ BoxBlurWindow::~BoxBlurWindow()
 void BoxBlurWindow::create_objects()
 {
        int x = xS(10), y = yS(10);
+       int ys10 = yS(10), ys20 = yS(20), ys30 = yS(30), ys40 = yS(40);
        int t1 = x, t2 = t1+xS(24), t3 = t2+xS(100), t4 = t3+xS(24);
        int ww = get_w() - 2*x, bar_o = xS(30), bar_m = xS(15);
        int margin = plugin->get_theme()->widget_border;
 
-        BC_TitleBar *tbar;
-        add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Position & Size")));
-        y += tbar->get_h() + margin;
+       BC_TitleBar *tbar;
+       add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Position & Size")));
+       y += ys20;
        int x1 = ww - BoxBlurDrag::calculate_w(this) - margin;
        add_subwindow(drag = new BoxBlurDrag(this, plugin, x1, y));
        drag->create_objects();
@@ -465,32 +466,32 @@ void BoxBlurWindow::create_objects()
        add_subwindow(title = new BC_Title(t3, y, _("W:")));
        box_w = new BoxBlurW(this, t4, y);
        box_w->create_objects();
-       y += bmax(title->get_h(), box_w->get_h()) + margin;
+       y += ys30;
        add_subwindow(title = new BC_Title(t1, y, _("Y:")));
        box_y = new BoxBlurY(this, t2, y);
        box_y->create_objects();
        add_subwindow(title = new BC_Title(t3, y, _("H:")));
        box_h = new BoxBlurH(this, t4, y);
        box_h->create_objects();
-       y += bmax(title->get_h(), box_h->get_h()) + 2*margin;
+       y += ys40;
 
        add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Blur")));
-       y += tbar->get_h() + margin;
+       y += ys20;
        blur_horz = new BoxBlurRadius(this, x, y, ww, _("Horz:"),
                        &plugin->config.horz_radius);
        blur_horz->create_objects();
-       y += blur_horz->get_h() + margin;
+       y += ys30;
        blur_vert = new BoxBlurRadius(this, x, y, ww, _("Vert:"),
                        &plugin->config.vert_radius);
        blur_vert->create_objects();
-       y += blur_vert->get_h() + margin;
+       y += ys30;
        blur_power = new BoxBlurPower(this, x, y, ww, _("Power:"),
                        &plugin->config.power);
        blur_power->create_objects();
-       y += blur_power->get_h() + margin + yS(8);
+       y += ys40;
        BC_Bar *bar;
        add_subwindow(bar = new BC_Bar(x, y, ww));
-       y += bar->get_h() + 2*margin;
+       y += ys10;
 
        add_subwindow(reset = new BoxBlurReset(this, x, y));
        x1 = x + ww - BoxBlurPreset::calculate_w(this);