alt transport keys, snap editing, grab focus, inv hilight clr, subtitle fix
[goodguy/history.git] / cinelerra-5.1 / cinelerra / mwindow.C
index 577f229ef5f1216236cda2bcb40e6c79e95f685f..1aa06bacab9eecb97a2f23c6a231638ff57c69da 100644 (file)
@@ -89,6 +89,7 @@
 #include "pluginserver.h"
 #include "pluginset.h"
 #include "preferences.h"
+#include "proxy.h"
 #include "record.h"
 #include "recordmonitor.h"
 #include "recordlabel.h"
@@ -201,6 +202,7 @@ MWindow::MWindow()
        mainprogress = 0;
        brender = 0;
        brender_active = 0;
+       strcpy(cin_lang,"en");
        channeldb_buz =  new ChannelDB;
        channeldb_v4l2jpeg =  new ChannelDB;
        //file_server = 0;
@@ -230,6 +232,7 @@ MWindow::MWindow()
 MWindow::~MWindow()
 {
        run_lock->lock("MWindow::~MWindow");
+       stop_playback(1);
        in_destructor = 1;
 //printf("MWindow::~MWindow %d\n", __LINE__);
        gui->stop_drawing();
@@ -295,6 +298,9 @@ MWindow::~MWindow()
 #endif
        reset_caches();
        dead_plugins->remove_all_objects();
+// must delete theme before destroying plugindb
+//  theme destructor will be deleted by delete_plugins
+       delete theme;           theme = 0;
        delete_plugins();
        finit_error();
        keyframe_threads->remove_all_objects();
@@ -323,7 +329,6 @@ MWindow::~MWindow()
        delete defaults;        defaults = 0;
        delete assets;          assets = 0;
        delete splash_window;   splash_window = 0;
-//     delete theme;           theme = 0;      // deleted by delete_plugins
        if( !edl->Garbage::remove_user() ) edl = 0;
        delete channeldb_buz;
        delete channeldb_v4l2jpeg;
@@ -470,7 +475,7 @@ void MWindow::check_language()
        if( !env_lang ) env_lang = getenv("LC_ALL");
        if( !env_lang ) env_lang = getenv("LANG");
        if( !env_lang ) {
-               snprintf(curr_lang, sizeof(curr_lang), "%s-%s.%s",
+               snprintf(curr_lang, sizeof(curr_lang), "%s_%s-%s",
                        BC_Resources::language, BC_Resources::region, BC_Resources::encoding);
                env_lang = curr_lang;
        }
@@ -487,6 +492,12 @@ void MWindow::check_language()
                ::remove(ladspa_path);
                defaults->save();
        }
+       if( strlen(env_lang) > 1 &&
+           ( env_lang[2] == 0 || env_lang[2] == '_'  || env_lang[2] == '.' ) ) {
+               cin_lang[0] = env_lang[0];  cin_lang[1] = env_lang[1];  cin_lang[2] = 0;
+       }
+       else
+               strcpy(cin_lang, "en");
 }
 
 void MWindow::get_plugin_path(char *path, const char *plug_dir, const char *fs_path)
@@ -725,6 +736,66 @@ void MWindow::add_plugins(ArrayList<PluginServer*> &plugins)
        plugins.remove_all();
 }
 
