delete convert_render; convert_render = 0;
delete render; render = 0;
delete mixers_align; mixers_align = 0;
+#ifdef HAVE_COMMERCIALS
commit_commercial();
if( commercials && !commercials->remove_user() ) commercials = 0;
+#endif
close_mixers();
if( speed_edl ) { speed_edl->remove_user(); speed_edl = 0; }
// Save defaults for open plugins
plugin_gui_lock->unlock();
hide_keyframe_guis();
clean_indexes();
+ clean_backups();
save_defaults();
// Give up and go to a movie
// cant run valgrind if this is used
gui->del_keyboard_listener(
(int (BC_WindowBase::*)(BC_WindowBase *))
&MWindowGUI::keyboard_listener);
- reset_caches();
+ reset_caches(0);
#if 0
// release the hounds
if( awindow && awindow->gui ) awindow->gui->close(0);
delete gui; gui = 0;
delete mainindexes; mainindexes = 0;
delete mainprogress; mainprogress = 0;
- delete audio_cache; audio_cache = 0; // delete the cache after the assets
- delete video_cache; video_cache = 0; // delete the cache after the assets
+ // delete the caches after the assets
+ if( audio_cache ) { audio_cache->remove_user(); audio_cache = 0; }
+ if( video_cache ) { video_cache->remove_user(); video_cache = 0; }
delete frame_cache; frame_cache = 0;
delete wave_cache; wave_cache = 0;
delete plugin_guis; plugin_guis = 0;
void MWindow::check_language()
{
+ char pref_locale[BCSTRLEN];
+ strcpy(pref_locale, DEFAULT_LOCALE);
+ defaults->get("LOCALE",pref_locale);
+// set LANGUAGE if pref locale != sys
+ if( strcmp(pref_locale, DEFAULT_LOCALE) )
+ setenv("LANGUAGE", pref_locale, 1);
+
char curr_lang[BCTEXTLEN]; curr_lang[0] = 0;
const char *env_lang = getenv("LANGUAGE");
if( !env_lang ) env_lang = getenv("LC_ALL");
delete [] base_path;
}
-int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_dir)
+/**
+* @brief Load plugins according to an index file.
+*
+* @details Builds an ArrayList of plugin servers only if there is no
+* mismatch for file layout version, index identifier, or timestamp of
+* the built-in plugins. If OK, add the plugin servers to the global list.
+*
+* @note If an error is returned the index file needs to be rebuilt, and
+* then this function must be called again.
+* There are two types of index files, with the same layout internally.
+* One called "Cinelerra_plugins" for built-ins, ffmpeg and lv2 .
+* The other type "ladspa_plugins.index_id" where index_id is either the
+* path or the $CIN_BUILD identifier if the path is from the running
+* AppImage itself. If there are multiple ladspa directories in the
+* path, there will be multiple index files.
+*
+* @return -1 if file no open, 0 if OK, 1 if error.
+*/
+int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_dir, const char *index_id)
{
if( !fp ) return -1;
+ struct stat st;
+ fstat (fileno(fp), &st); // don't bother if the file has just been created.
+ if( st.st_size < 4 ) return 1;
+
// load index
fseek(fp, 0, SEEK_SET);
int ret = 0;
char index_line[BCTEXTLEN];
- int index_version = -1, len = strlen(plugin_dir);
+ int index_version = -1, len = strlen(index_id);
if( !fgets(index_line, BCTEXTLEN, fp) ||
sscanf(index_line, "%d", &index_version) != 1 ||
index_version != PLUGIN_FILE_VERSION ||
!fgets(index_line, BCTEXTLEN, fp) ||
(int)strlen(index_line)-1 != len || index_line[len] != '\n' ||
- strncmp(index_line, plugin_dir, len) != 0 ) ret = 1;
-
+ strncmp(index_line, index_id, len) != 0 ) {
+// printf("index file mismatch, version %d, index id length %d, expected id %s, file id %s\n", index_version, len, index_id, index_line);
+ ret = 1;
+ }
+
ArrayList<PluginServer*> plugins;
while( !ret && !feof(fp) && fgets(index_line, BCTEXTLEN, fp) ) {
if( index_line[0] == ';' ) continue;
char path[BCTEXTLEN], title[BCTEXTLEN];
int64_t mtime = 0;
if( PluginServer::scan_table(index_line, type, path, title, mtime) ) {
+// printf("PluginServer::scan_table failed for %s\n", index_line);
ret = 1; continue;
}
PluginServer *server = 0;
char plugin_path[BCTEXTLEN]; struct stat st;
sprintf(plugin_path, "%s/%s", plugin_dir, path);
if( stat(plugin_path, &st) || st.st_mtime != mtime ) {
+// printf("Plugin %s index time %ld, file time %ld\n", plugin_path, mtime, st.st_mtime);
ret = 1; continue;
}
server = new PluginServer(mwindow, plugin_path, type);
// Create plugin server from index entry
server->set_title(title);
if( server->read_table(index_line) ) {
+// printf("server->read_table failed for title %s, %s\n", title, index_line);
ret = 1; continue;
}
}
return 0;
}
-
+/**
+* @brief Load built-in and LV2 plugins as specified in index file,
+* rebuild the index file if needed.
+* @param[in] mwindow: GUI class pointer, will be NULL for batch
+* rendering or renderfarm client.
+* @param[in] preferences: Information from cinelerra_rc file.
+*/
int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences)
{
if( !plugindb )
plugindb = new ArrayList<PluginServer*>;
init_ffmpeg();
- char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN];
+ char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN], index_id[BCTEXTLEN];
create_defaults_path(index_path, PLUGIN_FILE);
char *plugin_dir = FileSystem::basepath(preferences->plugin_dir);
strcpy(plugin_path, plugin_dir); delete [] plugin_dir;
+ // index_id is 2nd line of the index file, normally full plugin path,
+ // but fixed value if AppImage because the path changes on each run.
+ // And if the second line does not match on the next run the index is rebuilt.
+ if( getenv("APPDIR") && getenv("CINGG_BUILD")) strcpy(index_id, getenv("CINGG_BUILD"));
+ else strcpy(index_id, plugin_path);
FILE *fp = fopen(index_path,"a+");
if( !fp ) {
fprintf(stderr,_("MWindow::init_plugins: "
int fd = fileno(fp), ret = -1;
if( !flock(fd, LOCK_EX) ) {
fseek(fp, 0, SEEK_SET);
- ret = load_plugin_index(mwindow, fp, plugin_path);
+ ret = load_plugin_index(mwindow, fp, plugin_path, index_id);
}
if( ret > 0 ) {
ftruncate(fd, 0);
fseek(fp, 0, SEEK_SET);
- printf("init plugin index: %s\n", plugin_path);
+ printf("build plugin index for: %s\n", plugin_path);
fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
- fprintf(fp, "%s\n", plugin_path);
+ fprintf(fp, "%s\n", index_id);
init_plugin_index(mwindow, preferences, fp, plugin_path);
init_ffmpeg_index(mwindow, preferences, fp);
init_lv2_index(mwindow, preferences, fp);
fseek(fp, 0, SEEK_SET);
- ret = load_plugin_index(mwindow, fp, plugin_path);
+ ret = load_plugin_index(mwindow, fp, plugin_path, index_id);
}
if( ret ) {
fprintf(stderr,_("MWindow::init_plugins: "
return ret;
}
+/**
+* @brief Load ladspa plugins as specified in index files, for each ladspa
+* directory keep a separate index file. Rebuild index file(s) if needed.
+* @param[in] mwindow: GUI class pointer, will be NULL for batch
+* rendering or renderfarm client.
+* @param[in] preferences: Information from cinelerra_rc file.
+*/
int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences)
{
#ifdef HAVE_LADSPA
char *path = getenv("LADSPA_PATH");
+ char *appdir = getenv("APPDIR");
char ladspa_path[BCTEXTLEN];
- if( !path ) {
+ if( !path ) { // if no env var, use CinGG's own ladspa dir
strncpy(ladspa_path, File::get_ladspa_path(), sizeof(ladspa_path));
path = ladspa_path;
}
for( int len=0; *path; path+=len ) {
char *cp = strchr(path,':');
len = !cp ? strlen(path) : cp-path;
- char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN];
+ char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN], index_id[BCTEXTLEN];
memcpy(plugin_path, path, len); plugin_path[len] = 0;
if( cp ) ++len;
char *plugin_dir = FileSystem::basepath(plugin_path);
strcpy(plugin_path, plugin_dir); delete [] plugin_dir;
create_defaults_path(index_path, LADSPA_FILE);
cp = index_path + strlen(index_path);
- for( char *bp=plugin_path; *bp!=0; ++bp )
+ // If the first part of the plugin_path matches the APPDIR, we are
+ // referring to CinGG's ladspa, replace the path by a fixed ID. APPDIR
+ // only exists if we are running as AppImage (with variable mount points).
+ if( appdir && strncmp(plugin_path, appdir, strlen(appdir)) == 0 )
+ strcpy(index_id, getenv("CINGG_BUILD"));
+ else strcpy(index_id, plugin_path);
+
+ // Concatenate the path, replacing '/' with '_'.
+ for( char *bp=index_id; *bp!=0; ++bp )
*cp++ = *bp=='/' ? '_' : *bp;
*cp = 0;
FILE *fp = fopen(index_path,"a+");
int fd = fileno(fp), ret = -1;
if( !flock(fd, LOCK_EX) ) {
fseek(fp, 0, SEEK_SET);
- ret = load_plugin_index(mwindow, fp, plugin_path);
+ ret = load_plugin_index(mwindow, fp, plugin_path, index_id);
}
if( ret > 0 ) {
ftruncate(fd, 0);
fseek(fp, 0, SEEK_SET);
- init_ladspa_index(mwindow, preferences, fp, plugin_path);
+ printf("build ladspa plugin index for: %s\n", plugin_path);
+ fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
+ fprintf(fp, "%s\n", index_id);
+ init_plugin_index(mwindow, preferences, fp, plugin_path);
fseek(fp, 0, SEEK_SET);
- ret = load_plugin_index(mwindow, fp, plugin_path);
+ ret = load_plugin_index(mwindow, fp, plugin_path, index_id);
}
if( ret ) {
fprintf(stderr,_("MWindow::init_ladspa_plugins: "
char fs_path[BCTEXTLEN], path[BCTEXTLEN];
get_plugin_path(fs_path, 0, fs.dir_list[i]->path);
get_plugin_path(path, plug_dir, fs_path);
- if( fs.is_dir(fs_path) ) {
+ if( fs.is_dir(fs_path) ) { // recursively scan child directory
scan_plugin_index(mwindow, preferences, fp, plug_dir, path, idx);
continue;
}
YUV::yuv.yuv_set_colors(preferences->yuv_color_space, preferences->yuv_color_range);
}
+void MWindow::clean_backups()
+{
+ FileSystem fs;
+ int total_excess;
+ long oldest = 0;
+ int oldest_item = -1;
+ char string[BCTEXTLEN];
+
+// Delete extra backups
+ fs.set_filter("backup*.prev_*");
+ fs.complete_path(preferences->index_directory);
+ fs.update(preferences->index_directory);
+
+ // set to 50 for now
+ // total_excess = fs.dir_list.total - preferences->index_count;
+ total_excess = fs.dir_list.total - 50;
+ printf("Total excess of backups: %i \n", total_excess);
+
+//printf("MWindow::clean_backups 1 %d\n", fs.dir_list.total);
+
+ while(total_excess > 0)
+ {
+// Get oldest
+ for(int i = 0; i < fs.dir_list.total; i++)
+ {
+ fs.join_names(string, preferences->index_directory, fs.dir_list[i]->name);
+
+ if(i == 0 || fs.get_date(string) <= oldest)
+ {
+ oldest = fs.get_date(string);
+ oldest_item = i;
+ }
+ }
+
+ if(oldest_item >= 0)
+ {
+// Remove backup file
+ fs.join_names(string,
+ preferences->index_directory,
+ fs.dir_list[oldest_item]->name);
+//printf("MWindow::clean_backups 1 %s\n", string);
+ if(remove(string))
+ perror("delete_backups");
+ delete fs.dir_list[oldest_item];
+ fs.dir_list.remove_number(oldest_item);
+
+ }
+
+ total_excess--;
+ }
+}
+
void MWindow::clean_indexes()
{
FileSystem fs;
void MWindow::tile_mixers()
{
+ int x1 = session->tile_mixers_x;
+ int y1 = session->tile_mixers_y;
+ int x2 = x1 + session->tile_mixers_w;
+ int y2 = y1 + session->tile_mixers_h;
+ tile_mixers(x1, y1, x2, y2);
+}
+
+void MWindow::tile_mixers(int x1, int y1, int x2, int y2)
+{
+ if( x1 == x2 || y1 == y2 ) {
+// use top left quadrent
+ int sw = gui->get_screen_w(1, -1);
+ int sh = gui->get_screen_w(1, -1);
+ x1 = 1; y1 = 1;
+ x2 = sw/2; y2 = sh/2;
+ }
+ else {
+ if( x1 > x2 ) { int t = x1; x1 = x2; x2 = t; }
+ if( y1 > y2 ) { int t = y1; y1 = y2; y2 = t; }
+ }
+ int ow = edl->session->output_w, oh = edl->session->output_h;
int nz = 0;
for( int i=0; i<zwindows.size(); ++i ) {
ZWindow *zwindow = zwindows[i];
++nz;
}
if( !nz ) return;
- int zn = ceil(sqrt(nz));
- int x1 = 1 + gui->get_x(), x2 = cwindow->gui->get_x();
- int y1 = 1, y2 = gui->get_y();
- int rw = gui->get_root_w(0), rh = gui->get_root_h(0);
- if( x1 < 0 ) x1 = 0;
- if( y1 < 0 ) y1 = 0;
- if( x2 > rw ) x2 = rw;
- if( y2 > rh ) y2 = rh;
- int dx = x2 - x1, dy = y2 - y1;
- int zw = dx / zn;
int lt = BC_DisplayInfo::get_left_border();
int top = BC_DisplayInfo::get_top_border();
int bw = lt + BC_DisplayInfo::get_right_border(); // borders
int bh = top + BC_DisplayInfo::get_bottom_border();
- int zx = 0, zy = 0; // window origins
int mw = xS(10+10), mh = yS(10+10); // canvas margins
- int rsz = 0, n = 0, dz = 0;
- int ow = edl->session->output_w, oh = edl->session->output_h;
+ int dx = x2 - x1, dy = y2 - y1;
+ int64_t sz = dx * dy, best_r = sz;
+ int bx = 1, by = nz;
+ for( int nx=1; nx<=nz; ++nx ) {
+ int ny = ceil((double)nz / nx);
+ int zw = dx / nx;
+ int ww = zw - bw;
+ int hh = (ww - mw) * oh / ow + mh;
+ int zh = hh + bh;
+ int64_t za = zw*nx * zh*ny;
+ int64_t r = sz - za;
+ if( r < 0 ) continue;
+ if( r >= best_r ) continue;
+ best_r = r;
+ bx = nx; by = ny;
+ }
+ for( int ny=1; ny<=nz; ++ny ) {
+ int nx = ceil((double)nz / ny);
+ int zh = dy / ny;
+ int hh = zh - bh;
+ int ww = (hh - mh) * ow / oh + mw;
+ int zw = ww + bw;
+ int64_t za = zw*nx * zh*ny;
+ int64_t r = sz - za;
+ if( r < 0 ) continue;
+ if( r >= best_r ) continue;
+ best_r = r;
+ bx = nx; by = ny;
+ }
+ int zw, zh, ww, hh;
+ if( bx < by ) {
+ zh = dy / by;
+ hh = zh - bh;
+ ww = (hh - mh) * ow / oh + mw;
+ zw = ww + bw;
+ }
+ else {
+ zw = dx / bx;
+ ww = zw - bw;
+ hh = (ww - mw) * oh / ow + mh;
+ zh = hh + bh;
+ }
+
+ int zx = 0, zy = 0; // window origins
+ int n = 0;
for( int i=0; i<zwindows.size(); ++i ) {
ZWindow *zwindow = zwindows[i];
if( zwindow->idx < 0 ) continue;
- int ww = zw - bw, hh = (ww - mw) * oh / ow + mh, zh = hh + bh;
- if( rsz < hh ) rsz = hh;
int xx = zx + x1, yy = zy + y1;
int mx = x2 - zw, my = y2 - zh;
if( xx > mx ) xx = mx;
if( yy > my ) yy = my;
- xx += lt + xS(dz); yy += top + yS(dz);
zwindow->reposition(xx,yy, ww,hh);
if( zwindow->running() ) {
ZWindowGUI *gui = (ZWindowGUI *)zwindow->get_gui();
gui->BC_WindowBase::reposition_window(xx,yy, ww,hh);
gui->unlock_window();
}
- if( ++n >= zn ) {
- n = 0; rsz += bh;
- if( (zy += rsz) > (dy - rsz) ) dz += 10;
- rsz = 0;
- zx = 0;
+ if( ++n >= bx ) {
+ zx = 0; zy += zh;
+ n = 0;
}
else
zx += zw;
void MWindow::set_gang_tracks(int v)
{
- edl->session->gang_tracks = v;
+ edl->local_session->gang_tracks = v;
+ sync_parameters(CHANGE_PARAMS);
gui->update(1, 1, 0, 0, 1, 0, 0);
gui->flush();
}
// Start examining next batch of index files
if(got_indexes) mainindexes->start_build();
+// reload renderengine edl or the plugin guis will flip out
+ sync_parameters(CHANGE_ALL);
// Open plugin GUIs
show_plugins();
load_mode == LOADMODE_REPLACE_CONCATENATE ) &&
(ftype != FILE_IS_XML || edl_mode != LOADMODE_EDL_CLIP) ) {
select_asset(0, 0);
+ edl->session->proxy_state = PROXY_INACTIVE;
edl->session->proxy_scale = 1;
edl->session->proxy_disabled_scale = 1;
edl->session->proxy_use_scaler = 0;
goto_start();
}
- if( ( edl->session->proxy_auto_scale && edl->session->proxy_scale != 1 ) &&
- ( load_mode != LOADMODE_REPLACE && load_mode != LOADMODE_REPLACE_CONCATENATE ) ) {
+ if( edl->session->proxy_state != PROXY_INACTIVE && edl->session->proxy_auto_scale &&
+ 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));
int MWindow::enable_proxy()
{
int ret = 0;
- if( edl->session->proxy_scale == 1 &&
- edl->session->proxy_disabled_scale != 1 ) {
+ if( edl->session->proxy_state == PROXY_DISABLED ) {
int new_scale = edl->session->proxy_disabled_scale;
int new_use_scaler = edl->session->proxy_use_scaler;
Asset *asset = new Asset;
beep(2000., 1.5, gain);
}
edl->session->proxy_disabled_scale = 1;
+ edl->session->proxy_state = PROXY_ACTIVE;
gui->lock_window("MWindow::to_proxy");
update_project(LOADMODE_REPLACE);
gui->unlock_window();
int MWindow::disable_proxy()
{
- if( edl->session->proxy_scale != 1 &&
- edl->session->proxy_disabled_scale == 1 ) {
- int old_scale = edl->session->proxy_scale, new_scale = 1;
+ if( edl->session->proxy_state == PROXY_ACTIVE ) {
+ int old_scale = edl->session->proxy_scale, new_scale = 0;
int new_use_scaler = edl->session->proxy_use_scaler;
Asset *asset = new Asset;
asset->format = FILE_FFMPEG;
asset->load_defaults(defaults, "PROXY_", 1, 1, 0, 0, 0);
to_proxy(asset, new_scale, new_use_scaler);
asset->remove_user();
+ edl->session->proxy_state = PROXY_DISABLED;
edl->session->proxy_disabled_scale = old_scale;
gui->lock_window("MWindow::to_proxy");
update_project(LOADMODE_REPLACE);
edl->Garbage::add_user();
save_backup();
undo_before(_("proxy"), this);
- int asset_scale = new_scale == 1 ? 0 :
+ int asset_scale = !new_scale ? 0 :
!new_use_scaler ? 1 : new_scale;
ProxyRender proxy_render(this, asset, asset_scale);
// remove all session proxy assets at the at the current proxy_scale
int proxy_scale = edl->session->proxy_scale;
- if( proxy_scale > 1 ) {
+ if( edl->session->proxy_state == PROXY_ACTIVE ) {
Asset *orig_asset = edl->assets->first;
for( ; orig_asset; orig_asset=orig_asset->next ) {
char new_path[BCTEXTLEN];
for( int i=0,n=edl->nested_edls.size(); i<n; ++i ) {
EDL *orig_nested = edl->nested_edls[i];
char new_path[BCTEXTLEN];
- if( !ProxyRender::from_proxy_path(new_path, orig_nested, proxy_scale) )
- continue;
proxy_render.to_proxy_path(new_path, orig_nested, proxy_scale);
// test if proxy asset was already added to proxy_assets
int got_it = 0;
}
// convert from the proxy assets to the original assets
- edl->set_proxy(1, 0, &proxy_assets, &orig_idxbls);
+ edl->set_proxy(0, 0, &proxy_assets, &orig_idxbls);
// remove the references
for( int i=0; i<proxy_assets.size(); ++i ) {
confirm_paths.set_array_delete();
// convert to new size if not original size
- if( new_scale != 1 ) {
+ if( new_scale ) {
FileSystem fs;
Asset *orig = edl->assets->first;
for( ; orig; orig=orig->next ) {
proxy_render.add_needed(orig_nested, proxy);
}
}
+ edl->session->proxy_state = PROXY_ACTIVE;
}
+ else
+ edl->session->proxy_state = PROXY_INACTIVE;
int result = 0;
// test for existing files
confirm_paths.remove_all_objects();
}
- if( !result )
+ if( !result && new_scale )
result = proxy_render.create_needed_proxies(new_scale);
- if( !result ) // resize project
+ if( !result ) { // resize project
edl->set_proxy(new_scale, new_use_scaler,
&proxy_render.orig_idxbls, &proxy_render.orig_proxies);
-
+ }
undo_after(_("proxy"), LOAD_ALL);
edl->Garbage::remove_user();
restart_brender();
init_3d();
if(debug) PRINT_TRACE
- show_splash();
if(debug) PRINT_TRACE
default_standard = default_std();
init_defaults(defaults, config_path);
check_language();
+ show_splash();
init_preferences();
if(splash_window)
splash_window->update_status(_("Initializing Plugins"));
run_lock->unlock();
}
-void MWindow::show_vwindow()
+void MWindow::show_vwindow(int raise)
{
int total_running = 0;
session->show_vwindow = 1;
for(int j = 0; j < vwindows.size(); j++) {
VWindow *vwindow = vwindows[j];
if( !vwindow->is_running() ) continue;
+ total_running++;
+ if( !raise && !vwindow->gui->is_hidden() ) continue;
vwindow->gui->lock_window("MWindow::show_vwindow");
vwindow->gui->show_window(0);
vwindow->gui->raise_window();
vwindow->gui->flush();
vwindow->gui->unlock_window();
- total_running++;
}
-
// If no windows visible
- if(!total_running)
- {
+ if( !total_running )
get_viewer(1, DEFAULT_VWINDOW);
- }
gui->mainmenu->show_vwindow->set_checked(1);
}
+
+void MWindow::hide_vwindow(int raise)
+{
+ session->show_vwindow = 0;
+ int total_running = 0;
+
+ for(int j = 0; j < vwindows.size(); j++) {
+ VWindow *vwindow = vwindows[j];
+ if( !vwindow->is_running() ) continue;
+ total_running++;
+ if( !raise && !vwindow->gui->is_hidden() ) continue;
+ vwindow->gui->lock_window("MWindow::show_vwindow");
+ vwindow->gui->hide_window(0);
+ vwindow->gui->unlock_window();
+ }
+ gui->mainmenu->show_vwindow->set_checked(0);
+}
+
+
void MWindow::show_awindow()
{
session->show_awindow = 1;
gui->mainmenu->show_awindow->set_checked(1);
}
+void MWindow::hide_awindow()
+{
+ session->show_awindow = 0;
+
+ awindow->gui->lock_window("MWindow::show_awindow");
+ awindow->gui->hide_window();
+ awindow->gui->unlock_window();
+ gui->mainmenu->show_awindow->set_checked(0);
+}
+
+
char *MWindow::get_cwindow_display()
{
char *x11_host = screens < 2 || session->window_config == 0 ?
{
session->show_cwindow = 1;
cwindow->show_window();
+ cwindow->gui->tool_panel->raise_tool();
gui->mainmenu->show_cwindow->set_checked(1);
}
+
+void MWindow::hide_cwindow()
+{
+ session->show_cwindow = 0;
+
+ cwindow->gui->lock_window("MWindow::show_cwindow");
+ cwindow->gui->hide_window();
+ cwindow->gui->unlock_window();
+ gui->mainmenu->show_cwindow->set_checked(0);
+}
+
+
void MWindow::show_gwindow()
{
session->show_gwindow = 1;
gui->mainmenu->show_gwindow->set_checked(1);
}
+
void MWindow::hide_gwindow()
{
session->show_gwindow = 0;
gwindow->gui->lock_window("MWindow::show_gwindow");
gwindow->gui->hide_window();
gwindow->gui->unlock_window();
+ gui->mainmenu->show_gwindow->set_checked(0);
}
void MWindow::show_lwindow()
gui->mainmenu->show_lwindow->set_checked(1);
}
+void MWindow::hide_lwindow()
+{
+ session->show_lwindow = 0;
+
+ lwindow->gui->lock_window("MWindow::show_lwindow");
+ lwindow->gui->hide_window();
+ lwindow->gui->unlock_window();
+ gui->mainmenu->show_lwindow->set_checked(0);
+}
+
+
void MWindow::restore_windows()
{
gui->unlock_window();
vwindow->gui->unlock_window();
}
}
- else
- show_vwindow();
+ else
+ show_vwindow(0);
if( !session->show_awindow && !awindow->gui->is_hidden() ) {
awindow->gui->lock_window("MWindow::restore_windows");
cwindow->gui->unlock_window();
}
else if( session->show_cwindow && cwindow->gui->is_hidden() )
- cwindow->show_window();
+ show_cwindow();
if( !session->show_gwindow && !gwindow->gui->is_hidden() ) {
gwindow->gui->lock_window("MWindow::restore_windows");
else if( session->show_lwindow && lwindow->gui->is_hidden() )
show_lwindow();
+ tile_mixers();
gui->lock_window("MWindow::restore_windows");
gui->focus();
}
(Indexable*)edit->asset : (Indexable*)edit->nested_edl;
if( !idxbl ) return 0;
char path[BCTEXTLEN];
- if( !edit->asset || edit->track->data_type != TRACK_VIDEO ||
- edl->session->proxy_scale == 1 ||
- ProxyRender::from_proxy_path(path, idxbl, edl->session->proxy_scale) )
+// map proxy colors to unproxy colors
+ if( edl->session->proxy_state != PROXY_ACTIVE ||
+ !edit->asset || edit->track->data_type != TRACK_VIDEO ||
+ ProxyRender::from_proxy_path(path, (Asset*)idxbl, edl->session->proxy_scale) )
strcpy(path, idxbl->path);
char *cp = strrchr(path, '/');
cp = !cp ? path : cp+1;
if( load_mode == LOADMODE_REPLACE ||
load_mode == LOADMODE_REPLACE_CONCATENATE ) {
- delete gui->keyvalue_popup;
- gui->keyvalue_popup = 0;
+ edl->session->timecode_offset = 0;
+ gui->close_keyvalue_popup();
gui->load_panes();
}
if(debug) PRINT_TRACE
}
-void MWindow::stack_push(EDL *new_edl, Indexable *idxbl, Edit *edit)
+void MWindow::stack_push(EDL *new_edl, Indexable *idxbl)
{
int got_indexes = 0;
for( int i=0; i<new_edl->nested_edls.size(); ++i ) {
undo_before();
StackItem &item = stack.append();
item.edl = edl;
- item.edit = edit;
item.new_edl = new_edl;
item.duration = new_edl->tracks->total_length();
item.undo = undo;
// session edl replaced, overwrite and save clip data
if( item.new_edl != edl )
item.new_edl->overwrite_clip(edl);
- Edit *edit = item.edit;
-// resize the referring edit if the edl duration changed
- if( edit ) {
- double duration = item.new_edl->tracks->total_length();
- double dt = duration - item.duration;
- if( fabs(dt) > 1e-4 ) {
- int64_t du = edit->track->to_units(dt,0);
- if( (edit->length+=du) < 0 )
- edit->length = 0;
+ Indexable *idxbl = item.idxbl;
+ if( idxbl && idxbl->is_asset && item.mtime ) {
+ Asset *asset = (Asset *)idxbl;
+ if( asset->format == FILE_REF ) {
+ char *path = asset->path;
+ struct stat st;
+ if( stat(path, &st) || item.mtime == st.st_mtime ) {
+ int cw = xS(250), ch = yS(150), px, py;
+ gui->get_pop_cursor(px, py);
+ px -= cw/2; py -= ch/2;
+ ConfirmRefWindow confirm(this, path, px, py, cw, ch);
+ confirm.create_objects();
+ int result = confirm.run_window();
+ if( !result ) {
+ FileXML file;
+ item.new_edl->save_xml(&file, path);
+ file.terminate_string();
+ if(file.write_to_file(path))
+ eprintf(_("Cant write FileREF: %s"), path);
+ }
+ }
}
}
edl->remove_user();
edl = item.edl;
delete undo;
undo = item.undo;
- Indexable *idxbl = item.idxbl;
- int64_t mtime = item.mtime;
stack.remove();
if( idxbl ) {
+// resize the indexable edits if the new_edl duration changed
+ double duration = item.new_edl->tracks->total_length();
+ double dt = duration - item.duration;
+ if( fabs(dt) > 1e-4 )
+ edl->tracks->update_idxbl_length(idxbl->id, dt);
gui->unlock_window();
gui->resource_thread->close_indexable(idxbl);
remove_from_caches(idxbl);
- remove_indexfile(idxbl);
+ IndexFile::delete_index_files(preferences, idxbl);
mainindexes->add_indexable(idxbl);
mainindexes->start_build();
awindow->gui->async_update_assets();
undo_after(_("open edl"), LOAD_ALL);
show_plugins();
gui->stack_button->update();
- if( mtime && idxbl && idxbl->is_asset ) {
- struct stat st;
- Asset *asset = (Asset *)idxbl;
- if( asset->format == FILE_REF && !stat(asset->path, &st) &&
- item.mtime == st.st_mtime ) {
- char text[BCTEXTLEN];
- snprintf(text, sizeof(text),
- _("Warning: Asset not updated: %s"), asset->path);
- show_warning(&preferences->warn_stack, text);
- }
- }
}
int MWindow::save(EDL *edl, char *filename, int stat)
for( int i=stack.size(); --i>=0; ) {
StackItem &item = stack[i];
Indexable *idxbl = item.idxbl;
+ if( !idxbl ) continue;
if( idxbl->is_asset ) {
Asset *asset = (Asset *)idxbl;
if( asset->format == FILE_REF ) {
return 1;
}
}
- else if( item.new_edl != item.idxbl )
- item.new_edl->overwrite_clip((EDL*)item.idxbl);
+ else if( item.new_edl != idxbl )
+ item.new_edl->overwrite_clip((EDL*)idxbl);
}
EDL *new_edl = stack.size() ? stack[0].edl : edl;
save(new_edl, path, 1);
char *bp = strrchr(clip->local_session->clip_title, '/');
bp = bp ? bp+1 : clip->local_session->clip_title;
cp += snprintf(cp, ep-cp, "%s", bp);
- EDL *nested = edl->new_nested_edl(clip, path);
+ EDL *nested = edl->new_nested_clip(clip, path);
edl->clips.remove(clip);
clip->remove_user();
mainindexes->add_indexable(nested);
if( prefs != preferences )
preferences->copy_from(prefs);
if( cwindow->playback_engine )
- cwindow->playback_engine->preferences->copy_from(prefs);
+ cwindow->playback_engine->update_preferences(prefs);
for(int i = 0; i < vwindows.size(); i++) {
VWindow *vwindow = vwindows[i];
if( !vwindow->is_running() ) continue;
if( vwindow->playback_engine )
- vwindow->playback_engine->preferences->copy_from(prefs);
+ vwindow->playback_engine->update_preferences(prefs);
}
for(int i = 0; i < zwindows.size(); i++) {
ZWindow *zwindow = zwindows[i];
if( !zwindow->is_running() ) continue;
if( zwindow->zgui->playback_engine )
- zwindow->zgui->playback_engine->preferences->copy_from(prefs);
+ zwindow->zgui->playback_engine->update_preferences(prefs);
}
}
void MWindow::remove_indexfile(Indexable *indexable)
{
if( !indexable->is_asset ) return;
- Asset *asset = (Asset *)indexable;
// Erase file
- IndexFile::delete_index(preferences, asset, ".toc");
- IndexFile::delete_index(preferences, asset, ".idx");
- IndexFile::delete_index(preferences, asset, ".mkr");
+ IndexFile::delete_index_files(preferences, indexable);
}
void MWindow::rebuild_indices()
cp += snprintf(cp, ep-cp, idx ? BACKUPn_FILE : BACKUP_FILE, idx);
}
+void MWindow::create_timestamped_copy_from_previous_backup(char *previouspath)
+{
+ if (previouspath == NULL) return;
+ char backup_path[BCTEXTLEN];
+ backup_path[0] = 0;
+ time_t now = time(NULL);
+ struct tm* currenttime = localtime(&now);
+ snprintf(backup_path, sizeof(backup_path),
+ "%s/%s_%d%.2d%.2d_%.2d%.2d%.2d",
+ File::get_config_path(), BACKUP_FILE1,
+ currenttime->tm_year + 1900,
+ currenttime->tm_mon + 1,
+ currenttime->tm_mday,
+ currenttime->tm_hour,
+ currenttime->tm_min,
+ currenttime->tm_sec);
+ rename(previouspath, backup_path);
+}
+
void MWindow::save_backup()
{
FileXML file;
snprintf(backup_path1, sizeof(backup_path1), "%s/%s",
File::get_config_path(), BACKUP_FILE1);
get_backup_path(backup_path, sizeof(backup_path));
+ if( preferences->ongoing_backups )
+ create_timestamped_copy_from_previous_backup(backup_path1);
rename(backup_path, backup_path1);
edl->save_xml(&file, backup_path);
file.terminate_string();
int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
{
w = 1; h = 1;
+ double ar;
+
if(!width || !height) return 1;
if( width == 720 && (height == 480 || height == 576) ) {
w = 4; h = 3; return 0; // for NTSC and PAL
}
- double ar = (double)width / height;
+
+ ar = (double)width / height;
// square-ish pixels
if( EQUIV(ar, 1.0000) ) return 0;
if( EQUIV(ar, 1.3333) ) { w = 4; h = 3; return 0; }
if( EQUIV(ar, 2.1111) ) { w = 19; h = 9; return 0; }
if( EQUIV(ar, 2.2222) ) { w = 20; h = 9; return 0; }
if( EQUIV(ar, 2.3333) ) { w = 21; h = 9; return 0; }
+ if( EQUIV(ar, 2.37037) ) { w = 64; h = 27; return 0; }
+
int ww = width, hh = height;
// numerator, denominator must be under mx
int mx = 255, n = gcd(ww, hh);
return 0;
}
-void MWindow::reset_caches()
+void MWindow::reset_caches(int locked)
{
- awindow->gui->stop_vicon_drawing();
- frame_cache->remove_all();
- wave_cache->remove_all();
- audio_cache->remove_all();
- video_cache->remove_all();
- 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();
- }
+ if( locked ) gui->unlock_window();
+ awindow->gui->stop_vicon_drawing(1);
+ if( cwindow->playback_engine )
+ cwindow->playback_engine->create_cache();
for(int i = 0; i < vwindows.size(); i++) {
VWindow *vwindow = vwindows[i];
if( !vwindow->is_running() ) continue;
if( !vwindow->playback_engine ) continue;
- if( vwindow->playback_engine->audio_cache )
- vwindow->playback_engine->audio_cache->remove_all();
- if( vwindow->playback_engine->video_cache )
- vwindow->playback_engine->video_cache->remove_all();
+ vwindow->playback_engine->create_cache();
}
+ gui->lock_window("MWindow::reset_caches");
+ frame_cache->remove_all();
+ wave_cache->remove_all();
+ audio_cache->remove_all();
+ video_cache->remove_all();
+ if( !locked ) gui->unlock_window();
}
void MWindow::remove_from_caches(Indexable *idxbl)
{
- awindow->gui->stop_vicon_drawing();
+ awindow->gui->stop_vicon_drawing(1);
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->stop_vicon_drawing();
+ awindow->gui->stop_vicon_drawing(1);
// Remove from VWindow.
if( drag_clips ) {
void MWindow::next_time_format()
{
- switch(edl->session->time_format)
- {
- case TIME_HMS: edl->session->time_format = TIME_HMSF; break;
- case TIME_HMSF: edl->session->time_format = TIME_SAMPLES; break;
- case TIME_SAMPLES: edl->session->time_format = TIME_SAMPLES_HEX; break;
- case TIME_SAMPLES_HEX: edl->session->time_format = TIME_FRAMES; break;
- case TIME_FRAMES: edl->session->time_format = TIME_FEET_FRAMES; break;
- case TIME_FEET_FRAMES: edl->session->time_format = TIME_SECONDS; break;
- case TIME_SECONDS: edl->session->time_format = TIME_HMS; break;
+ switch( edl->session->time_format ) {
+ case TIME_HMS: edl->session->time_format = TIME_HMSF; break;
+ case TIME_HMSF: edl->session->time_format = TIME_TIMECODE; break;
+ case TIME_TIMECODE: edl->session->time_format = TIME_FRAMES; break;
+ case TIME_FRAMES: edl->session->time_format = TIME_SAMPLES; break;
+ case TIME_SAMPLES: edl->session->time_format = TIME_SAMPLES_HEX; break;
+ case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SECONDS; break;
+ case TIME_SECONDS: edl->session->time_format = TIME_FEET_FRAMES; break;
+ case TIME_FEET_FRAMES: edl->session->time_format = TIME_HMS; break;
}
-
time_format_common();
}
void MWindow::prev_time_format()
{
- switch(edl->session->time_format)
- {
- case TIME_HMS: edl->session->time_format = TIME_SECONDS; break;
- case TIME_SECONDS: edl->session->time_format = TIME_FEET_FRAMES; break;
- case TIME_FEET_FRAMES: edl->session->time_format = TIME_FRAMES; break;
- case TIME_FRAMES: edl->session->time_format = TIME_SAMPLES_HEX; break;
- case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SAMPLES; break;
- case TIME_SAMPLES: edl->session->time_format = TIME_HMSF; break;
- case TIME_HMSF: edl->session->time_format = TIME_HMS; break;
+ switch( edl->session->time_format ) {
+ case TIME_HMS: edl->session->time_format = TIME_FEET_FRAMES; break;
+ case TIME_HMSF: edl->session->time_format = TIME_HMS; break;
+ case TIME_TIMECODE: edl->session->time_format = TIME_HMSF; break;
+ case TIME_FRAMES: edl->session->time_format = TIME_TIMECODE; break;
+ case TIME_SAMPLES: edl->session->time_format = TIME_FRAMES; break;
+ case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SAMPLES; break;
+ case TIME_SECONDS: edl->session->time_format = TIME_SAMPLES_HEX; break;
+ case TIME_FEET_FRAMES: edl->session->time_format = TIME_SECONDS; break;
}
time_format_common();
session->output_w = width;
session->output_h = height;
session->frame_rate = framerate;
+ session->interlace_mode = asset->interlace_mode;
// not, asset->actual_width/actual_height
asset->width = session->output_w;
asset->height = session->output_h;
asset->frame_rate = session->frame_rate;
+
create_aspect_ratio(session->aspect_w, session->aspect_h,
session->output_w, session->output_h);
+ float ar = asset->aspect_ratio;
+ if (ar) {
+ //printf ("Aspect ratio from asset: %f \n", ar);
+ if( EQUIV(ar, 1.3333) ) { session->aspect_w = 4; session->aspect_h = 3; }
+ if( EQUIV(ar, 1.7777) ) { session->aspect_w = 16; session->aspect_h = 9; }
+ if( EQUIV(ar, 2.1111) ) { session->aspect_w = 19; session->aspect_h = 9; }
+ if( EQUIV(ar, 2.2222) ) { session->aspect_w = 20; session->aspect_h = 9; }
+ if( EQUIV(ar, 2.3333) ) { session->aspect_w = 21; session->aspect_h = 9; }
+ if( EQUIV(ar, 2.370370) ) { session->aspect_w = 64; session->aspect_h = 27; }
+ }
+
+
Track *track = edl->tracks->first;
for( Track *next_track=0; track; track=next_track ) {
next_track = track->next;
mwindow->gui->unlock_window();
}
+
+ConfirmRefWindow::ConfirmRefWindow(MWindow *mwindow, char *path,
+ int px, int py, int cw, int ch)
+ : BC_Window(_(PROGRAM_NAME ": Confirm update"), px, py, cw, ch, cw, ch)
+{
+ this->mwindow = mwindow;
+ this->path = path;
+// *** CONTEXT_HELP ***
+ context_help_set_keyword("File by Reference");
+}
+
+ConfirmRefWindow::~ConfirmRefWindow()
+{
+}
+
+void ConfirmRefWindow::create_objects()
+{
+ lock_window("ConfirmRefWindow::create_objects()");
+ int x = xS(10), y = yS(10), pad = yS(5);
+ BC_Title *title;
+ add_subwindow(title = new BC_Title(x, y, _("FileREF not updated:")));
+ y += title->get_h() + pad;
+ BC_TextBox *text_box;
+ add_subwindow(text_box = new BC_TextBox(x,y, get_w()-2*x, 1, path));
+ y += text_box->get_h() + 2*pad;
+ add_subwindow(title = new BC_Title(x, y, _("Save file ref changes?")));
+ add_subwindow(new BC_OKButton(this));
+ add_subwindow(new BC_CancelButton(this));
+ show_window();
+ unlock_window();
+}
+