Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / cinelerra / resourcethread.C
diff --git a/cinelerra-5.0/cinelerra/resourcethread.C b/cinelerra-5.0/cinelerra/resourcethread.C
deleted file mode 100644 (file)
index c14bf27..0000000
+++ /dev/null
@@ -1,813 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include "arender.h"
-#include "asset.h"
-#include "bcsignals.h"
-#include "bctimer.h"
-#include "cache.h"
-#include "clip.h"
-#include "condition.h"
-#include "datatype.h"
-#include "edl.h"
-#include "edlsession.h"
-#include "file.h"
-#include "framecache.h"
-#include "mutex.h"
-#include "mwindow.h"
-#include "mwindowgui.h"
-#include "renderengine.h"
-#include "resourcethread.h"
-#include "resourcepixmap.h"
-#include "samples.h"
-#include "timelinepane.h"
-#include "trackcanvas.h"
-#include "transportque.h"
-#include "vframe.h"
-#include "vrender.h"
-#include "wavecache.h"
-
-
-#include <unistd.h>
-
-ResourceThreadItem::ResourceThreadItem(ResourcePixmap *pixmap,
-       int pane_number,
-       Indexable *indexable,
-       int data_type,
-       int operation_count)
-{
-       this->pane_number = pane_number;
-       this->data_type = data_type;
-       this->pixmap = pixmap;
-       this->indexable = indexable;
-
-// Assets are garbage collected so they don't need to be replicated.
-       this->operation_count = operation_count;
-       indexable->Garbage::add_user();
-       last = 0;
-}
-
-ResourceThreadItem::~ResourceThreadItem()
-{
-       indexable->Garbage::remove_user();
-}
-
-
-
-
-
-
-
-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;
-       this->picon_w = picon_w;
-       this->picon_h = picon_h;
-       this->frame_rate = frame_rate;
-       this->position = position;
-       this->layer = layer;
-}
-
-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)
-{
-       this->x = x;
-       this->channel = channel;
-       this->start = start;
-       this->end = end;
-}
-
-AResourceThreadItem::~AResourceThreadItem()
-{
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ResourceThread::ResourceThread(MWindow *mwindow, MWindowGUI *gui)
- : Thread(1, 0, 0)
-{
-//printf("ResourceThread::ResourceThread %d %p\n", __LINE__, this);
-       this->mwindow = mwindow;
-       this->gui = gui;
-       interrupted = 1;
-       done = 1;
-       temp_picon = 0;
-       temp_picon2 = 0;
-       draw_lock = new Condition(0, "ResourceThread::draw_lock", 0);
-//     interrupted_lock = new Condition(0, "ResourceThread::interrupted_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;
-       render_engine = 0;
-
-       audio_asset = 0;
-       audio_source = 0;
-       video_asset = 0;
-       video_source = 0;
-}
-
-ResourceThread::~ResourceThread()
-{
-       stop();
-       delete draw_lock;
-//     delete interrupted_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()
-{
-       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::stop_draw(int reset)
-{
-       if(!interrupted)
-       {
-               interrupted = 1;
-               item_lock->lock("ResourceThread::stop_draw");
-
-//printf("ResourceThread::stop_draw %d %d\n", __LINE__, reset);
-//BC_Signals::dump_stack();
-               if(reset) items.remove_all_objects();
-               operation_count++;
-               item_lock->unlock();
-               prev_x = -1;
-               prev_h = 0;
-               prev_l = 0;
-       }
-}
-
-void ResourceThread::start_draw()
-{
-       interrupted = 0;
-// Tag last audio item to cause refresh.
-       int i = items.total;
-       while( --i>=0 && items[i]->data_type!=TRACK_AUDIO );
-       if( i >= 0 ) items[i]->last = 1;
-       timer->update();
-       draw_lock->unlock();
-}
-
-void ResourceThread::run()
-{
-       while(!done)
-       {
-
-               draw_lock->lock("ResourceThread::run");
-
-               while(!interrupted)
-               {
-// Pull off item
-                       item_lock->lock("ResourceThread::run");
-                       int total_items = items.size();
-                       ResourceThreadItem *item = 0;
-                       if(items.size())
-                       {
-                               item = items[0];
-                               items.remove_number(0);
-                       }
-                       item_lock->unlock();
-//printf("ResourceThread::run %d %d\n", __LINE__, items.size());
-                       if(!total_items) break;
-
-                       switch( item->data_type ) {
-                       case TRACK_VIDEO:
-                               do_video((VResourceThreadItem*)item);
-                               break;
-                       case TRACK_AUDIO:
-                               do_audio((AResourceThreadItem*)item);
-                               break;
-                       }
-
-                       delete item;
-               }
-
-               get_audio_source(0);
-               get_video_source(0);
-               mwindow->age_caches();
-       }
-}
-
-void ResourceThread::stop()
-{
-       if( !done ) {
-               done = 1;
-               interrupted = 1;
-               draw_lock->unlock();
-               join();
-       }
-}
-
-
-void ResourceThread::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)
-       {
-               TransportCommand command;
-               if(do_audio)
-                       command.command = NORMAL_FWD;
-               else
-                       command.command = 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, 0);
-               render_engine_id = nested_edl->id;
-               render_engine->set_vcache(mwindow->video_cache);
-               render_engine->set_acache(mwindow->audio_cache);
-               render_engine->arm_command(&command);
-       }
-}
-
-File *ResourceThread::get_audio_source(Asset *asset)
-{
-       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;
-}
-
-File *ResourceThread::get_video_source(Asset *asset)
-{
-       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 ResourceThread::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)
-       {
-               Asset *asset = (Asset*)item->indexable;
-               source_w = asset->width;
-               source_h = asset->height;
-               source_id = asset->id;
-               source_cmodel = BC_RGB888;
-       }
-       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(0,
-                       -1,
-                       item->picon_w,
-                       item->picon_h,
-                       BC_RGB888,
-                       -1);
-       }
-
-
-
-// Search frame cache again.
-
-       VFrame *picon_frame = 0;
-       int need_conversion = 0;
-       EDL *nested_edl = 0;
-       Asset *asset = 0;
-
-       picon_frame = mwindow->frame_cache->get_frame_ptr(item->position,
-               item->layer,
-               item->frame_rate,
-               BC_RGB888,
-               item->picon_w,
-               item->picon_h,
-               source_id);
-//printf("search cache %ld,%d,%f,%dx%d,%d = %p\n",
-//  item->position, item->layer, item->frame_rate,
-//  item->picon_w, item->picon_h, source_id, picon_frame);
-       if( picon_frame )
-       {
-               temp_picon2->copy_from(picon_frame);
-// Unlock the get_frame_ptr command
-               mwindow->frame_cache->unlock();
-       }
-       else
-       if(!item->indexable->is_asset)
-       {
-               nested_edl = (EDL*)item->indexable;
-               open_render_engine(nested_edl, 0, 1);
-
-               int64_t source_position = (int64_t)(item->position *
-                       nested_edl->session->frame_rate /
-                       item->frame_rate);
-               if(render_engine->vrender)
-                       render_engine->vrender->process_buffer(
-                               temp_picon,
-                               source_position,
-                               0);
-
-               need_conversion = 1;
-       }
-       else
-       {
-               asset = (Asset*)item->indexable;
-               File *source = get_video_source(asset);
-               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);
-
-               source->read_frame(temp_picon);
-
-               need_conversion = 1;
-       }
-
-       if(need_conversion)
-       {
-               picon_frame = new VFrame(0,
-                       -1,
-                       item->picon_w,
-                       item->picon_h,
-                       BC_RGB888,
-                       -1);
-               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());
-               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;
-       }
-
-
-// Draw the picon
-       mwindow->gui->lock_window("ResourceThread::do_video");
-
-// It was interrupted while waiting.
-       if(interrupted)
-       {
-               mwindow->gui->unlock_window();
-               return;
-       }
-
-
-
-// Test for pixmap existence first
-       if(item->operation_count == 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);
-               }
-       }
-
-       mwindow->gui->unlock_window();
-}
-
-
-#define BUFFERSIZE 65536
-void ResourceThread::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)))
-       {
-               high = wave_item->high;
-               low = wave_item->low;
-               mwindow->wave_cache->unlock();
-       }
-       else
-       {
-               int first_sample = 1;
-               int64_t start = item->start;
-               int64_t end = item->end;
-               if(start == end) end = start + 1;
-               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;
-// 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
-                       {
-                               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)
-                                       fragment = total_samples - sample;
-
-                               if(!item->indexable->is_asset)
-                               {
-                                       if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
-                                       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__);
-                                               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])
-                                                       {
-                                                               temp_buffer[i] = new Samples(BUFFERSIZE);
-                                                       }
-                                                       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__);
-                                               memcpy(buffer_samples,
-                                                       temp_buffer[item->channel]->get_data(),
-                                                       fragment * sizeof(double));
-                                       }
-                                       else
-                                       {
-                                               if(debug) printf("ResourceThread::do_audio %d %d\n", __LINE__, fragment);
-                                               if(fragment > 0) bzero(buffer_samples, sizeof(double) * fragment);
-                                               if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
-
-                                       }
-                               }
-                               else
-                               {
-                                       Asset *asset = (Asset*)item->indexable;
-                                       File *source = get_audio_source(asset);
-                                       if(!source)
-                                               return;
-
-                                       source->set_channel(item->channel);
-                                       source->set_audio_position(sample);
-                                       source->read_samples(audio_buffer, fragment);
-                               }
-
-                               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)
-                       {
-                               high = low = value;
-                               first_sample = 0;
-                       }
-                       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__);
-       }
-       if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
-
-// Allow escape here
-       if(interrupted)
-               return;
-
-       if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
-// Draw the column
-       mwindow->gui->lock_window("ResourceThread::do_audio");
-       if(interrupted)
-       {
-               mwindow->gui->unlock_window();
-               return;
-       }
-
-       if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
-       if(item->operation_count == 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)
-                       {
-                               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])
-                               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, 3, 0, 0, 0, 0, 0);
-                               timer->update();
-                       }
-               }
-       }
-       if(debug) printf("ResourceThread::do_audio %d\n", __LINE__);
-
-       mwindow->gui->unlock_window();
-
-}
-
-
-
-