+void MWindow::init_plugin_tips(ArrayList<PluginServer*> &plugins, const char *lang)
+{
+       const char *cfg_path = File::get_cindat_path();
+       char msg_path[BCTEXTLEN];  int txt = 0;
+       FILE *fp = 0;
+       if( BC_Resources::language[0] ) {
+               snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.%s",
+                       cfg_path, lang);
+               fp = fopen(msg_path, "r");
+       }
+       if( !fp ) {
+               txt = 1;
+               snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.txt",
+                       cfg_path);
+               fp = fopen(msg_path, "r");
+       }
+       if( !fp ) return;
+       char text[BCTEXTLEN];
+       char *tp = text, *ep = tp + sizeof(text)-1;
+       char title[BCTEXTLEN];
+       title[0] = 0;
+       int no = 0;
+       for(;;) {
+               ++no;  int done = 1;
+               char line[BCTEXTLEN], *cp = line;
+               if( fgets(line,sizeof(line)-1,fp) ) {
+                       if( *cp == '#' ) continue;
+                       done = *cp == ' ' || *cp == '\t' ? 0 : -1;
+               }
+               if( done ) {
+                       if( tp > text && *--tp == '\n' ) *tp = 0;
+                       if( title[0] ) {
+                               tp = !txt ? title : _(title);
+                               int idx = plugins.size();
+                               while( --idx>=0 && strcmp(plugins[idx]->title, tp) );
+                               if( idx >= 0 ) {
+                                       delete [] plugins[idx]->tip;
+                                       plugins[idx]->tip = cstrdup(text);
+                               }
+                               title[0] = 0;
+                       }
+                       if( done > 0 ) break;
+                       tp = text;  *tp = 0;
+                       char *dp = strchr(cp, ':');
+                       if( !dp ) {
+                               printf("plugin tips: error on line %d\n", no);
+                               continue;
+                       }
+                       char *bp = title;
+                       while( cp < dp ) *bp++ = *cp++;
+                       *bp = 0;
+                       ++cp;
+               }
+
+               while( *cp == ' ' || *cp == '\t' ) ++cp;
+               for( ; tp<ep && (*tp=*cp)!=0; ++tp,++cp );
+       }
+       fclose(fp);
+}
+
 void MWindow::delete_plugins()
 {
        plugindb->remove_all_objects();
@@ -825,6 +896,7 @@ void MWindow::init_preferences()
        }
        BC_WindowBase::get_resources()->popupmenu_btnup = preferences->popupmenu_btnup;
        BC_WindowBase::get_resources()->textbox_focus_policy = preferences->textbox_focus_policy;
+       BC_WindowBase::get_resources()->grab_input_focus = preferences->grab_input_focus;
 }
 
 void MWindow::clean_indexes()
@@ -919,6 +991,7 @@ void MWindow::init_gwindow()
 
 void MWindow::init_tipwindow()
 {
+       TipWindow::load_tips(cin_lang);
        if( !twindow )
                twindow = new TipWindow(this);
        twindow->start();
@@ -953,12 +1026,13 @@ void MWindow::init_theme()
                fprintf(stderr, _("MWindow::init_theme: prefered theme %s not found.\n"),
                         preferences->theme);
 
-       if( !theme_plugin && strcasecmp(preferences->theme, DEFAULT_THEME) ) {
+       const char *default_theme = _(DEFAULT_THEME);
+       if( !theme_plugin && strcasecmp(preferences->theme, default_theme) ) {
                fprintf(stderr, _("MWindow::init_theme: trying default theme %s\n"),
-                       DEFAULT_THEME);
+                       default_theme);
                for(int i = 0; i < plugindb->total && !theme_plugin; i++) {
                        if( plugindb->get(i)->theme &&
-                           !strcasecmp(DEFAULT_THEME, plugindb->get(i)->title) )
+                           !strcasecmp(default_theme, plugindb->get(i)->title) )
                                theme_plugin = plugindb->get(i);
                }
        }
