From 1da768016a2ecba0296b03d75c02879f99a0f582 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Sat, 20 Jun 2020 16:00:53 -0600 Subject: [PATCH] vicon checkout fix, checkout tweak, remove_all/delete_oldest rework, ffmpeg seek retry limit msg, mixer menu mods, extract_name valgrind bug fix --- cinelerra-5.1/cinelerra/awindowgui.C | 20 +++---- cinelerra-5.1/cinelerra/cache.C | 88 +++++++++++++++------------- cinelerra-5.1/cinelerra/ffmpeg.C | 4 +- cinelerra-5.1/cinelerra/mainmenu.C | 79 +++++++++++++++++++++---- cinelerra-5.1/cinelerra/mainmenu.h | 28 ++++++--- cinelerra-5.1/cinelerra/mwindow.C | 16 ++--- cinelerra-5.1/cinelerra/mwindow.h | 2 +- cinelerra-5.1/cinelerra/track.C | 8 +++ cinelerra-5.1/cinelerra/track.h | 2 + cinelerra-5.1/cinelerra/zwindow.C | 26 +++++--- cinelerra-5.1/cinelerra/zwindow.h | 8 +-- cinelerra-5.1/guicast/filesystem.C | 14 ++--- 12 files changed, 188 insertions(+), 107 deletions(-) diff --git a/cinelerra-5.1/cinelerra/awindowgui.C b/cinelerra-5.1/cinelerra/awindowgui.C index 7f7300a8..b74a0a7c 100644 --- a/cinelerra-5.1/cinelerra/awindowgui.C +++ b/cinelerra-5.1/cinelerra/awindowgui.C @@ -164,27 +164,25 @@ VFrame *AssetVIcon::frame() } 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]; diff --git a/cinelerra-5.1/cinelerra/cache.C b/cinelerra-5.1/cinelerra/cache.C index 4c94adbf..ec219d21 100644 --- a/cinelerra-5.1/cinelerra/cache.C +++ b/cinelerra-5.1/cinelerra/cache.C @@ -81,14 +81,10 @@ File* CICache::check_out(Asset *asset, EDL *edl, int block) 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); @@ -101,7 +97,7 @@ SET_TRACE } 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(); @@ -113,7 +109,7 @@ SET_TRACE 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"); } @@ -148,42 +144,47 @@ int CICache::check_in(Asset *asset) void CICache::remove_all() { - CICacheItem *current, *temp; List 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; } @@ -247,12 +248,18 @@ int CICache::delete_oldest() 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(); @@ -262,9 +269,6 @@ int CICache::delete_oldest() 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(); diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 499974f0..23549f9a 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -762,7 +762,9 @@ int FFStream::seek(int64_t no, double rate) 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; diff --git a/cinelerra-5.1/cinelerra/mainmenu.C b/cinelerra-5.1/cinelerra/mainmenu.C index 94c88420..f616d26a 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.C +++ b/cinelerra-5.1/cinelerra/mainmenu.C @@ -37,6 +37,7 @@ #include "dvdcreate.h" #include "edl.h" #include "edlsession.h" +#include "exportedl.h" #include "file.h" #include "filesystem.h" #include "filexml.h" @@ -78,7 +79,8 @@ #include "transportque.h" #include "viewmenu.h" #include "zoombar.h" -#include "exportedl.h" +#include "zwindow.h" +#include "zwindowgui.h" #include @@ -1628,45 +1630,96 @@ void MixerItems::create_objects() { 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; iedl->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); diff --git a/cinelerra-5.1/cinelerra/mainmenu.h b/cinelerra-5.1/cinelerra/mainmenu.h index 9e0513cd..681ba384 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.h +++ b/cinelerra-5.1/cinelerra/mainmenu.h @@ -501,31 +501,41 @@ class MixerItems : public BC_MenuItem 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 diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 73df7140..0fe6752f 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -1210,10 +1210,9 @@ ZWindow *MWindow::get_mixer(Mixer *&mixer) 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 ) @@ -1222,7 +1221,7 @@ void MWindow::del_mixer(ZWindow *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(); } @@ -3750,6 +3749,7 @@ void MWindow::update_project(int load_mode) for( int i=0; imixers.size(); ++i ) { Mixer *mixer = edl->mixers[i]; + if( !mixer->show ) continue; ZWindow *zwindow = get_mixer(mixer); zwindow->set_title(mixer->title); zwindow->start(); @@ -3964,7 +3964,7 @@ void MWindow::clip_to_media() return; } undo_before(); - awindow->gui->close_view_popup(); + awindow->gui->stop_vicon_drawing(); int clips_total = session->drag_clips->total; for( int i=0; idrag_clips->values[i]; @@ -4441,7 +4441,7 @@ int MWindow::create_aspect_ratio(float &w, float &h, int width, int height) 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(); @@ -4465,7 +4465,7 @@ void MWindow::reset_caches() 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 && @@ -4505,7 +4505,7 @@ void MWindow::remove_from_caches(Indexable *idxbl) void MWindow::remove_assets_from_project(int push_undo, int redraw, int delete_indexes, ArrayList *drag_assets, ArrayList *drag_clips) { - awindow->gui->close_view_popup(); + awindow->gui->stop_vicon_drawing(); // Remove from VWindow. if( drag_clips ) { diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index 59f816c6..c7076099 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -274,7 +274,7 @@ public: 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(); diff --git a/cinelerra-5.1/cinelerra/track.C b/cinelerra-5.1/cinelerra/track.C index 27cd96b5..7a01982f 100644 --- a/cinelerra-5.1/cinelerra/track.C +++ b/cinelerra-5.1/cinelerra/track.C @@ -1851,3 +1851,11 @@ void Track::set_camera(float x, float y, float z) 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; +} + diff --git a/cinelerra-5.1/cinelerra/track.h b/cinelerra-5.1/cinelerra/track.h index f59e9898..ba47679c 100644 --- a/cinelerra-5.1/cinelerra/track.h +++ b/cinelerra-5.1/cinelerra/track.h @@ -50,6 +50,7 @@ #include "trackcanvas.inc" #include "tracks.inc" #include "transition.inc" +#include "zwindow.inc" // UNITS ARE SAMPLES FOR ALL @@ -165,6 +166,7 @@ public: 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; diff --git a/cinelerra-5.1/cinelerra/zwindow.C b/cinelerra-5.1/cinelerra/zwindow.C index a833b284..da28e013 100644 --- a/cinelerra-5.1/cinelerra/zwindow.C +++ b/cinelerra-5.1/cinelerra/zwindow.C @@ -46,14 +46,14 @@ Mixers::~Mixers() remove_all_objects(); } -Mixer *Mixers::new_mixer() +Mixer *Mixers::new_mixer(int show) { int idx = 0; for( int i=0; iidx ) idx = mixer->idx; } - return append(new Mixer(idx+1)); + return append(new Mixer(idx+1, show)); } Mixer *Mixers::get_mixer(int idx) @@ -65,10 +65,9 @@ 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) @@ -100,6 +99,7 @@ int Mixers::load(FileXML *file) 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); @@ -122,6 +122,7 @@ void Mixers::copy_from(Mixers &that) 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); @@ -142,9 +143,10 @@ void Mixer::save(FileXML *file) 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; @@ -202,6 +204,7 @@ ZWindow::~ZWindow() 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; @@ -210,8 +213,15 @@ BC_Window* ZWindow::new_gui() 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) diff --git a/cinelerra-5.1/cinelerra/zwindow.h b/cinelerra-5.1/cinelerra/zwindow.h index ea76bdf4..11b238ab 100644 --- a/cinelerra-5.1/cinelerra/zwindow.h +++ b/cinelerra-5.1/cinelerra/zwindow.h @@ -33,12 +33,12 @@ class Mixer { public: - int idx; + int idx, show; int x, y, w, h; ArrayList 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); @@ -51,9 +51,9 @@ class Mixers : public ArrayList 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); diff --git a/cinelerra-5.1/guicast/filesystem.C b/cinelerra-5.1/guicast/filesystem.C index ebc2007d..6017f6ea 100644 --- a/cinelerra-5.1/guicast/filesystem.C +++ b/cinelerra-5.1/guicast/filesystem.C @@ -667,18 +667,12 @@ int FileSystem::extract_dir(char *out, const char *in) 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; } -- 2.26.2