vicon checkout fix, checkout tweak, remove_all/delete_oldest rework, ffmpeg seek...
authorGood Guy <[email protected]>
Sat, 20 Jun 2020 22:00:53 +0000 (16:00 -0600)
committerGood Guy <[email protected]>
Sat, 20 Jun 2020 22:00:53 +0000 (16:00 -0600)
12 files changed:
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/cache.C
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/mainmenu.C
cinelerra-5.1/cinelerra/mainmenu.h
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/track.C
cinelerra-5.1/cinelerra/track.h
cinelerra-5.1/cinelerra/zwindow.C
cinelerra-5.1/cinelerra/zwindow.h
cinelerra-5.1/guicast/filesystem.C

index 7f7300a8a0797c5d2ec90527a8189b14ccd895fc..b74a0a7cadefa42cc258d79629b33897fc1f0a1c 100644 (file)
@@ -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];
index 4c94adbfe78ba4f6a0616cd21094155b53a3df02..ec219d2180e669e7399d087115180fc766d21c7a 100644 (file)
@@ -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<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;
 }
@@ -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();
index 499974f0e201ac30f3937dc90125d554d746d47c..23549f9a0c603a82175ffd1f1176f8d59193b19a 100644 (file)
@@ -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;
index 94c884206b3ac4e6c826546792f0d66734545760..f616d26a12819b6bf650ddf79c4ae2c06949d457 100644 (file)
@@ -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 <string.h>
 
@@ -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; 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);
index 9e0513cdb4cfa7c0af82b45137a1116307caa177..681ba38459927d37921fa2c77a5cf2a12c673440 100644 (file)
@@ -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
index 73df71401e603fe569df21ebde0bac0dd3630c5b..0fe6752f3598394b1fe16e6d1900e18a6c0631ba 100644 (file)
@@ -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; 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();
@@ -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; i<clips_total; ++i ) {
                EDL *clip = session->drag_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<Indexable*> *drag_assets, ArrayList<EDL*> *drag_clips)
 {
-       awindow->gui->close_view_popup();
+       awindow->gui->stop_vicon_drawing();
 
 // Remove from VWindow.
        if( drag_clips ) {
index 59f816c658ccfd5f2c4917ac590aca75cd54d7cb..c7076099ce7bae36dacaec3571a912eadf8a4447 100644 (file)
@@ -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();
index 27cd96b5076e5f7126bee7ad59556909ff4bab98..7a01982f002aefedca928d81ba7dcfcee89a63a2 100644 (file)
@@ -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;
+}
+
index f59e989804905f877a08a25ca1cad5bf5caf8edd..ba47679c7488d08a797c6fac426ec4c34b4d9147 100644 (file)
@@ -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;
index a833b284fbf09c5ad866d27f22833a4cb91c984f..da28e0136170a4f0598b2b29cd27ed55e4da8d26 100644 (file)
@@ -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; 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)
@@ -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)
index ea76bdf45aaea24ffa0524f033be6981a6156752..11b238ab80bca6278b83f51a1372dcc5114c12d6 100644 (file)
 
 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);
@@ -51,9 +51,9 @@ class Mixers : public ArrayList<Mixer *>
 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);
index ebc2007da9e145744e7d5b85dc05915ff79763f3..6017f6eaf7deeff4c9aa4d30a6ffa006398dd8f0 100644 (file)
@@ -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;
 }