@@ -1171,20 +1245,28 @@ void MWindow::init_brender()
 void MWindow::restart_brender()
 {
 //printf("MWindow::restart_brender 1\n");
-       if(!brender_active || !preferences->use_brender) return;
-       if(brender) brender->restart(edl);
+       if( !brender_active || !preferences->use_brender ) return;
+       if( !brender ) return;
+       int locked  = gui->get_window_lock();
+       if( locked ) gui->unlock_window();
+       brender->restart(edl);
+       if( locked ) gui->lock_window("MWindow::restart_brender");
 }
 
 void MWindow::stop_brender()
 {
-       if(brender) brender->stop();
+       if( !brender ) return;
+       int locked  = gui->get_window_lock();
+       if( locked ) gui->unlock_window();
+       brender->stop();
+       if( locked ) gui->lock_window("MWindow::stop_brender");
 }
 
 int MWindow::brender_available(int position)
 {
        int result = 0;
        brender_lock->lock("MWindow::brender_available 1");
-       if(brender)
+       if(brender && brender_active)
        {
                if(brender->map_valid)
                {
@@ -1217,8 +1299,10 @@ void MWindow::set_brender_active(int v, int update)
                }
                restart_brender();
        }
-       else
+       else {
+               edl->session->brender_start = edl->session->brender_end = 0;
                stop_brender();
+       }
        if( update ) {
                gui->update_timebar(0);
                gui->draw_overlays(1);
@@ -1326,17 +1410,12 @@ void MWindow::stop_playback(int wait)
        int locked  = gui->get_window_lock();
        if( locked ) gui->unlock_window();
 
-       cwindow->playback_engine->que->send_command(STOP,
-               CHANGE_NONE,
-               0,
-               0);
-       cwindow->playback_engine->interrupt_playback(wait);
+       cwindow->playback_engine->stop_playback();
 
        for(int i = 0; i < vwindows.size(); i++) {
                VWindow *vwindow = vwindows[i];
                if( !vwindow->is_running() ) continue;
-               vwindow->playback_engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
-               vwindow->playback_engine->interrupt_playback(wait);
+               vwindow->playback_engine->stop_playback();
        }
        if( locked ) gui->lock_window("MWindow::stop_playback");
 }
@@ -1417,14 +1496,10 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
                                if(load_mode != LOADMODE_RESOURCESONLY)
                                {
-SET_TRACE
                                        RecordLabels *labels = edl->session->label_cells ?
                                                new RecordLabels(new_file) : 0;
-SET_TRACE
                                        asset_to_edl(new_edl, new_asset, labels);
-SET_TRACE
                                        new_edls.append(new_edl);
-SET_TRACE
                                        new_asset->Garbage::remove_user();
                                        delete labels;
                                        new_asset = 0;
@@ -1455,17 +1530,16 @@ SET_TRACE
                        case FILE_NOT_FOUND:
                                sprintf(string, _("Failed to open %s"), new_asset->path);
                                gui->show_message(string, theme->message_error);
+                               gui->update_default_message();
                                break;
 
 // Unknown format
                        case FILE_UNRECOGNIZED_CODEC:
                        {
 // Test index file
-                               IndexFile indexfile(this, new_asset);
-                               result = indexfile.open_index();
-                               if(!result)
-                               {
-                                       indexfile.close_index();
+                               {       IndexFile indexfile(this, new_asset);
+                                       if( !(result = indexfile.open_index()) )
+                                               indexfile.close_index();
                                }
 
 // Test existing EDLs
@@ -1474,7 +1548,7 @@ SET_TRACE
                                                new_edls[j]->assets->get_asset(new_asset->path) :
                                                edl->assets->get_asset(new_asset->path);
                                        if( old_asset ) {
-                                               *new_asset = *old_asset;
+                                               new_asset->copy_from(old_asset,1);
                                                result = 0;
                                        }
                                }
@@ -1598,6 +1672,15 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                                if(update_filename)
                                                        set_filename(new_edl->local_session->clip_title);
                                        }
+                                       else
+                                       if( load_mode == LOADMODE_RESOURCESONLY ) {
+                                               strcpy(new_edl->local_session->clip_title,
+                                                       filenames->get(i));
+                                               struct stat st;
+                                               time_t t = !stat(filenames->get(i),&st) ?
+                                                       st.st_mtime : time(&t);
+                                               ctime_r(&t, new_edl->local_session->clip_notes);
+                                       }
                                }
 
                                new_edls.append(new_edl);
@@ -1618,12 +1701,10 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 
-       if(!result) gui->statusbar->default_message();
-
-
-
-
-
+       if(!result) {
+               gui->reset_default_message();
+               gui->default_message();
+       }
 
 
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
@@ -1646,10 +1727,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                        edl->session->autos_follow_edits);
                }
 
