command.realtime = 0;
RenderEngine render_engine(0, preferences, 0, 0);
- CICache video_cache(preferences);
- render_engine.set_vcache(&video_cache);
+ CICache *video_cache = new CICache(preferences);
+ render_engine.set_vcache(video_cache);
render_engine.arm_command(&command);
double position = edl->local_session->get_selectionstart(1);
if( !ret )
ret = file.write_video_buffer(1);
file.close_file();
+ video_cache->remove_user();
}
if( !ret ) {
asset->folder_no = AW_MEDIA_FOLDER;
// edl came from a command which won't exist anymore
CICache::CICache(Preferences *preferences)
- : List<CICacheItem>()
+ : Garbage("CICache"), List<CICacheItem>()
{
this->preferences = preferences;
edl = 0;
CICacheItem *current = 0;
long tid = (long)Thread::get_self();
if( !tid ) tid = 1;
+ total_lock->lock("CICache::check_out");
+ add_user();
- while(1)
- {
+ while( users > 1 ) {
File *file = 0;
- total_lock->lock("CICache::check_out");
// Scan directory for item
current = first;
while(current && strcmp(current->asset->path, asset->path) != 0)
else
current = 0;
}
- total_lock->unlock();
if( current || !file || !block ) break;
// Try again after blocking
+ total_lock->unlock();
check_out_lock->lock("CICache::check_out");
+ total_lock->lock("CICache::check_out");
+ }
+
+// cache deleted during checkout, destroy this
+ if( users == 1 ) {
+ remove_user();
+ return 0;
}
+ remove_user();
+ total_lock->unlock();
//printf("check out %p %lx %s\n", current, tid, asset->path);
return current ? current->file : 0;
}
CICache *cache;
};
-class CICache : public List<CICacheItem>
+class CICache : public Garbage, public List<CICacheItem>
{
public:
CICache(Preferences *preferences);
int EditPanelGangTracks::handle_event()
{
int gang = mwindow->edl->session->gang_tracks;
- switch( gang ) {
- case GANG_NONE: gang = GANG_CHANNELS; break;
- case GANG_CHANNELS: gang = GANG_MEDIA; break;
- case GANG_MEDIA: gang = GANG_NONE; break;
+ if( !shift_down() ) {
+ if( ++gang > GANG_MEDIA ) gang = GANG_NONE;
+ }
+ else {
+ if( --gang < GANG_NONE ) gang = GANG_MEDIA;
}
update(gang);
panel->panel_set_gang_tracks(gang);
ref = 0;
delete render_engine; render_engine = 0;
delete command; command = 0;
- delete acache; acache = 0;
- delete vcache; vcache = 0;
+ if( acache ) { acache->remove_user(); acache = 0; }
+ if( vcache ) { vcache->remove_user(); vcache = 0; }
delete temp; temp = 0;
for( int i=0; i<MAX_CHANNELS; ++i ) {
delete samples[i]; samples[i] = 0;
delete render_engine;
render_engine = 0;
-
- delete cache;
- cache = 0;
+ if( cache ) {
+ cache->remove_user();
+ cache = 0;
+ }
}
int64_t IndexFile::get_required_scale()
trackmenu->add_item(new DeleteFirstTrack(mwindow));
trackmenu->add_item(new DeleteLastTrack(mwindow));
trackmenu->add_item(new ConcatenateTracks(mwindow));
+ trackmenu->add_item(new SwapTracksUp(mwindow));
+ trackmenu->add_item(new SwapTracksDown(mwindow));
AppendTracks *append_tracks;
trackmenu->add_item(append_tracks = new AppendTracks(mwindow));
append_tracks->create_objects();
}
+SwapTracksUp::SwapTracksUp(MWindow *mwindow)
+ : BC_MenuItem(_("Swap tracks up"), 0, UP)
+{
+ this->mwindow = mwindow;
+ set_shift();
+}
+
+int SwapTracksUp::handle_event()
+{
+ if( mwindow->session->current_operation == NO_OPERATION )
+ mwindow->swap_tracks_up();
+ return 1;
+}
+
+SwapTracksDown::SwapTracksDown(MWindow *mwindow)
+ : BC_MenuItem(_("Swap tracks down"), 0, DOWN)
+{
+ set_shift(); this->mwindow = mwindow;
+}
+
+int SwapTracksDown::handle_event()
+{
+ if( mwindow->session->current_operation == NO_OPERATION )
+ mwindow->swap_tracks_down();
+ return 1;
+}
+
+
ConcatenateTracks::ConcatenateTracks(MWindow *mwindow)
MWindow *mwindow;
};
+class SwapTracksUp : public BC_MenuItem
+{
+public:
+ SwapTracksUp(MWindow *mwindow);
+ int handle_event();
+ MWindow *mwindow;
+};
+
+class SwapTracksDown : public BC_MenuItem
+{
+public:
+ SwapTracksDown(MWindow *mwindow);
+ int handle_event();
+ MWindow *mwindow;
+};
+
class DeleteTracks : public BC_MenuItem
{
public:
pkg = (MaskPackage*)package;
start_x = pkg->start_x; end_x = pkg->end_x;
start_y = pkg->start_y; end_y = pkg->end_y;
- if( start_y >= end_y ) return;
MaskEdge *edge = engine->edge;
float r = engine->r, v = engine->v;
VFrame *in = engine->in;
nested_edl = 0;
nested_renderengine = 0;
nested_command = 0;
- private_cache = 0;
cache = 0;
}
delete nested_renderengine;
delete nested_command;
- if(private_cache) delete cache;
}
void Module::create_objects()
// CICache used during effect & nested EDL
CICache *cache;
-// If the cache was allocated by the module
- int private_cache;
// Parent EDL of this module when used for effect rendering.
// Used by APluginArray.
EDL *edl;
delete gui; gui = 0;
delete mainindexes; mainindexes = 0;
delete mainprogress; mainprogress = 0;
- delete audio_cache; audio_cache = 0; // delete the cache after the assets
- delete video_cache; video_cache = 0; // delete the cache after the assets
+ // delete the caches after the assets
+ if( audio_cache ) { audio_cache->remove_user(); audio_cache = 0; }
+ if( video_cache ) { video_cache->remove_user(); video_cache = 0; }
delete frame_cache; frame_cache = 0;
delete wave_cache; wave_cache = 0;
delete plugin_guis; plugin_guis = 0;
void move_tracks_down();
void move_track_up(Track *track);
void move_tracks_up();
+ void swap_track_down(Track *track);
+ void swap_tracks_down();
+ void swap_track_up(Track *track);
+ void swap_tracks_up();
void mute_selection();
void new_folder(const char *new_folder, int is_clips);
void delete_folder(char *folder);
}
+void MWindow::swap_track_down(Track *track)
+{
+ undo_before();
+ edl->tracks->swap_track_down(track);
+ save_backup();
+ undo_after(_("swap track down"), LOAD_ALL);
+
+ restart_brender();
+ gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+ sync_parameters(CHANGE_EDL);
+ save_backup();
+}
+
+void MWindow::swap_tracks_down()
+{
+ undo_before();
+ edl->tracks->swap_tracks_down();
+ save_backup();
+ undo_after(_("swap tracks down"), LOAD_ALL);
+
+ restart_brender();
+ gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+ sync_parameters(CHANGE_EDL);
+ save_backup();
+}
+
+void MWindow::swap_track_up(Track *track)
+{
+ undo_before();
+ edl->tracks->swap_track_up(track);
+ save_backup();
+ undo_after(_("swap track up"), LOAD_ALL);
+ restart_brender();
+ gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+ sync_parameters(CHANGE_EDL);
+ save_backup();
+}
+
+void MWindow::swap_tracks_up()
+{
+ undo_before();
+ edl->tracks->swap_tracks_up();
+ save_backup();
+ undo_after(_("swap tracks up"), LOAD_ALL);
+ restart_brender();
+ gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+ sync_parameters(CHANGE_EDL);
+}
+
+
void MWindow::mute_selection()
{
double start = edl->local_session->get_selectionstart();
PackageRenderer::~PackageRenderer()
{
delete command;
- delete audio_cache;
- delete video_cache;
+ if( audio_cache )
+ audio_cache->remove_user();
+ if( video_cache )
+ video_cache->remove_user();
delete vconfig;
delete aconfig;
delete timer;
record = 0;
play = 0;
// automate = 0;
- gang = 0;
draw = 0;
mute = 0;
- zoom = 0;
+ gang = 0;
master = 0;
+ zoom = 0;
expand = 0;
nudge = 0;
mix = 0;
delete record;
delete play;
// delete automate;
- delete gang;
delete draw;
delete mute;
- delete zoom;
+ delete gang;
delete master;
+ delete zoom;
delete expand;
delete nudge;
delete mix;
x1 += record->get_w();
// automate->reposition_window(x1, y1 + y);
// x1 += automate->get_w();
- gang->reposition_window(gang->get_x(), y1 + y);
- x1 += gang->get_w();
draw->reposition_window(draw->get_x(), y1 + y);
x1 += draw->get_w();
mute->reposition_window(mute->get_x(), y1 + y);
x1 += mute->get_w();
- zoom->reposition_window(zoom->get_x(), y1 + y);
- x1 += zoom->get_w();
+ gang->reposition_window(gang->get_x(), y1 + y);
+ x1 += gang->get_w();
master->reposition_window(master->get_x(), y1 + y);
+ x1 += master->get_w();
+ zoom->reposition_window(zoom->get_x(), y1 + y);
+// x1 += zoom->get_w();
}
y1 += mwindow->theme->play_h;
}
if( h < y2 ) {
delete play; play = 0;
delete record; record = 0;
- delete gang; gang = 0;
delete draw; draw = 0;
delete mute; mute = 0;
- delete zoom; zoom = 0;
+ delete gang; gang = 0;
delete master; master = 0;
+ delete zoom; zoom = 0;
}
else {
play->update(track->play);
record->update(track->armed);
- gang->update(track->ganged);
draw->update(track->draw);
mute->update(mwindow->get_int_auto(this, AUTOMATION_MUTE)->value);
+ gang->update(track->ganged);
+ master->update(track->master);
}
}
else if( h >= y2 ) {
x1 += play->get_w();
patchbay->add_subwindow(record = new RecordPatch(mwindow, this, x1 + x, y1 + y));
x1 += record->get_w();
- patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
- x1 += gang->get_w();
patchbay->add_subwindow(draw = new DrawPatch(mwindow, this, x1 + x, y1 + y));
x1 += draw->get_w();
patchbay->add_subwindow(mute = new MutePatch(mwindow, this, x1 + x, y1 + y));
x1 += mute->get_w();
- patchbay->add_subwindow(zoom = new ZoomPatch(mwindow, this, x1 + x, y1 + y));
- x1 += zoom->get_w();
+ patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
+ x1 += gang->get_w();
patchbay->add_subwindow(master = new MasterPatch(mwindow, this, x1 + x, y1 + y));
+ x1 += master->get_w();
+ patchbay->add_subwindow(zoom = new ZoomPatch(mwindow, this, x1 + x, y1 + y));
+// x1 += zoom->get_w();
}
if( play )
y1 = y2;
Thread::join();
delete preferences;
delete_render_engine();
- delete audio_cache;
- delete video_cache;
+ if( audio_cache )
+ audio_cache->remove_user();
+ if( video_cache )
+ video_cache->remove_user();
delete tracking_lock;
delete tracking_done;
delete pause_lock;
void PlaybackEngine::create_cache()
{
- if(audio_cache) { delete audio_cache; audio_cache = 0; }
- if(video_cache) { delete video_cache; video_cache = 0; }
- if(!audio_cache) audio_cache = new CICache(preferences);
- if(!video_cache) video_cache = new CICache(preferences);
+ if( audio_cache )
+ audio_cache->remove_user();
+ if( video_cache )
+ video_cache->remove_user();
+ audio_cache = new CICache(preferences);
+ video_cache = new CICache(preferences);
}
#include "preferences.h"
#include "shuttle.h"
#include "theme.h"
+#include "tracks.h"
#include "transportque.h"
#include "vframe.h"
return mwindow->edl;
}
-int PlayTransport::pause_transport()
+int PlayTransport::set_transport(int mode)
{
- if(active_button) active_button->set_mode(PLAY_MODE);
- return 0;
-}
-
-
-int PlayTransport::reset_transport()
-{
- fast_reverse->set_mode(PLAY_MODE);
- reverse_play->set_mode(PLAY_MODE);
- forward_play->set_mode(PLAY_MODE);
- frame_reverse_play->set_mode(PLAY_MODE);
- frame_forward_play->set_mode(PLAY_MODE);
- fast_play->set_mode(PLAY_MODE);
+ fast_reverse->set_mode(mode);
+ reverse_play->set_mode(mode);
+ forward_play->set_mode(mode);
+ frame_reverse_play->set_mode(mode);
+ frame_forward_play->set_mode(mode);
+ fast_play->set_mode(mode);
return 0;
}
{
}
-int PTransportButton::set_mode(int mode)
+void PTransportButton::set_mode(int mode)
{
this->mode = mode;
- return 0;
+}
+
+void PTransportButton::loop_mode(int dir)
+{
+ if( mode != LOOP_MODE ) return;
+ EDL *edl = transport->get_edl();
+ if( !edl ) return;
+ PlaybackEngine *engine = transport->engine;
+ if( !engine || engine->is_playing_back ) return;
+ double position = engine->get_tracking_position();
+ switch( dir ) {
+ case PLAY_FORWARD:
+ if( position >= edl->tracks->total_playable_length() )
+ transport->goto_start();
+ break;
+ case PLAY_REVERSE:
+ if( position <= 0 )
+ transport->goto_end();
+ break;
+ }
}
int PTransportButton::play_command(const char *lock_msg, int command)
}
int FastReverseButton::handle_event()
{
+ loop_mode(PLAY_REVERSE);
return play_command("FastReverseButton::handle_event", FAST_REWIND);
}
}
int ReverseButton::handle_event()
{
+ loop_mode(PLAY_REVERSE);
return play_command("ReverseButton::handle_event", NORMAL_REWIND);
}
}
int PlayButton::handle_event()
{
+ loop_mode(PLAY_FORWARD);
return play_command("PlayButton::handle_event", NORMAL_FWD);
}
}
int FastPlayButton::handle_event()
{
+ loop_mode(PLAY_FORWARD);
return play_command("FastPlayButton::handle_event", FAST_FWD);
}
#include "playtransport.inc"
#define PLAY_MODE 0
-#define PAUSE_MODE 1
-#define PAUSEDOWN_MODE 2
+#define LOOP_MODE 1
class PlayTransport
{
// speed - play speed for SLOW/FAST playback, zero defaults to slow=.5,fast=2.
void handle_transport(int command, int wait_tracking=0,
int use_inout=0, int toggle_audio=0, int loop_play=0, float speed=0);
- int pause_transport();
- int reset_transport();
+ int set_transport(int mode);
int get_w();
int is_stopped();
// Get the EDL to play back with default to mwindow->edl
public:
PTransportButton(MWindow *mwindow, PlayTransport *transport, int x, int y, VFrame **data);
virtual ~PTransportButton();
- virtual int set_mode(int mode);
+ void set_mode(int mode);
+ void loop_mode(int dir);
int play_command(const char *lock_msg, int command);
int mode;
values[i]->close_plugin();
}
}
-
- delete cache;
+ if( cache ) {
+ cache->remove_user();
+ cache = 0;
+ }
return 0;
}
#include "bcwindowbase.h"
#include "bctitle.h"
#include "cstrdup.h"
+#include "keys.h"
#include "language.h"
#include "mwindow.h"
#include "pluginfclient.h"
int PluginFClientText::handle_event()
{
+ if( get_keypress() == RETURN ) {
+ fwin->update();
+ activate();
+ }
return 0;
}
ProxyClient::~ProxyClient()
{
delete render_engine;
- delete video_cache;
+ if( video_cache )
+ video_cache->remove_user();
delete src_file;
}
mwindow->restart_brender();
if( farm_server ) delete farm_server;
delete command;
- delete audio_cache;
- delete video_cache;
+ audio_cache->remove_user();
+ video_cache->remove_user();
// Must delete packages after server
delete render->packages;
video_thread->stop();
}
-void ResourceThread::reset(int pane_number)
+void ResourceThread::reset(int pane_number, int indexes_only)
{
audio_thread->reset(pane_number);
- video_thread->reset(pane_number);
+ if( !indexes_only )
+ video_thread->reset(pane_number);
}
void ResourceThread::close_indexable(Indexable *idxbl)
void run();
void stop();
- void reset(int pane_number);
+ void reset(int pane_number, int indexes_only);
void close_indexable(Indexable*);
MWindow *mwindow;
Track *Track::gang_master()
{
- if( edl->session->gang_tracks == GANG_NONE ) return this;
Track *track = this;
- while( track && !track->master ) track = track->previous;
- return !track ? tracks->first : track;
+ switch( edl->session->gang_tracks ) {
+ case GANG_NONE:
+ return track;
+ case GANG_CHANNELS: {
+ Track *current = track;
+ int data_type = track->data_type;
+ while( current && !track->master ) {
+ if( !(current = current->previous) ) break;
+ if( current->data_type == data_type ) track = current;
+ if( track->master ) break;
+ }
+ break; }
+ case GANG_MEDIA: {
+ while( track && !track->master ) track = track->previous;
+ break; }
+ }
+ if( !track ) track = tracks->first;
+ return track;
}
int Track::is_hidden()
{
return gang_master()->armed;
}
+
int Track::is_ganged()
{
return gang_master()->ganged;
if(debug) PRINT_TRACE
if(mode != IGNORE_THREAD)
- gui->resource_thread->reset(pane->number);
+ gui->resource_thread->reset(pane->number, indexes_only);
// Search every edit
for(Track *current = mwindow->edl->tracks->first;
!vrender->process_buffer(&vlt, left, 0) &&
!vrender->process_buffer(&vrt, pos , 0) ? 0 : 1;
delete render_engine;
- delete video_cache;
+ video_cache->remove_user();
mwindow->cwindow->gui->lock_window("TrackCanvas::render_handle_frame 0");
Canvas *canvas = mwindow->cwindow->gui->canvas;
float ox1, oy1, ox2, oy2, cx1, cy1, cx2, cy2;
add_item(new TrackPopupShow(mwindow, this));
add_item(new TrackPopupUserTitle(mwindow, this));
add_item(new TrackPopupTitleColor(mwindow, this));
+ add_item(new TrackSwapUp(mwindow, this));
+ add_item(new TrackSwapDown(mwindow, this));
resize_option = 0;
matchsize_option = 0;
}
return 1;
}
-
-
TrackMoveDown::TrackMoveDown(MWindow *mwindow, TrackPopup *popup)
: BC_MenuItem(_("Move down"))
{
}
+TrackSwapUp::TrackSwapUp(MWindow *mwindow, TrackPopup *popup)
+ : BC_MenuItem(_("Swap up"))
+{
+ this->mwindow = mwindow;
+ this->popup = popup;
+}
+TrackSwapUp::~TrackSwapUp()
+{
+}
+int TrackSwapUp::handle_event()
+{
+ mwindow->swap_track_up(popup->track);
+ return 1;
+}
+
+TrackSwapDown::TrackSwapDown(MWindow *mwindow, TrackPopup *popup)
+ : BC_MenuItem(_("Swap down"))
+{
+ this->mwindow = mwindow;
+ this->popup = popup;
+}
+TrackSwapDown::~TrackSwapDown()
+{
+}
+int TrackSwapDown::handle_event()
+{
+ mwindow->swap_track_down(popup->track);
+ return 1;
+}
+
+
TrackPopupResize::TrackPopupResize(MWindow *mwindow, TrackPopup *popup)
: BC_MenuItem(_("Resize track..."))
{
TrackPopup *popup;
};
+class TrackSwapUp : public BC_MenuItem
+{
+public:
+ TrackSwapUp(MWindow *mwindow, TrackPopup *popup);
+ ~TrackSwapUp();
+
+ int handle_event();
+
+ MWindow *mwindow;
+ TrackPopup *popup;
+};
+
+class TrackSwapDown : public BC_MenuItem
+{
+public:
+ TrackSwapDown(MWindow *mwindow, TrackPopup *popup);
+ ~TrackSwapDown();
+
+ int handle_event();
+
+ MWindow *mwindow;
+ TrackPopup *popup;
+};
+
class TrackPopupFindAsset : public BC_MenuItem
{
public:
void equivalent_output(Tracks *tracks, double *result);
void move_tracks(Track *src, Track *dst, int n);
- int move_track_up(Track *track); // move recordable tracks up
- int move_track_down(Track *track); // move recordable tracks down
- int move_tracks_up(); // move recordable tracks up
- int move_tracks_down(); // move recordable tracks down
+ int move_track_up(Track *track);
+ int move_track_down(Track *track);
+ int move_tracks_up();
+ int move_tracks_down();
+ int swap_track_up(Track *track);
+ int swap_track_down(Track *track);
+ int swap_tracks_up();
+ int swap_tracks_down();
void paste_audio_transition(PluginServer *server);
void paste_video_transition(PluginServer *server, int first_track = 0);
}
+int Tracks::swap_track_up(Track *track)
+{
+ Track *next_track = track->previous;
+ if(!next_track) next_track = last;
+
+ change_modules(number_of(track), number_of(next_track), 1);
+ swap(track, next_track);
+ return 0;
+}
+
+int Tracks::swap_track_down(Track *track)
+{
+ Track *next_track = track->next;
+ if(!next_track) next_track = first;
+
+ change_modules(number_of(track), number_of(next_track), 1);
+ swap(track, next_track);
+ return 0;
+}
+
+
+int Tracks::swap_tracks_up()
+{
+ int result = 0;
+ Track *next = first;
+ while( next ) {
+ Track *track = next; next = track->next;
+ if( !track->armed ) continue;
+ if( track->previous ) {
+ change_modules(number_of(track->previous), number_of(track), 1);
+ swap(track->previous, track);
+ result = 1;
+ }
+ }
+
+ return result;
+}
+
+int Tracks::swap_tracks_down()
+{
+ int result = 0;
+ Track *prev = last;
+ while( prev ) {
+ Track *track = prev; prev = track->previous;
+ if( !track->armed ) continue;
+ if( track->next ) {
+ change_modules(number_of(track), number_of(track->next), 1);
+ swap(track, track->next);
+ result = 1;
+ }
+ }
+
+ return result;
+}
+
void Tracks::paste_audio_transition(PluginServer *server)
{
for(Track *current = first; current; current = NEXT)
for( int i=channels; --i>=0; ) delete samples[i];
delete render_engine;
- delete cache;
+ cache->remove_user();
delete canvas->refresh_frame;
canvas->refresh_frame = vframe;
canvas->refresh(1);
mwindow->theme->vtransport_x,
mwindow->theme->vtransport_y);
transport->create_objects();
+ transport->set_transport(LOOP_MODE);
//printf("VWindowGUI::create_objects 1\n");
// add_subwindow(fps_title = new BC_Title(mwindow->theme->vedit_x, y, ""));
delete yscroll; yscroll = 0;
}
- if( view_rows != text->get_rows() || view_w != text->get_w() ) {
+ if( view_rows != text->get_rows() || view_w != text->get_w() ||
+ x != text->get_x() || y != text->get_y() ) {
text->reposition_window(x, y, view_w, view_rows);
}
if( need_xscroll && !xscroll ) {
background = 0;
}
delete render_engine;
- delete video_cache;
+ if( video_cache )
+ video_cache->remove_user();
delete overlay_frame;
delete bg_file;
delete bg_frame;
Indexable *TitleMain::open_background(const char *filename)
{
delete render_engine; render_engine = 0;
- delete video_cache; video_cache = 0;
+ if( video_cache ) { video_cache->remove_user(); video_cache = 0; }
delete bg_file; bg_file = new File;
Asset *asset = new Asset(filename);