X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fmwindow.C;h=448f37b659fefc58afcc22f0493b2ea1e4217e72;hb=3f6a262cfe390b3f8b275297d64565a5b6272969;hp=107ef1669a8036f0e7b8fedd57d90ceecc0f58b4;hpb=26fe9e12d6d42ae8f7087ac7f08242769d77a84a;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 107ef166..448f37b6 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -18,6 +18,7 @@ * */ +#include "aboutprefs.h" #include "asset.h" #include "assets.h" #include "atrack.h" @@ -89,6 +90,7 @@ #include "pluginserver.h" #include "pluginset.h" #include "preferences.h" +#include "proxy.h" #include "record.h" #include "recordmonitor.h" #include "recordlabel.h" @@ -103,6 +105,7 @@ #include "theme.h" #include "threadloader.h" #include "timebar.h" +#include "timelinepane.h" #include "tipwindow.h" #include "trackcanvas.h" #include "track.h" @@ -122,6 +125,8 @@ #include "wavecache.h" #include "wwindow.h" #include "zoombar.h" +#include "zwindow.h" +#include "zwindowgui.h" #include "exportedl.h" #include "defaultformats.h" @@ -180,6 +185,7 @@ MWindow::MWindow() plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock"); dead_plugin_lock = new Mutex("MWindow::dead_plugin_lock"); vwindows_lock = new Mutex("MWindow::vwindows_lock"); + zwindows_lock = new Mutex("MWindow::zwindows_lock"); brender_lock = new Mutex("MWindow::brender_lock"); keyframe_gui_lock = new Mutex("MWindow::keyframe_gui_lock"); @@ -272,6 +278,7 @@ MWindow::~MWindow() if( twindow && twindow->is_running() ) twindow->close_window(); if( wwindow && wwindow->is_running() ) wwindow->close_window(); vwindows.remove_all_objects(); + zwindows.remove_all_objects(); gui->close(0); if( awindow ) awindow->join(); if( cwindow ) cwindow->join(); @@ -292,11 +299,15 @@ MWindow::~MWindow() close_gui(twindow); close_gui(wwindow); vwindows.remove_all_objects(); + zwindows.remove_all_objects(); gui->close(0); join(); #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(); @@ -325,7 +336,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; @@ -334,6 +344,7 @@ MWindow::~MWindow() delete dead_plugin_lock; delete plugin_gui_lock; delete vwindows_lock; + delete zwindows_lock; delete brender_lock; delete keyframe_gui_lock; colormodels.remove_all_objects(); @@ -733,14 +744,14 @@ void MWindow::add_plugins(ArrayList &plugins) plugins.remove_all(); } -void MWindow::init_plugin_tips(ArrayList &plugins) +void MWindow::init_plugin_tips(ArrayList &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, BC_Resources::language); + cfg_path, lang); fp = fopen(msg_path, "r"); } if( !fp ) { @@ -893,6 +904,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() @@ -1022,12 +1034,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); } } @@ -1057,8 +1070,8 @@ void MWindow::init_theme() theme->build_menus(); init_menus(); + theme->sort_image_sets(); theme->check_used(); - //printf("MWindow::init_theme %d total_time=%d\n", __LINE__, (int)timer.get_difference()); } @@ -1112,6 +1125,154 @@ VWindow *MWindow::get_viewer(int start_it, int idx) return vwindow; } +ZWindow *MWindow::get_mixer(Mixer *&mixer) +{ + zwindows_lock->lock("MWindow::get_mixer"); + if( !mixer ) mixer = edl->mixers.new_mixer(); + ZWindow *zwindow = 0; + for( int i=0; !zwindow && iis_running() ) zwindow = zwindows[i]; + if( !zwindow ) + zwindows.append(zwindow = new ZWindow(this)); + zwindow->idx = mixer->idx; + zwindows_lock->unlock(); + return zwindow; +} + +void MWindow::del_mixer(ZWindow *zwindow) +{ + zwindows_lock->lock("MWindow::del_mixer 0"); + edl->mixers.del_mixer(zwindow->idx); + zwindow->idx = -1; + if( session->selected_zwindow >= 0 ) { + int i = zwindows.number_of(zwindow); + if( i >= 0 && i < session->selected_zwindow ) + --session->selected_zwindow; + else if( i == session->selected_zwindow ) + session->selected_zwindow = -1; + } + zwindows_lock->unlock(); + gui->lock_window("MWindow::del_mixer 1"); + gui->update_mixers(0, -1); + gui->unlock_window(); +} + +void MWindow::start_mixer() +{ + Mixer *mixer = 0; + ZWindow *zwindow = get_mixer(mixer); + const char *title = 0; + + for( Track *track=edl->tracks->first; track!=0; track=track->next ) { + PatchGUI *patchgui = get_patchgui(track); + if( !patchgui || !patchgui->mixer ) continue; + mixer->mixer_ids.append(track->get_mixer_id()); + if( !title ) title = track->title; + } + + session->selected_zwindow = -1; + gui->lock_window("MWindow::start_mixer"); + gui->update_mixers(0, 0); + gui->unlock_window(); + + zwindow->set_title(title); + zwindow->start(); + queue_mixers(edl,CURRENT_FRAME,0,0,1,0); +} + +int MWindow::mixer_track_active(Track *track) +{ + int i = session->selected_zwindow; + if( i < 0 || i >= zwindows.size() ) return 0; + ZWindow *zwindow = zwindows[i]; + Mixer *mixer = edl->mixers.get_mixer(zwindow->idx); + if( !mixer ) return 0; + int n = mixer->mixer_ids.number_of(track->get_mixer_id()); + return n >= 0 ? 1 : 0; +} + +void MWindow::update_mixer_tracks() +{ + zwindows_lock->lock("MixPatch::handle_event"); + int i = session->selected_zwindow; + if( i >= 0 && i < zwindows.size() ) { + ZWindow *zwindow = zwindows[i]; + zwindow->update_mixer_ids(); + } + zwindows_lock->unlock(); +} + +void MWindow::queue_mixers(EDL *edl, int command, int wait_tracking, + int use_inout, int update_refresh, int toggle_audio) +{ + zwindows_lock->lock("MWindow::queue_mixers"); + for( int vidx=0; vidxrunning() ) continue; + Mixer *mixer = edl->mixers.get_mixer(zwindow->idx); + if( !mixer || !mixer->mixer_ids.size() ) continue; + int k = -1; + for( Track *track = edl->tracks->first; k<0 && track!=0; track=track->next ) { + if( track->data_type != TRACK_VIDEO ) continue; + int mixer_id = track->get_mixer_id(); + k = mixer->mixer_ids.size(); + while( --k >= 0 && mixer_id != mixer->mixer_ids[k] ); + } + if( k < 0 ) continue; + EDL *mixer_edl = new EDL(this->edl); + mixer_edl->create_objects(); + mixer_edl->copy_all(edl); + mixer_edl->remove_vwindow_edls(); + for( Track *track = mixer_edl->tracks->first; track!=0; track=track->next ) { + k = mixer->mixer_ids.size(); + while( --k >= 0 && track->get_mixer_id() != mixer->mixer_ids[k] ); + if( k >= 0 ) { + track->record = 1; + track->play = track->data_type == TRACK_VIDEO ? 1 : 0; + } + else + track->record = track->play = 0; + } + zwindow->change_source(mixer_edl); + zwindow->issue_command(command, + wait_tracking, use_inout, update_refresh, toggle_audio); + } + zwindows_lock->unlock(); +} + +void MWindow::stop_mixers() +{ + for( int vidx=0; vidxrunning() ) continue; + zwindow->issue_command(STOP, 0, 0, 0, 0); + } +} + +int MWindow::select_zwindow(ZWindow *zwindow) +{ + int ret = 0, n = zwindows.number_of(zwindow); + if( session->selected_zwindow != n ) { + session->selected_zwindow = n; + for( int i=0; irunning() ) continue; + ZWindowGUI *zgui = zwindow->zgui; + zgui->lock_window("MWindow::select_zwindow 0"); + zwindow->highlighted = i == n ? 1 : 0; + if( zgui->draw_overlays() ) + zgui->canvas->get_canvas()->flash(1); + zgui->unlock_window(); + } + ret = 1; + gui->lock_window("MWindow::select_window 1"); + gui->update_mixers(0, -1); + gui->unlock_window(); + } + return ret; +} + + void MWindow::init_cache() { audio_cache = new CICache(preferences); @@ -1404,13 +1565,19 @@ void MWindow::stop_playback(int wait) { int locked = gui->get_window_lock(); if( locked ) gui->unlock_window(); + gui->stop_drawing(); - cwindow->playback_engine->stop_playback(); + cwindow->stop_playback(); for(int i = 0; i < vwindows.size(); i++) { VWindow *vwindow = vwindows[i]; if( !vwindow->is_running() ) continue; - vwindow->playback_engine->stop_playback(); + vwindow->stop_playback(); + } + for(int i = 0; i < zwindows.size(); i++) { + ZWindow *zwindow = zwindows[i]; + if( !zwindow->is_running() ) continue; + zwindow->stop_playback(); } if( locked ) gui->lock_window("MWindow::stop_playback"); } @@ -1491,14 +1658,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; @@ -1529,6 +1692,7 @@ 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 @@ -1800,10 +1964,6 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); show_plugin(plugin); } } - else - { - plugin->show = 0; - } plugin = (Plugin*)plugin->next; } @@ -1817,8 +1977,11 @@ 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->preview_end = edl->tracks->total_length(); edl->local_session->loop_playback = 0; edl->local_session->set_selectionstart(0); edl->local_session->set_selectionend(0); @@ -1827,6 +1990,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 orig_idxbls; + for( int i=0; itracks->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__); @@ -1871,8 +2057,35 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); return 0; } +void MWindow::render_proxy(ArrayList &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; ipath) > 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) { @@ -1985,7 +2198,6 @@ void MWindow::create_objects(int want_gui, int want_new, char *config_path) { - FileSystem fs; const int debug = 0; if(debug) PRINT_TRACE @@ -2009,7 +2221,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); + init_plugin_tips(*plugindb, cin_lang); if(splash_window) splash_window->operation->update(_("Initializing GUI")); if(debug) PRINT_TRACE @@ -2453,6 +2665,7 @@ void MWindow::sync_parameters(int change_type) } else { + queue_mixers(edl,CURRENT_FRAME,0,0,1,0); cwindow->playback_engine->que->send_command(CURRENT_FRAME, change_type, edl, @@ -2566,12 +2779,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); @@ -2950,7 +3162,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 @@ -2972,8 +3184,8 @@ void MWindow::update_project(int load_mode) if(debug) PRINT_TRACE // Close all the vwindows - if(load_mode == LOADMODE_REPLACE || - load_mode == LOADMODE_REPLACE_CONCATENATE) { + if( load_mode == LOADMODE_REPLACE || + load_mode == LOADMODE_REPLACE_CONCATENATE ) { if(debug) PRINT_TRACE int first_vwindow = 0; if(session->show_vwindow) first_vwindow = 1; @@ -2991,13 +3203,28 @@ void MWindow::update_project(int load_mode) vwindow->close_window(); } if(debug) PRINT_TRACE + select_zwindow(0); + for( int i=0; iis_running() ) continue; + zwindow->close_window(); + } + + for( int i=0; imixers.size(); ++i ) { + Mixer *mixer = edl->mixers[i]; + ZWindow *zwindow = get_mixer(mixer); + zwindow->set_title(mixer->title); + zwindow->start(); + } } - else if(vwindows.size()) { - VWindow *vwindow = vwindows[DEFAULT_VWINDOW]; - if( vwindow->is_running() ) { - vwindow->gui->lock_window("MWindow::update_project"); - vwindow->update(1); - vwindow->gui->unlock_window(); + else { + if(vwindows.size()) { + VWindow *vwindow = vwindows[DEFAULT_VWINDOW]; + if( vwindow->is_running() ) { + vwindow->gui->lock_window("MWindow::update_project"); + vwindow->update(1); + vwindow->gui->unlock_window(); + } } } @@ -3016,6 +3243,7 @@ void MWindow::update_project(int load_mode) if(debug) PRINT_TRACE gui->lock_window("MWindow::update_project"); + gui->update_mixers(0, 0); gui->flush(); if(debug) PRINT_TRACE } @@ -3148,33 +3376,47 @@ int MWindow::create_aspect_ratio(float &w, float &h, int width, int height) void MWindow::reset_caches() { + stop_playback(1); + int locked = gui->get_window_lock(); + if( locked ) gui->unlock_window(); + gui->resource_thread->stop_draw(1); + gui->resource_thread->source_lock->lock("MWindow::reset_caches"); frame_cache->remove_all(); wave_cache->remove_all(); audio_cache->remove_all(); video_cache->remove_all(); - if( cwindow->playback_engine && cwindow->playback_engine->audio_cache ) - cwindow->playback_engine->audio_cache->remove_all(); - if( cwindow->playback_engine && cwindow->playback_engine->video_cache ) - cwindow->playback_engine->video_cache->remove_all(); - + gui->resource_thread->source_lock->unlock(); + if( locked ) gui->lock_window("MWindow::reset_caches"); + if( cwindow->playback_engine ) { + if( cwindow->playback_engine->audio_cache ) + cwindow->playback_engine->audio_cache->remove_all(); + if( cwindow->playback_engine->video_cache ) + cwindow->playback_engine->video_cache->remove_all(); + } for(int i = 0; i < vwindows.size(); i++) { VWindow *vwindow = vwindows[i]; if( !vwindow->is_running() ) continue; - if(vwindow->playback_engine && vwindow->playback_engine->audio_cache) + if( !vwindow->playback_engine ) continue; + if( vwindow->playback_engine->audio_cache ) vwindow->playback_engine->audio_cache->remove_all(); - if(vwindow->playback_engine && vwindow->playback_engine->video_cache) + if( vwindow->playback_engine->video_cache ) vwindow->playback_engine->video_cache->remove_all(); } } void MWindow::remove_asset_from_caches(Asset *asset) { - gui->resource_thread->get_video_source(0); - gui->resource_thread->get_audio_source(0); + stop_playback(1); + int locked = gui->get_window_lock(); + if( locked ) gui->unlock_window(); + gui->resource_thread->stop_draw(1); + gui->resource_thread->source_lock->lock("MWindow::remove_asset_from_caches"); frame_cache->remove_asset(asset); wave_cache->remove_asset(asset); audio_cache->delete_entry(asset); video_cache->delete_entry(asset); + gui->resource_thread->source_lock->unlock(); + if( locked ) gui->lock_window("MWindow::remove_asset_from_caches"); if( cwindow->playback_engine && cwindow->playback_engine->audio_cache ) cwindow->playback_engine->audio_cache->delete_entry(asset); if( cwindow->playback_engine && cwindow->playback_engine->video_cache ) @@ -3182,9 +3424,10 @@ void MWindow::remove_asset_from_caches(Asset *asset) for(int i = 0; i < vwindows.size(); i++) { VWindow *vwindow = vwindows[i]; if( !vwindow->is_running() ) continue; - if(vwindow->playback_engine && vwindow->playback_engine->audio_cache) + if( !vwindow->playback_engine ) continue; + if( vwindow->playback_engine->audio_cache ) vwindow->playback_engine->audio_cache->delete_entry(asset); - if(vwindow->playback_engine && vwindow->playback_engine->video_cache) + if( vwindow->playback_engine->video_cache ) vwindow->playback_engine->video_cache->delete_entry(asset); } } @@ -3312,7 +3555,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; @@ -3337,6 +3581,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"); } @@ -3349,7 +3594,7 @@ void MWindow::trap_hook(FILE *fp, void *vp) mwindow->dump_edl(fp); fprintf(fp, "\nUNDO:\n"); mwindow->dump_undo(fp); - fprintf(fp, "\nEXE:\n"); + fprintf(fp, "\nEXE: %s\n", AboutPrefs::build_timestamp); mwindow->dump_exe(fp); } @@ -3615,7 +3860,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. @@ -3671,7 +3917,7 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra 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<channels)-1; @@ -3785,4 +4031,19 @@ PanAuto* MWindow::get_pan_auto(PatchGUI *patch) return (PanAuto*)ptr->get_prev_auto( (long)unit_position, PLAY_FORWARD, current); } +PatchGUI *MWindow::get_patchgui(Track *track) +{ + PatchGUI *patchgui = 0; + TimelinePane **panes = gui->pane; + for( int i=0; ipatchbay; + if( !patchbay ) continue; + for( int j=0; jpatches.total && !patchgui; ++j ) { + if( patchbay->patches.values[j]->track == track ) + patchgui = patchbay->patches.values[j]; + } + } + return patchgui; +}