-               paste_edls(&new_edls,
-                       load_mode,
-                       0,
-                       -1,
+               paste_edls(&new_edls, load_mode, 0, -1,
                        edl->session->labels_follow_edits,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits,
@@ -1677,32 +1755,26 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
        }
 
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
-       if(new_assets.size())
+       for(int i = 0; i < new_assets.size(); i++)
        {
-               for(int i = 0; i < new_assets.size(); i++)
-               {
-                       Asset *new_asset = new_assets[i];
+               Asset *new_asset = new_assets[i];
 
-                       File *new_file = 0;
-                       int got_it = 0;
-                       for(int j = 0; j < new_files.size(); j++)
+               File *new_file = 0;
+               int got_it = 0;
+               for(int j = 0; j < new_files.size(); j++)
+               {
+                       new_file = new_files[j];
+                       if(!strcmp(new_file->asset->path,
+                               new_asset->path))
                        {
-                               new_file = new_files[j];
-                               if(!strcmp(new_file->asset->path,
-                                       new_asset->path))
-                               {
-                                       got_it = 1;
-                                       break;
-                               }
+                               got_it = 1;
+                               break;
                        }
-
-                       mainindexes->add_next_asset(got_it ? new_file : 0, new_asset);
-                       got_indexes = 1;
-                       edl->assets->update(new_asset);
-
                }
 
-
+               mainindexes->add_next_asset(got_it ? new_file : 0, new_asset);
+               got_indexes = 1;
+               edl->assets->update(new_asset);
        }
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
@@ -1730,10 +1802,6 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                                show_plugin(plugin);
                                        }
                                }
-                               else
-                               {
-                                       plugin->show = 0;
-                               }
 
                                plugin = (Plugin*)plugin->next;
                        }
@@ -1747,6 +1815,9 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
            ( load_mode == LOADMODE_REPLACE ||
              load_mode == LOADMODE_REPLACE_CONCATENATE ) ) {
                select_asset(0, 0);
+               edl->session->proxy_scale = 1;
+               edl->session->proxy_use_scaler = 0;
+               edl->session->proxy_auto_scale = 0;
                edl->local_session->preview_start = 0;
                edl->local_session->preview_end = edl->tracks->total_playable_length();
                edl->local_session->loop_playback = 0;
@@ -1757,6 +1828,29 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                goto_start();
        }
 
+       if( ( edl->session->proxy_auto_scale && edl->session->proxy_scale != 1 ) &&
+           ( load_mode != LOADMODE_REPLACE && load_mode != LOADMODE_REPLACE_CONCATENATE ) ) {
+               ArrayList<Indexable *> orig_idxbls;
+               for( int i=0; i<new_assets.size(); ++i )
+                       orig_idxbls.append(new_assets.get(i));
+               for( int i=0; i<new_edls.size(); ++i ) {
+                       EDL *new_edl = new_edls[i];
+                       for( Track *track=new_edl->tracks->first; track; track=track->next ) {
+                               if( track->data_type != TRACK_VIDEO ) continue;
+                               for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                                       Indexable *idxbl = (Indexable *)edit->asset;
+                                       if( !idxbl ) continue;
+                                       if( !idxbl->have_video() ) continue;
+                                       if( edit->channel != 0 ) continue; // first layer only
+                                       orig_idxbls.append(edit->asset);
+                               }
+                       }
+               }
+               gui->unlock_window(); // to update progress bar
+               render_proxy(orig_idxbls);
+               gui->lock_window("MWindow::load_filenames");
+       }
+
 // need to update undo before project, since mwindow is unlocked & a new load
 // can begin here.  Should really prevent loading until we're done.
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
@@ -1801,8 +1895,35 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
        return 0;
 }
 
