}
if( seq_no >= images.size() ) {
MWindow *mwindow = picon->mwindow;
- File *file = mwindow->video_cache->check_out(asset, mwindow->edl, 1);
- if( !file ) {
- broken = 1;
- return 0;
- }
if( temp && (temp->get_w() != asset->width || temp->get_h() != asset->height) ) {
delete temp; temp = 0;
}
if( !temp )
temp = new VFrame(0, -1, asset->width, asset->height, BC_RGB888, -1);
- while( seq_no >= images.size() ) {
- mwindow->video_cache->check_in(asset);
- Thread::yield();
- file = mwindow->video_cache->check_out(asset, mwindow->edl, 0);
- if( !file ) { usleep(1000); continue; }
- file->set_layer(0);
+ File *file = mwindow->video_cache->check_out(asset, mwindow->edl, 1);
+ while( file && seq_no >= images.size() ) {
int64_t pos = images.size() / picon->gui->vicon_thread->refresh_rate * frame_rate;
file->set_video_position(pos,0);
+ file->set_layer(0);
if( file->read_frame(temp) ) temp->clear_frame();
add_image(temp, vw, vh, vicon_cmodel);
+ mwindow->video_cache->check_in(asset);
+ Thread::yield();
+ file = 0;
+ for( int retries=1000; !file && --retries>=0; usleep(10000) )
+ file = mwindow->video_cache->check_out(asset, mwindow->edl, 0);
}
+ if( !file ) { broken = 1; return 0; }
mwindow->video_cache->check_in(asset);
}
return *images[seq_no];
if(!current) { // Create new item
current = new CICacheItem(this, edl, asset);
append(current); current->checked_out = tid;
+ total_lock->unlock();
file = current->file;
int result = file->open_file(preferences, asset, 1, 0);
- total_lock->unlock();
- if( result ) {
-SET_TRACE
- delete file;
- file = 0;
- }
+ if( result ) { delete file; file = 0; }
total_lock->lock("CICache::check_out 2");
if( !file ) {
remove_pointer(current);
}
else {
file = current->file;
- if(!current->checked_out) {
+ if( !current->checked_out ) {
// Return existing/new item
current->Garbage::add_user();
current->age = EDL::next_id();
current = 0;
}
total_lock->unlock();
- if(current || !file || !block) break;
+ if( current || !file || !block ) break;
// Try again after blocking
check_out_lock->lock("CICache::check_out");
}
void CICache::remove_all()
{
- CICacheItem *current, *temp;
List<CICacheItem> removed;
- total_lock->lock("CICache::remove_all");
- for(current=first; current; current=temp)
- {
- temp = NEXT;
-// Must not be checked out because we need the pointer to check back in.
-// Really need to give the user the CacheItem.
- if(!current->checked_out)
- {
-//printf("CICache::remove_all: %s\n", current->asset->path);
- remove_pointer(current);
- removed.append(current);
+ for(;;) {
+ total_lock->lock("CICache::remove_all");
+ CICacheItem *current = first;
+ while( current ) {
+ CICacheItem *next_item = current->next;
+ if( !current->checked_out ) {
+ remove_pointer(current);
+ removed.append(current);
+ }
+ current = next_item;
}
- }
- total_lock->unlock();
- while( (current=removed.first) != 0 )
- {
- removed.remove_pointer(current);
- current->Garbage::remove_user();
+ total_lock->unlock();
+ while( removed.first ) {
+ CICacheItem *current = removed.first;
+ removed.remove_pointer(current);
+ current->Garbage::remove_user();
+ }
+ if( !first ) break;
+ check_out_lock->lock();
}
}
int CICache::delete_entry(char *path)
{
- total_lock->lock("CICache::delete_entry");
- CICacheItem *current = first;
- while( current && strcmp(current->asset->path, path) !=0 )
- current = NEXT;
- if(current && !current->checked_out)
- remove_pointer(current);
- else
- current = 0;
-//printf("CICache::delete_entry: %s\n", current->asset->path);
+ CICacheItem *current = 0;
+ for( ;; ) {
+ total_lock->lock("CICache::delete_entry");
+ current = first;
+ while( current && strcmp(current->asset->path, path) !=0 )
+ current = NEXT;
+ if( !current ) break;
+ if( current->checked_out ) {
+ remove_pointer(current);
+ break;
+ }
+ total_lock->unlock();
+ check_out_lock->lock();
+ }
total_lock->unlock();
- if(current)
+ if( current )
current->Garbage::remove_user();
return 0;
}
CICacheItem *oldest = 0;
// at least 2
if( first != last ) {
- CICacheItem *current = first;
- oldest = current;
- while( (current=NEXT) != 0 ) {
+ oldest = first;
+ CICacheItem *current = oldest->next;
+ while( current ) {
if( current->age < oldest->age )
oldest = current;
+ current = current->next;
}
+ }
+// settle for just deleting one frame
+ else if( first )
+ result = first->file->delete_oldest();
+ if( oldest ) {
// Got the oldest file. Try requesting cache purge from it.
if( oldest->file )
oldest->file->purge_cache();
else
oldest = 0;
}
-// settle for just deleting one frame
- else if( first )
- result = first->file->delete_oldest();
total_lock->unlock();
if( oldest ) {
oldest->Garbage::remove_user();
if( pkt_ts >= tstmp ) break;
}
if( retry < 0 ) {
- fprintf(stderr,"FFStream::seek: retry limit, pos=%jd tstmp=%jd\n",pos,tstmp);
+ ff_err(AVERROR(EIO), "FFStream::seek: %s\n"
+ " retry limit, pos=%jd tstmp=%jd, ",
+ ffmpeg->fmt_ctx->url, pos, tstmp);
ret = -1;
}
if( ret < 0 ) break;
#include "dvdcreate.h"
#include "edl.h"
#include "edlsession.h"
+#include "exportedl.h"
#include "file.h"
#include "filesystem.h"
#include "filexml.h"
#include "transportque.h"
#include "viewmenu.h"
#include "zoombar.h"
-#include "exportedl.h"
+#include "zwindow.h"
+#include "zwindowgui.h"
#include <string.h>
{
BC_SubMenu *mixer_submenu = new BC_SubMenu();
add_submenu(mixer_submenu);
- mixer_submenu->add_submenuitem(new MixerViewer(mwindow));
- mixer_submenu->add_submenuitem(new TileMixers(mwindow));
- mixer_submenu->add_submenuitem(new AlignMixers(mwindow));
+ mixer_submenu->add_submenuitem(new MixerViewer(this));
+ mixer_submenu->add_submenuitem(new TileMixers(this));
+ mixer_submenu->add_submenuitem(new AlignMixers(this));
}
-MixerViewer::MixerViewer(MWindow *mwindow)
- : BC_MenuItem(_("Mixer Viewer"), _("Shift-M"), 'M')
+int MixerItems::activate_submenu()
+{
+ BC_SubMenu *mixer_submenu = (BC_SubMenu *)get_submenu();
+ int k = mixer_submenu->total_items();
+ while( --k >= 0 ) {
+ MixerItem *mixer_item = (MixerItem *)mixer_submenu->get_item(k);
+ if( mixer_item->idx < 0 ) continue;
+ mixer_submenu->del_item(mixer_item);
+ }
+ int n = mwindow->edl->mixers.size();
+ for( int i=0; i<n; ++i ) {
+ Mixer *mixer = mwindow->edl->mixers[i];
+ if( !mixer ) continue;
+ MixerItem *mixer_item = new MixerItem(this, mixer->title, mixer->idx);
+ mixer_submenu->add_submenuitem(mixer_item);
+ }
+ return BC_MenuItem::activate_submenu();
+}
+
+MixerItem::MixerItem(MixerItems *mixer_items, const char *text, int idx)
+ : BC_MenuItem(text)
+{
+ this->mixer_items = mixer_items;
+ this->idx = idx;
+}
+
+MixerItem::MixerItem(MixerItems *mixer_items, const char *text, const char *hotkey_text, int hotkey)
+ : BC_MenuItem(text, hotkey_text, hotkey)
+{
+ this->mixer_items = mixer_items;
+ this->idx = -1;
+}
+
+int MixerItem::handle_event()
+{
+ if( idx < 0 ) return 0;
+ MWindow *mwindow = mixer_items->mwindow;
+ Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+ if( !mixer ) return 0;
+ ZWindow *zwindow = mwindow->get_mixer(mixer);
+ if( !zwindow->zgui ) {
+ zwindow->set_title(mixer->title);
+ zwindow->start();
+ }
+ zwindow->zgui->lock_window("MixerItem::handle_event");
+ zwindow->zgui->raise_window();
+ zwindow->zgui->unlock_window();
+ mwindow->refresh_mixers();
+ return 1;
+}
+
+MixerViewer::MixerViewer(MixerItems *mixer_items)
+ : MixerItem(mixer_items, _("Mixer Viewer"), _("Shift-M"), 'M')
{
- this->mwindow = mwindow;
set_shift(1);
}
int MixerViewer::handle_event()
{
+ MWindow *mwindow = mixer_items->mwindow;
mwindow->start_mixer();
return 1;
}
-TileMixers::TileMixers(MWindow *mwindow)
- : BC_MenuItem(_("Tile mixers"), "Alt-t", 't')
+TileMixers::TileMixers(MixerItems *mixer_items)
+ : MixerItem(mixer_items, _("Tile mixers"), "Alt-t", 't')
{
- this->mwindow = mwindow;
set_alt();
}
int TileMixers::handle_event()
{
+ MWindow *mwindow = mixer_items->mwindow;
mwindow->tile_mixers();
return 1;
}
-AlignMixers::AlignMixers(MWindow *mwindow)
- : BC_MenuItem(_("Align mixers"))
+AlignMixers::AlignMixers(MixerItems *mixer_items)
+ : MixerItem(mixer_items, _("Align mixers"), "", 0)
{
- this->mwindow = mwindow;
}
int AlignMixers::handle_event()
{
+ MWindow *mwindow = mixer_items->mwindow;
int wx, wy;
mwindow->gui->get_abs_cursor(wx, wy);
mwindow->mixers_align->start_dialog(wx, wy);
public:
MixerItems(MWindow *mwindow);
void create_objects();
+ int activate_submenu();
+
MWindow *mwindow;
};
-class MixerViewer : public BC_MenuItem
+class MixerItem : public BC_MenuItem
+{
+public:
+ MixerItem(MixerItems *mixer_items, const char *text, int idx);
+ MixerItem(MixerItems *mixer_items, const char *text, const char *hotkey_text, int hotkey);
+ virtual int handle_event();
+
+ MixerItems *mixer_items;
+ int idx;
+};
+
+class MixerViewer : public MixerItem
{
public:
- MixerViewer(MWindow *mwindow);
+ MixerViewer(MixerItems *mixer_items);
int handle_event();
- MWindow *mwindow;
};
-class TileMixers : public BC_MenuItem
+class TileMixers : public MixerItem
{
public:
- TileMixers(MWindow *mwindow);
+ TileMixers(MixerItems *mixer_items);
int handle_event();
- MWindow *mwindow;
};
-class AlignMixers : public BC_MenuItem
+class AlignMixers : public MixerItem
{
public:
- AlignMixers(MWindow *mwindow);
+ AlignMixers(MixerItems *mixer_items);
int handle_event();
- MWindow *mwindow;
};
// ======================================== audio
return zwindow;
}
-void MWindow::del_mixer(ZWindow *zwindow)
+void MWindow::close_mixer(ZWindow *zwindow)
{
- zwindows_lock->lock("MWindow::del_mixer 0");
- edl->mixers.del_mixer(zwindow->idx);
+ zwindows_lock->lock("MWindow::close_mixer 0");
if( session->selected_zwindow >= 0 ) {
int i = zwindows.number_of(zwindow);
if( i >= 0 && i < session->selected_zwindow )
session->selected_zwindow = -1;
}
zwindows_lock->unlock();
- gui->lock_window("MWindow::del_mixer 1");
+ gui->lock_window("MWindow::close_mixer 1");
gui->update_mixers(0, -1);
gui->unlock_window();
}
for( int i=0; i<edl->mixers.size(); ++i ) {
Mixer *mixer = edl->mixers[i];
+ if( !mixer->show ) continue;
ZWindow *zwindow = get_mixer(mixer);
zwindow->set_title(mixer->title);
zwindow->start();
return;
}
undo_before();
- awindow->gui->close_view_popup();
+ awindow->gui->stop_vicon_drawing();
int clips_total = session->drag_clips->total;
for( int i=0; i<clips_total; ++i ) {
EDL *clip = session->drag_clips->values[i];
void MWindow::reset_caches()
{
- awindow->gui->close_view_popup();
+ awindow->gui->stop_vicon_drawing();
frame_cache->remove_all();
wave_cache->remove_all();
audio_cache->remove_all();
void MWindow::remove_from_caches(Indexable *idxbl)
{
- awindow->gui->close_view_popup();
+ awindow->gui->stop_vicon_drawing();
frame_cache->remove_item(idxbl);
wave_cache->remove_item(idxbl);
if( gui->render_engine &&
void MWindow::remove_assets_from_project(int push_undo, int redraw, int delete_indexes,
ArrayList<Indexable*> *drag_assets, ArrayList<EDL*> *drag_clips)
{
- awindow->gui->close_view_popup();
+ awindow->gui->stop_vicon_drawing();
// Remove from VWindow.
if( drag_clips ) {
void close_mixers(int result=1);
void open_mixers();
ZWindow *get_mixer(Mixer *&mixer);
- void del_mixer(ZWindow *zwindow);
+ void close_mixer(ZWindow *zwindow);
int mixer_track_active(Track *track);
void update_mixer_tracks();
void start_mixer();
set_fauto_xyz(AUTOMATION_CAMERA_X, x, y, z);
}
+int Track::index_in(Mixer *mixer)
+{
+ if( !mixer || mixer_id ) return -1;
+ int k = mixer->mixer_ids.size();
+ while( --k >= 0 && mixer_id != mixer->mixer_ids[k] );
+ return k;
+}
+
#include "trackcanvas.inc"
#include "tracks.inc"
#include "transition.inc"
+#include "zwindow.inc"
// UNITS ARE SAMPLES FOR ALL
void change_plugins(SharedLocation &old_location, SharedLocation &new_location, int do_swap);
void change_modules(int old_location, int new_location, int do_swap);
Plugin *plugin_exists(int plugin_id);
+ int index_in(Mixer *mixer);
EDL *edl;
Tracks *tracks;
remove_all_objects();
}
-Mixer *Mixers::new_mixer()
+Mixer *Mixers::new_mixer(int show)
{
int idx = 0;
for( int i=0; i<size(); ++i ) {
Mixer *mixer = get(i);
if( idx < mixer->idx ) idx = mixer->idx;
}
- return append(new Mixer(idx+1));
+ return append(new Mixer(idx+1, show));
}
Mixer *Mixers::get_mixer(int idx)
return 0;
}
-void Mixers::del_mixer(int idx)
+void Mixers::del_mixer(Mixer *mixer)
{
- Mixer *mixer = get_mixer(idx);
- if( mixer ) remove_object(mixer);
+ remove_object(mixer);
}
void Mixer::set_title(const char *tp)
if( file->tag.title_is("MIXER") ) {
Mixer *mixer = new_mixer();
file->tag.get_property("TITLE", mixer->title);
+ mixer->show = file->tag.get_property("SHOW", 1);
mixer->x = file->tag.get_property("X", mixer->x);
mixer->y = file->tag.get_property("Y", mixer->y);
mixer->w = file->tag.get_property("W", mixer->w);
void Mixer::save(FileXML *file)
{
file->tag.set_title("MIXER");
+ file->tag.set_property("SHOW",show);
file->tag.set_property("TITLE",title);
file->tag.set_property("X",x);
file->tag.set_property("Y",y);
file->append_newline();
}
-Mixer::Mixer(int idx)
+Mixer::Mixer(int idx, int show)
{
this->idx = idx;
+ this->show = show;
title[0] = 0;
x = y = 100 + idx*64;
w = 400; h = 300;
BC_Window* ZWindow::new_gui()
{
Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+ mixer->show = 1;
zgui = new ZWindowGUI(mwindow, this, mixer);
zgui->create_objects();
return zgui;
void ZWindow::handle_done_event(int result)
{
stop_playback(1);
- if( result )
- mwindow->del_mixer(this);
+ if( result ) {
+ mwindow->close_mixer(this);
+ Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+ if( mixer ) mixer->show = 0;
+ Track *track = mixer ? mwindow->edl->tracks->first : 0;
+ while( track && track->index_in(mixer) < 0 ) track = track->next;
+// if no refs to tracks, delete it
+ if( !track ) mwindow->edl->mixers.del_mixer(mixer);
+ }
idx = -1;
}
void ZWindow::handle_close_event(int result)
class Mixer {
public:
- int idx;
+ int idx, show;
int x, y, w, h;
ArrayList<int> mixer_ids;
char title[BCSTRLEN];
- Mixer(int idx);
+ Mixer(int idx, int show);
void save(FileXML *file);
int load(FileXML *file);
void copy_from(Mixer &that);
public:
Mixers();
~Mixers();
- Mixer *new_mixer();
+ Mixer *new_mixer(int show=0);
Mixer *get_mixer(int idx);
- void del_mixer(int idx);
+ void del_mixer(Mixer *mixer);
void save(FileXML *file);
int load(FileXML *file);
void copy_from(Mixers &that);
int FileSystem::extract_name(char *out, const char *in, int test_dir)
{
- int i;
-
if(test_dir && is_dir(in))
out[0] = 0; // complete string is directory
- else
- {
- for(i = strlen(in)-1; i > 0 && in[i] != '/'; i--)
- {
- ;
- }
- if(in[i] == '/') i++;
- strcpy(out, &in[i]);
+ else {
+ const char *cp = strrchr(in, '/');
+ const char *bp = !cp ? in : cp + 1;
+ strcpy(out, bp);
}
return 0;
}