*
*/
+#include "aboutprefs.h"
#include "asset.h"
#include "assets.h"
+#include "atrack.h"
#include "audioalsa.h"
+#include "autos.h"
#include "awindowgui.h"
#include "awindow.h"
#include "batchrender.h"
#include "bcdisplayinfo.h"
#include "bcsignals.h"
#include "bctimer.h"
+#include "bctrace.h"
#include "bdcreate.h"
#include "brender.h"
#include "cache.h"
#include "file.h"
#include "filesystem.h"
#include "filexml.h"
+#include "floatautos.h"
#include "framecache.h"
#include "gwindow.h"
#include "gwindowgui.h"
#include "keyframegui.h"
#include "indexfile.h"
+#include "intautos.h"
#include "interlacemodes.h"
#include "language.h"
#include "levelwindowgui.h"
#include "mwindow.h"
#include "nestededls.h"
#include "new.h"
+#include "panautos.h"
#include "patchbay.h"
#include "playback3d.h"
#include "playbackengine.h"
#include "pluginserver.h"
#include "pluginset.h"
#include "preferences.h"
+#include "proxy.h"
#include "record.h"
#include "recordmonitor.h"
#include "recordlabel.h"
#include "transition.h"
#include "transportque.h"
#include "vframe.h"
+#include "vtrack.h"
+#include "versioninfo.h"
#include "videodevice.inc"
#include "videowindow.h"
#include "vplayback.h"
#include "defaultformats.h"
#include "ntsczones.h"
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
#include <fcntl.h>
#include <string.h>
+#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <errno.h>
extern "C"
MWindow::MWindow()
: Thread(1, 0, 0)
{
+ run_lock = new Mutex("MWindow::run_lock");
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");
mainindexes = 0;
mainprogress = 0;
brender = 0;
+ brender_active = 0;
+ strcpy(cin_lang,"en");
channeldb_buz = new ChannelDB;
channeldb_v4l2jpeg = new ChannelDB;
//file_server = 0;
// Need to delete brender temporary here.
MWindow::~MWindow()
{
- in_destructor = 1;
+ run_lock->lock("MWindow::~MWindow");
stop_playback(1);
- stop_brender();
+ in_destructor = 1;
//printf("MWindow::~MWindow %d\n", __LINE__);
gui->stop_drawing();
gui->remote_control->deactivate();
gui->record->stop();
+#ifdef HAVE_DVB
gui->channel_info->stop();
- brender_lock->lock("MWindow::quit");
- delete brender; brender = 0;
- brender_lock->unlock();
+#endif
delete create_bd; create_bd = 0;
delete create_dvd; create_dvd = 0;
delete batch_render; batch_render = 0;
+ delete render; render = 0;
commit_commercial();
if( commercials && !commercials->remove_user() ) commercials = 0;
#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();
colormodels.remove_all_objects();
- delete gui; gui = 0;
- delete render; render = 0;
delete awindow; awindow = 0;
delete lwindow; lwindow = 0;
delete twindow; twindow = 0;
delete wwindow; wwindow = 0;
delete gwindow; gwindow = 0;
- // must be last or nouveau chokes
delete cwindow; cwindow = 0;
+ delete gui; gui = 0;
//delete file_server; file_server = 0; // reusable
delete mainindexes; mainindexes = 0;
delete mainprogress; mainprogress = 0;
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;
interlace_asset_fixmethods.remove_all_objects();
sighandler->terminate();
delete sighandler;
+ delete run_lock;
}
-void MWindow::quit(int unlock)
+void MWindow::quit()
{
- stop_playback(1);
- if(unlock) gui->unlock_window();
-
- brender_lock->lock("MWindow::quit");
- delete brender; brender = 0;
- brender_lock->unlock();
-
- interrupt_indexes();
- clean_indexes();
- save_defaults();
gui->set_done(0);
- if(unlock) gui->lock_window("MWindow::quit");
}
void MWindow::init_error()
// set the .bcast path
FileSystem fs;
- sprintf(string, "%s", BCASTDIR);
+ sprintf(string, "%s/", File::get_config_path());
fs.complete_path(string);
if(!fs.is_dir(string))
fs.create_dir(string);
}
const char *MWindow::default_std()
{
- int fd, i, l = 0;
- char buf[BCTEXTLEN];
- char *p;
+ char buf[BCTEXTLEN], *p = 0;
- if((fd = open(TIMEZONE_NAME, O_RDONLY)) >= 0)
- {
- l = read(fd, buf, BCTEXTLEN);
+ int fd = open(TIMEZONE_NAME, O_RDONLY);
+ if( fd >= 0 ) {
+ int l = read(fd, buf, sizeof(buf)-1);
close(fd);
- if(l > 0)
- {
+ if( l > 0 ) {
+ if( buf[l-1] == '\n' ) --l;
buf[l] = 0;
- if(buf[l - 1] == '\n')
- buf[--l] = 0;
+ p = buf;
}
- p = buf;
}
- if(l < 1)
- {
- if((l = readlink(LOCALTIME_LINK, buf, BCTEXTLEN)) > 0)
- {
+ if( !p ) {
+ int l = readlink(LOCALTIME_LINK, buf, sizeof(buf)-1);
+ if( l > 0 ) {
buf[l] = 0;
- if( (p=strstr(buf, ZONEINFO_STR)) != 0 )
- {
- p += strlen(ZONEINFO_STR);
- l = strlen(p);
- }
- else
- l = 0;
+ if( !(p=strstr(buf, ZONEINFO_STR)) != 0 ) return "PAL";
+ p += strlen(ZONEINFO_STR);
}
}
- if(l)
- {
- for(i = 0; ntsc_zones[i]; i++)
- if(strcmp(ntsc_zones[i], p) == 0)
- return "NTSC";
+
+ if( p ) {
+ for( int i=0; ntsc_zones[i]; ++i ) {
+ if( !strcmp(ntsc_zones[i], p) )
+ return "NTSC";
+ }
}
- return "PAL";
+
+ p = getenv("TZ");
+ if( p ) {
+ for( int i=0; ntsc_zones[i]; ++i ) {
+ if( !strcmp(ntsc_zones[i], p) )
+ return "NTSC";
+ }
+ }
+
+//__timezone: Seconds west of UTC. 240sec/deg
+ double tz_deg = -__timezone / 240.;
+// from Honolulu = -10, to New York = -5, 15deg/hr lat -150..-75
+ return tz_deg >= -10*15 && tz_deg <= -5*15 ? "NTSC" : "PAL";
}
void MWindow::fill_preset_defaults(const char *preset, EDLSession *session)
for(fpr = &format_presets[0]; fpr->name; fpr++)
{
- if(strcmp(fpr->name, preset) == 0)
+ if(strcmp(_(fpr->name), preset) == 0)
{
session->audio_channels = fpr->audio_channels;
session->audio_tracks = fpr->audio_tracks;
{
if(index < 0 || index >= (int)MAX_NUM_PRESETS)
return "Error";
- return format_presets[index].name;
+ return _(format_presets[index].name);
}
defaults->load();
}
+
+void MWindow::check_language()
+{
+ char curr_lang[BCTEXTLEN]; curr_lang[0] = 0;
+ const char *env_lang = getenv("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",
+ BC_Resources::language, BC_Resources::region, BC_Resources::encoding);
+ env_lang = curr_lang;
+ }
+ char last_lang[BCTEXTLEN]; last_lang[0] = 0;
+ defaults->get("LAST_LANG",last_lang);
+ if( strcmp(env_lang,last_lang)) {
+ printf("lang changed from '%s' to '%s'\n", last_lang, env_lang);
+ defaults->update("LAST_LANG",env_lang);
+ char plugin_path[BCTEXTLEN];
+ create_defaults_path(plugin_path, PLUGIN_FILE);
+ ::remove(plugin_path);
+ char ladspa_path[BCTEXTLEN];
+ create_defaults_path(ladspa_path, LADSPA_FILE);
+ ::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)
{
char *base_path = FileSystem::basepath(fs_path), *bp = base_path;
char *path = getenv("LADSPA_PATH");
char ladspa_path[BCTEXTLEN];
if( !path ) {
- get_exe_path(ladspa_path);
- strcat(ladspa_path, "/ladspa");
+ strncpy(ladspa_path, File::get_ladspa_path(), sizeof(ladspa_path));
path = ladspa_path;
}
for( int len=0; *path; path+=len ) {
len = !cp ? strlen(path) : cp-path;
char index_path[BCTEXTLEN], plugin_path[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);
strcpy(plugin_path, path); delete [] path;
printf("init ladspa index: %s\n", plugin_dir);
FILE *fp = fopen(index_path,"w");
- if( !fp ) {
+ if( !fp ) {
fprintf(stderr,_("MWindow::init_ladspa_index: "
"can't create plugin index: %s\n"), index_path);
return 1;
}
fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
fprintf(fp, "%s\n", plugin_dir);
- init_plugin_index(mwindow, preferences, fp, plugin_path);
+ init_plugin_index(mwindow, preferences, fp, plugin_path);
fclose(fp);
return 0;
}
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();
session->load_defaults(defaults);
// set x11_host, screens, window_config
screens = session->set_default_x11_host();
- BC_Signals::set_trap_path("/tmp/cinelerra_%d.dmp");
BC_Signals::set_trap_hook(trap_hook, this);
BC_Signals::set_catch_segv(preferences->trap_sigsegv);
BC_Signals::set_catch_intr(preferences->trap_sigintr);
+ if( preferences->trap_sigsegv || preferences->trap_sigintr ) {
+ BC_Trace::enable_locks();
+ }
+ else {
+ BC_Trace::disable_locks();
+ }
+ 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()
void MWindow::init_tipwindow()
{
+ TipWindow::load_tips(cin_lang);
if( !twindow )
twindow = new TipWindow(this);
twindow->start();
wwindow->show_warning(do_warning, text);
}
+int MWindow::wait_warning()
+{
+ return wwindow->wait_result();
+}
+
void MWindow::init_theme()
{
Timer timer;
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);
}
}
edl->create_objects();
fill_preset_defaults(default_standard, edl->session);
edl->load_defaults(defaults);
+ edl->session->brender_start = edl->session->brender_end = 0;
edl->create_default_tracks();
edl->tracks->update_y_pixels(theme);
}
interlace_asset_fixmethods.append(new InterlacefixmethodItem(string, x));
// Interlacing Modes
- ILACEASSETMODELISTADD(BC_ILACE_MODE_UNDETECTED); // Not included in the list for the project options.
+ ILACEASSETMODELISTADD(ILACE_MODE_UNDETECTED); // Not included in the list for the project options.
- ILACEASSETMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
- ILACEPROJECTMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
+ ILACEASSETMODELISTADD(ILACE_MODE_TOP_FIRST);
+ ILACEPROJECTMODELISTADD(ILACE_MODE_TOP_FIRST);
- ILACEASSETMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
- ILACEPROJECTMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
+ ILACEASSETMODELISTADD(ILACE_MODE_BOTTOM_FIRST);
+ ILACEPROJECTMODELISTADD(ILACE_MODE_BOTTOM_FIRST);
- ILACEASSETMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
- ILACEPROJECTMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
+ ILACEASSETMODELISTADD(ILACE_MODE_NOTINTERLACED);
+ ILACEPROJECTMODELISTADD(ILACE_MODE_NOTINTERLACED);
// Interlacing Fixing Methods
- ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_NONE);
- ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_UPONE);
- ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_DOWNONE);
+ ILACEFIXMETHODLISTADD(ILACE_FIXMETHOD_NONE);
+ ILACEFIXMETHODLISTADD(ILACE_FIXMETHOD_UPONE);
+ ILACEFIXMETHODLISTADD(ILACE_FIXMETHOD_DOWNONE);
}
void MWindow::init_indexes()
void MWindow::init_signals()
{
sighandler = new SigHandler;
- sighandler->initialize();
+ sighandler->initialize("/tmp/cinelerra_%d.dmp");
ENABLE_BUFFER
}
session->brender_end = 0;
brender_lock->unlock();
}
- if(brender) brender->restart(edl);
+ brender_active = 0;
+ stop_brender();
}
void MWindow::restart_brender()
{
//printf("MWindow::restart_brender 1\n");
- 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)
{
return result;
}
-void MWindow::set_brender_start()
+void MWindow::set_brender_active(int v, int update)
{
- edl->session->brender_start = edl->local_session->get_selectionstart(1);
- restart_brender();
- gui->draw_overlays(1);
-}
+ if( !preferences->use_brender ) v = 0;
+ brender_active = v;
+ gui->mainmenu->brender_active->set_checked(v);
+ if( v != 0 ) {
+ edl->session->brender_start = edl->local_session->get_selectionstart(1);
+ edl->session->brender_end = edl->local_session->get_selectionend(1);
+ if(EQUIV(edl->session->brender_end, edl->session->brender_start)) {
+ edl->session->brender_end = edl->tracks->total_video_length();
+ }
+ restart_brender();
+ }
+ else {
+ edl->session->brender_start = edl->session->brender_end = 0;
+ stop_brender();
+ }
+ if( update ) {
+ gui->update_timebar(0);
+ gui->draw_overlays(1);
+ }
+}
int MWindow::has_commercials()
{
void MWindow::stop_playback(int wait)
{
int locked = gui->get_window_lock();
- if( locked ) gui->unlock_window();
+ 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");
+ if( locked ) gui->lock_window("MWindow::stop_playback");
}
int MWindow::load_filenames(ArrayList<char*> *filenames,
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;
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
- if(result)
- {
- for(int j = 0; j < new_edls.total + 1; j++)
- {
- Asset *old_asset;
- if(j == new_edls.total)
- {
- old_asset = edl->assets->get_asset(new_asset->path);
- if( old_asset )
- {
- *new_asset = *old_asset;
- result = 0;
- }
- }
- else
- {
- old_asset = new_edls[j]->assets->get_asset(new_asset->path);
- if( old_asset )
- {
- *new_asset = *old_asset;
- result = 0;
- }
- }
+ for(int j = 0; result && j <= new_edls.total; j++) {
+ Asset *old_asset = j < new_edls.total ?
+ new_edls[j]->assets->get_asset(new_asset->path) :
+ edl->assets->get_asset(new_asset->path);
+ if( old_asset ) {
+ new_asset->copy_from(old_asset,1);
+ result = 0;
}
}
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
xml_file.read_from_file(filenames->get(i));
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
-
+ const char *cin_version = 0;
+ while( !xml_file.read_tag() ) {
+ if( xml_file.tag.title_is("EDL") ) {
+ cin_version = xml_file.tag.get_property("VERSION");
+ break;
+ }
+ }
+ xml_file.rewind();
+ if( !cin_version ) {
+ eprintf(_("XML file %s\n not from cinelerra."),filenames->get(i));
+ char string[BCTEXTLEN];
+ sprintf(string,_("Unknown %s"), filenames->get(i));
+ gui->show_message(string);
+ result = 1;
+ break;
+ }
+ if( strcmp(cin_version, CINELERRA_VERSION) ) {
+ char string[BCTEXTLEN];
+ snprintf(string, sizeof(string),
+ _("Warning: XML from cinelerra version %s\n"
+ "Session data may be incompatible."), cin_version);
+ show_warning(&preferences->warn_version, string);
+ }
if(load_mode == LOADMODE_NESTED)
{
// Load temporary EDL for nesting.
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);
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__);
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,
}
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__);
show_plugin(plugin);
}
}
- else
- {
- plugin->show = 0;
- }
plugin = (Plugin*)plugin->next;
}
}
// if just opening one new resource in replace mode
- if( load_mode == LOADMODE_REPLACE && new_edls.size() == 1 &&
- ftype != FILE_IS_XML )
- {
+ if( ftype != FILE_IS_XML &&
+ ( 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;
edl->local_session->set_selectionstart(0);
edl->local_session->set_selectionend(0);
+ set_brender_active(0, 0);
fit_selection();
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__);
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)
{
}
int64_t result = 0;
- fscanf(fd, _LD, &result);
+ fscanf(fd, "%jd", &result);
fclose(fd);
fd = 0;
if(result < 0x7fffffff) {
int want_new,
char *config_path)
{
- FileSystem fs;
const int debug = 0;
if(debug) PRINT_TRACE
if(debug) PRINT_TRACE
default_standard = default_std();
init_defaults(defaults, config_path);
+ check_language();
init_preferences();
if(splash_window)
splash_window->operation->update(_("Initializing Plugins"));
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
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());
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();
void MWindow::run()
{
+ run_lock->lock("MWindow::run");
gui->run_window();
+ stop_playback(1);
+
+ brender_lock->lock("MWindow::run 1");
+ delete brender; brender = 0;
+ brender_lock->unlock();
+
+ interrupt_indexes();
+ clean_indexes();
+ save_defaults();
+ run_lock->unlock();
}
void MWindow::show_vwindow()
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();
+}
void MWindow::show_lwindow()
{
if(lock_cwindow) cwindow->gui->unlock_window();
}
+void MWindow::set_auto_visibility(Autos *autos, int value)
+{
+ if( autos->type == Autos::AUTOMATION_TYPE_PLUGIN )
+ edl->session->auto_conf->plugins = value;
+ else if( autos->autoidx >= 0 )
+ edl->session->auto_conf->autos[autos->autoidx] = value;
+ else
+ return;
+
+ gui->update(0, 1, 0, 0, 0, 0, 0);
+ gui->mainmenu->update_toggles(1);
+ gui->unlock_window();
+ gwindow->gui->update_toggles(1);
+ gui->lock_window("MWindow::set_auto_visibility");
+}
+
void MWindow::set_keyframe_type(int mode)
{
gui->lock_window("MWindow::set_keyframe_type");
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);
// Needs mwindow to do GUI
gui->set_mwindow(this);
gui->open_plugin(0, preferences, edl, plugin);
- gui->show_gui();
plugin->show = 1;
+ gui->show_gui();
}
}
plugin_gui_lock->unlock();
ptr->hide_gui();
delete_plugin(ptr);
//sleep(1);
-// return;
+ return;
}
}
if(lock) plugin_gui_lock->unlock();
const int debug = 0;
if(debug) PRINT_TRACE
- restart_brender();
+ init_brender();
edl->tracks->update_y_pixels(theme);
if(debug) PRINT_TRACE
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);
}
void MWindow::save_backup()
{
FileXML file;
+ edl->optimize();
edl->set_path(session->filename);
- edl->save_xml(&file,
- BACKUP_PATH,
- 0,
- 0);
+ char backup_path[BCTEXTLEN];
+ snprintf(backup_path, sizeof(backup_path), "%s/%s",
+ File::get_config_path(), BACKUP_FILE);
+ edl->save_xml(&file, backup_path, 0, 0);
file.terminate_string();
- char path[BCTEXTLEN];
FileSystem fs;
- strcpy(path, BACKUP_PATH);
- fs.complete_path(path);
+ fs.complete_path(backup_path);
- if(file.write_to_file(path))
+ if(file.write_to_file(backup_path))
{
char string2[256];
- sprintf(string2, _("Couldn't open %s for writing."), BACKUP_PATH);
+ sprintf(string2, _("Couldn't open %s for writing."), backup_path);
gui->show_message(string2);
}
}
ArrayList<char*> path_list;
path_list.set_array_delete();
char *out_path;
- char string[BCTEXTLEN];
- strcpy(string, BACKUP_PATH);
+ char backup_path[BCTEXTLEN];
+ snprintf(backup_path, sizeof(backup_path), "%s/%s",
+ File::get_config_path(), BACKUP_FILE);
FileSystem fs;
- fs.complete_path(string);
+ fs.complete_path(backup_path);
- path_list.append(out_path = new char[strlen(string) + 1]);
- strcpy(out_path, string);
+ path_list.append(out_path = new char[strlen(backup_path) + 1]);
+ strcpy(out_path, backup_path);
load_filenames(&path_list, LOADMODE_REPLACE, 0);
edl->local_session->clip_title[0] = 0;
{
w = 1; h = 1;
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;
// square-ish pixels
if( EQUIV(ar, 1.0000) ) return 0;
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);
}
}
}
- 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();
}
}
- 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
void MWindow::dump_exe(FILE *fp)
{
- char proc_path[BCTEXTLEN], exe_path[BCTEXTLEN];
- sprintf(proc_path, "/proc/%d/exe", (int)getpid());
- int len = readlink(proc_path, exe_path, sizeof(exe_path));
- if( len < 0 ) { fprintf(fp,"readlink: %m\n"); return; }
- exe_path[len] = 0;
+ char proc_path[BCTEXTLEN], exe_path[BCTEXTLEN];
+ sprintf(proc_path, "/proc/%d/exe", (int)getpid());
+
+ int ret = -1, n = 100;
+ for( int len; (len=readlink(proc_path, exe_path, sizeof(exe_path)))>0; --n ) {
+ exe_path[len] = 0; strcpy(proc_path, exe_path);
+ ret = 0;
+ }
+ if( n < 0 || ret < 0 ) { fprintf(fp,"readlink: %m\n"); return; }
+
struct stat st;
- if( stat(exe_path,&st) ) { fprintf(fp,"stat: %m\n"); return; }
- fprintf(fp, "path: %s = %9jd bytes\n",exe_path,st.st_size);
- int fd = open(exe_path,O_RDONLY);
+ if( stat(proc_path,&st) ) { fprintf(fp,"stat: %m\n"); return; }
+ fprintf(fp, "path: %s = %9jd bytes\n",proc_path,st.st_size);
+ struct tm *tm = localtime(&st.st_mtime);
+ 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 buf[65536]; SHA1 sha1;
- while( (len=read(fd,buf,sizeof(buf))) > 0 ) {
- sha1.addBytes(buf, len);
+ uint8_t *bfr = 0;
+ int64_t bfrsz = 0;
+ int64_t pagsz = sysconf(_SC_PAGE_SIZE);
+ int64_t maxsz = 1024*pagsz;
+ int64_t size = st.st_size, pos = 0;
+ SHA1 sha1;
+ while( (bfrsz = size-pos) > 0 ) {
+ if( bfrsz > maxsz ) bfrsz = maxsz;
+ bfr = (uint8_t *)mmap(NULL, bfrsz, PROT_READ,
+ MAP_PRIVATE+MAP_NORESERVE+MAP_POPULATE, fd, pos);
+ if( bfr == MAP_FAILED ) break;
+ sha1.addBytes(bfr, bfrsz);
+ munmap(bfr, bfrsz);
+ pos += bfrsz;
}
close(fd);
+ ret = pos < size ? EIO : 0;
fprintf(fp, "SHA1: ");
uint8_t digest[20]; sha1.computeHash(digest);
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");
}
-
void MWindow::trap_hook(FILE *fp, void *vp)
{
MWindow *mwindow = (MWindow *)vp;
- fprintf(fp, "\nEXE:\n");
- mwindow->dump_exe(fp);
- fprintf(fp, "\nPLUGINS:\n");
- mwindow->dump_plugins(fp);
+// fprintf(fp, "\nPLUGINS:\n");
+// mwindow->dump_plugins(fp);
fprintf(fp, "\nEDL:\n");
mwindow->dump_edl(fp);
fprintf(fp, "\nUNDO:\n");
mwindow->dump_undo(fp);
+ fprintf(fp, "\nEXE: %s\n", AboutPrefs::build_timestamp);
+ mwindow->dump_exe(fp);
}
int MWindow::interrupt_indexes()
{
+ mainprogress->cancelled = 1;
mainindexes->interrupt_build();
return 0;
}
EDLSession *session = edl->session;
double old_framerate = session->frame_rate;
double old_samplerate = session->sample_rate;
+ int old_auto_keyframes = session->auto_keyframes;
+ session->auto_keyframes = 0;
int result = file->open_file(preferences, asset, 1, 0);
if( !result && delete_tracks > 0 )
undo->update_undo_before();
- if( !result && 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.
next_edit = edit->next;
if( edit->channel != vstream ||
!edit->asset || !edit->asset->is_asset ||
- *asset != *edit->asset )
+ !asset->equivalent(*edit->asset,1,1,edl) )
delete edit;
}
}
else if( delete_tracks )
edl->tracks->delete_track(track);
}
+ edl->retrack();
edl->resample(old_framerate, session->frame_rate, TRACK_VIDEO);
}
- if( !result && asset->channels > 0 ) {
+ if( !result && asset->audio_data && asset->channels > 0 ) {
session->sample_rate = asset->get_sample_rate();
int64_t channel_mask = 0;
- int astrm = file->get_audio_for_video(vstream, astream, channel_mask);
+ 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;
int channels = 0;
for( uint64_t mask=channel_mask; mask!=0; mask>>=1 ) channels += mask & 1;
+ if( channels < 1 ) channels = 1;
if( channels > 6 ) channels = 6;
session->audio_tracks = session->audio_channels = channels;
switch( channels ) {
session->achannel_positions[0] = 180;
session->achannel_positions[1] = 0;
break;
+ case 1:
+ session->achannel_positions[1] = 90;
+ break;
+ default: {
+ if( !channels ) break;
+ double t = 0, dt = 360./channels;
+ for( int i=channels; --i>=0; t+=dt )
+ session->achannel_positions[i] = int(t+0.5);
+ break; }
}
remap_audio(MWindow::AUDIO_1_TO_1);
next_edit = edit->next;
if( !((1<<edit->channel) & channel_mask) ||
!edit->asset || !edit->asset->is_asset ||
- *asset != *edit->asset )
+ !asset->equivalent(*edit->asset,1,1,edl) )
delete edit;
}
if( !track->edits->first )
edl->resample(old_samplerate, session->sample_rate, TRACK_AUDIO);
}
delete file;
+ session->auto_keyframes = old_auto_keyframes;
if( !result && delete_tracks > 0 ) {
save_backup();
undo->update_undo_after(_("select asset"), LOAD_ALL);
int MWindow::select_asset(int vtrack, int delete_tracks)
{
Track *track = edl->tracks->get(vtrack, TRACK_VIDEO);
+ if( !track )
+ track = edl->tracks->get(vtrack, TRACK_AUDIO);
if( !track ) return 1;
Edit *edit = track->edits->first;
if( !edit ) return 1;
Asset *asset = edit->asset;
if( !asset || !asset->is_asset ) return 1;
- return select_asset(asset, edit->channel, -1, delete_tracks);
+ return select_asset(asset, edit->channel, 0, delete_tracks);
}
void MWindow::dump_plugindb(FILE *fp)
plugindb->get(i)->dump(fp);
}
+FloatAuto* MWindow::get_float_auto(PatchGUI *patch,int idx)
+{
+ Auto *current = 0;
+ double unit_position = edl->local_session->get_selectionstart(1);
+ unit_position = patch->track->to_units(unit_position, 0);
+
+ FloatAutos *ptr = (FloatAutos*)patch->track->automation->autos[idx];
+ return (FloatAuto*)ptr->get_prev_auto( (long)unit_position, PLAY_FORWARD, current);
+}
+
+IntAuto* MWindow::get_int_auto(PatchGUI *patch,int idx)
+{
+ Auto *current = 0;
+ double unit_position = edl->local_session->get_selectionstart(1);
+ unit_position = patch->track->to_units(unit_position, 0);
+
+ IntAutos *ptr = (IntAutos*)patch->track->automation->autos[idx];
+ return (IntAuto*)ptr->get_prev_auto( (long)unit_position, PLAY_FORWARD, current);
+}
+
+PanAuto* MWindow::get_pan_auto(PatchGUI *patch)
+{
+ Auto *current = 0;
+ double unit_position = edl->local_session->get_selectionstart(1);
+ unit_position = patch->track->to_units(unit_position, 0);
+
+ PanAutos *ptr = (PanAutos*)patch->track->automation->autos[AUTOMATION_PAN];
+ return (PanAuto*)ptr->get_prev_auto( (long)unit_position, PLAY_FORWARD, current);
+}
+
+