+void MWindow::render_proxy(ArrayList<Indexable *> &new_idxbls)
+{
+       Asset *format_asset = new Asset;
+       format_asset->format = FILE_FFMPEG;
+       format_asset->load_defaults(defaults, "PROXY_", 1, 1, 0, 0, 0);
+       ProxyRender proxy_render(this, format_asset);
+       int new_scale = edl->session->proxy_scale;
+       int use_scaler = edl->session->proxy_use_scaler;
 
+       for( int i=0; i<new_idxbls.size(); ++i ) {
+               Indexable *orig = new_idxbls.get(i);
+               Asset *proxy = proxy_render.add_original(orig, new_scale);
+               if( !proxy ) continue;
+               FileSystem fs;
+               int exists = fs.get_size(proxy->path) > 0 ? 1 : 0;
+               int got_it = exists && // if proxy exists, and is newer than orig
+                   fs.get_date(proxy->path) > fs.get_date(orig->path) ? 1 : 0;
+               if( got_it ) continue;
+               proxy_render.add_needed(orig, proxy);
+       }
 
+// render needed proxies
+       int result = proxy_render.create_needed_proxies(new_scale);
+       if( !result ) {
+               add_proxy(use_scaler,
+                       &proxy_render.orig_idxbls, &proxy_render.orig_proxies);
+       }
+       format_asset->remove_user();
+}
 
 void MWindow::test_plugins(EDL *new_edl, char *path)
 {
@@ -1915,7 +2036,6 @@ void MWindow::create_objects(int want_gui,
        int want_new,
        char *config_path)
 {
-       FileSystem fs;
        const int debug = 0;
        if(debug) PRINT_TRACE
 
@@ -1939,6 +2059,7 @@ void MWindow::create_objects(int want_gui,
        if(debug) PRINT_TRACE
        init_ladspa_plugins(this, preferences);
        if(debug) PRINT_TRACE
+       init_plugin_tips(*plugindb, cin_lang);
        if(splash_window)
                splash_window->operation->update(_("Initializing GUI"));
        if(debug) PRINT_TRACE
@@ -1967,6 +2088,9 @@ void MWindow::create_objects(int want_gui,
 
        Timer timer;
 
+       init_awindow();
+       if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_compositor();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
@@ -1978,24 +2102,21 @@ void MWindow::create_objects(int want_gui,
        init_gui();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
-       init_awindow();
-       if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
-
        init_levelwindow();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
-       if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
-
        init_indexes();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
        init_channeldb();
-
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_gwindow();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_render();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_brender();
        init_exportedl();
        init_commercials();
@@ -2495,12 +2616,11 @@ SET_TRACE
 SET_TRACE
 
 //printf("MWindow::show_plugin 1\n");
-       if(!done)
-       {
-               if(!plugin->track)
-               {
-                       printf("MWindow::show_plugin track not defined.\n");
-               }
+       if( !done && !plugin->track ) {
+               printf("MWindow::show_plugin track not defined.\n");
+               done = 1;
+       }
+       if( !done ) {
                PluginServer *server = scan_plugindb(plugin->title,
                        plugin->track->data_type);
 
@@ -2879,7 +2999,7 @@ void MWindow::update_project(int load_mode)
        const int debug = 0;
 
        if(debug) PRINT_TRACE
-       restart_brender();
+       init_brender();
        edl->tracks->update_y_pixels(theme);
 
        if(debug) PRINT_TRACE
@@ -2971,9 +3091,13 @@ void MWindow::rebuild_indices()
                index_state->index_status = INDEX_NOTTESTED;
                if( indexable->is_asset ) {
                        Asset *asset = (Asset *)indexable;
-                       if( asset->format != FILE_PCM )
+                       if( asset->format != FILE_PCM ) {
+                               asset->format = FILE_UNKNOWN;
                                asset->reset_audio();
+                       }
                        asset->reset_video();
+//                     File file; // re-probe the asset
+//                     file.open_file(preferences, asset, 1, 0);
                }
                mainindexes->add_next_asset(0, indexable);
        }
@@ -3118,8 +3242,8 @@ void MWindow::remove_asset_from_caches(Asset *asset)
 void MWindow::remove_assets_from_project(int push_undo, int redraw,
                ArrayList<Indexable*> *drag_assets, ArrayList<EDL*> *drag_clips)
 {
-       for(int i = 0; i < session->drag_assets->total; i++) {
-               Indexable *indexable = session->drag_assets->get(i);
+       for(int i = 0; i < drag_assets->total; i++) {
+               Indexable *indexable = drag_assets->get(i);
                if(indexable->is_asset) remove_asset_from_caches((Asset*)indexable);
        }
 
@@ -3136,11 +3260,11 @@ void MWindow::remove_assets_from_project(int push_undo, int redraw,
                }
        }
 
-       for(int i = 0; i < session->drag_assets->size(); i++) {
+       for(int i = 0; i < drag_assets->size(); i++) {
                for(int j = 0; j < vwindows.size(); j++) {
                        VWindow *vwindow = vwindows[j];
                        if( !vwindow->is_running() ) continue;
-                       if(session->drag_assets->get(i) == vwindow->get_source()) {
+                       if(drag_assets->get(i) == vwindow->get_source()) {
                                vwindow->gui->lock_window("MWindow::remove_assets_from_project 2");
                                vwindow->delete_source(1, 1);
                                vwindow->gui->unlock_window();
@@ -3148,29 +3272,22 @@ void MWindow::remove_assets_from_project(int push_undo, int redraw,
                }
        }
 
-       for(int i = 0; i < session->drag_assets->size(); i++) {
-               Indexable *indexable = session->drag_assets->get(i);
+       for(int i = 0; i < drag_assets->size(); i++) {
+               Indexable *indexable = drag_assets->get(i);
                remove_indexfile(indexable);
        }
 
 //printf("MWindow::rebuild_indices 1 %s\n", indexable->path);
        if(push_undo) undo->update_undo_before();
        if(drag_assets) edl->remove_from_project(drag_assets);
-       if(drag_clips) edl->remove_from_project(session->drag_clips);
+       if(drag_clips) edl->remove_from_project(drag_clips);
        if(redraw) save_backup();
        if(push_undo) undo->update_undo_after(_("remove assets"), LOAD_ALL);
-       if(redraw)
-       {
+       if(redraw) {
                restart_brender();
 
                gui->lock_window("MWindow::remove_assets_from_project 3");
-               gui->update(1,
-                       1,
-                       1,
-                       1,
-                       0,
-                       1,
-                       0);
+               gui->update(1, 1, 1, 1, 0, 1, 0);
                gui->unlock_window();
 
        // Removes from playback here
@@ -3244,7 +3361,8 @@ void MWindow::dump_exe(FILE *fp)
        char mtime[256];
        strftime(mtime, sizeof(mtime), "%F %T", tm);
        fprintf(fp,"mtime: %s\n", mtime);
-
+#if 0
+// people hit ctl-c waiting for this
        int fd = open(proc_path,O_RDONLY+O_NONBLOCK);
        if( fd < 0 ) { fprintf(fp,"open: %m\n"); return; }
        uint8_t *bfr = 0;
@@ -3269,6 +3387,7 @@ void MWindow::dump_exe(FILE *fp)
        for( int i=0; i<20; ++i ) fprintf(fp, "%02x", digest[i]);
        if( ret < 0 ) fprintf(fp, " (ret %d)", ret);
        if( pos < st.st_size ) fprintf(fp, " (pos %jd)", pos);
+#endif
        fprintf(fp, "\n");
 }
 
@@ -3547,7 +3666,8 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra
        int result = file->open_file(preferences, asset, 1, 0);
        if( !result && delete_tracks > 0 )
                undo->update_undo_before();
-       if( !result && asset->video_data && asset->get_video_layers() > 0 ) {
+       int video_layers = asset->get_video_layers();
+       if( !result && asset->video_data && vstream < video_layers ) {
                // try to get asset up to date, may fail
                file->select_video_stream(asset, vstream);
                // either way use what was/is there.
@@ -3597,12 +3717,13 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra
                        else if( delete_tracks )
                                edl->tracks->delete_track(track);
                }
+               edl->retrack();
                edl->resample(old_framerate, session->frame_rate, TRACK_VIDEO);
        }
        if( !result && asset->audio_data && asset->channels > 0 ) {
                session->sample_rate = asset->get_sample_rate();
                int64_t channel_mask = 0;
-               int astrm = !asset->video_data ? -1 :
+               int astrm = !asset->video_data || vstream >= video_layers ? -1 :
                        file->get_audio_for_video(vstream, astream, channel_mask);
                if( astrm >= 0 ) file->select_audio_stream(asset, astrm);
                if( astrm < 0 || !channel_mask ) channel_mask = (1<<asset->channels)-1;