#include "awindow.h"
#include "batchrender.h"
#include "bcdisplayinfo.h"
+#include "bcprogressbox.h"
#include "bcsignals.h"
#include "bctimer.h"
#include "bctrace.h"
#include "channeldb.h"
#include "channelinfo.h"
#include "clip.h"
+#include "clipedls.h"
#include "bccmodels.h"
#include "commercials.h"
+#include "confirmsave.h"
#include "cplayback.h"
#include "ctimebar.h"
#include "cwindowgui.h"
#include "mutex.h"
#include "mwindowgui.h"
#include "mwindow.h"
-#include "nestededls.h"
#include "new.h"
#include "panautos.h"
#include "patchbay.h"
#include "removefile.h"
#include "render.h"
#include "resourcethread.h"
+#include "savefile.inc"
#include "samplescroll.h"
#include "sha1.h"
#include "sighandler.h"
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
+#include <sys/file.h>
#include <limits.h>
#include <errno.h>
}
+extern long cin_timezone;
ArrayList<PluginServer*>* MWindow::plugindb = 0;
Commercials* MWindow::commercials = 0;
strcpy(cin_lang,"en");
channeldb_buz = new ChannelDB;
channeldb_v4l2jpeg = new ChannelDB;
- //file_server = 0;
plugin_guis = 0;
dead_plugins = 0;
keyframe_threads = 0;
restart_status = 0;
screens = 1;
in_destructor = 0;
+ speed_edl = 0;
+ proxy_beep = 0;
}
#ifdef HAVE_DVB
gui->channel_info->stop();
#endif
+ delete proxy_beep;
delete create_bd; create_bd = 0;
delete create_dvd; create_dvd = 0;
delete batch_render; batch_render = 0;
commit_commercial();
if( commercials && !commercials->remove_user() ) commercials = 0;
close_mixers();
-
+ if( speed_edl ) { speed_edl->remove_user(); speed_edl = 0; }
// Save defaults for open plugins
plugin_gui_lock->lock("MWindow::~MWindow");
for(int i = 0; i < plugin_guis->size(); i++) {
delete gwindow; gwindow = 0;
delete cwindow; cwindow = 0;
delete gui; gui = 0;
- //delete file_server; file_server = 0; // reusable
delete mainindexes; mainindexes = 0;
delete mainprogress; mainprogress = 0;
delete audio_cache; audio_cache = 0; // delete the cache after the assets
}
}
-//__timezone: Seconds west of UTC. 240sec/deg
- double tz_deg = -__timezone / 240.;
+// cin_timezone: Seconds west of UTC. 240sec/deg
+ double tz_deg = -cin_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";
}
else
create_defaults_path(path, CONFIG_FILE);
+ delete defaults;
defaults = new BC_Hash(path);
defaults->load();
}
delete [] base_path;
}
-int MWindow::load_plugin_index(MWindow *mwindow, const char *index_path, const char *plugin_dir)
+int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_dir)
{
-// load index
- FILE *fp = fopen(index_path, "r");
if( !fp ) return -1;
-
+// load index
+ fseek(fp, 0, SEEK_SET);
int ret = 0;
char index_line[BCTEXTLEN];
int index_version = -1, len = strlen(plugin_dir);
case PLUGIN_TYPE_FFMPEG: {
server = new_ffmpeg_server(mwindow, path);
break; }
+ case PLUGIN_TYPE_LV2: {
+ server = new_lv2_server(mwindow, path);
+ break; }
}
if( !server ) continue;
plugins.append(server);
ret = 1; continue;
}
}
- fclose(fp);
if( !ret )
ret = check_plugin_index(plugins, plugin_dir, ".");
create_defaults_path(index_path, PLUGIN_FILE);
char *plugin_dir = FileSystem::basepath(preferences->plugin_dir);
strcpy(plugin_path, plugin_dir); delete [] plugin_dir;
- if( !load_plugin_index(mwindow, index_path, plugin_path) ) return 1;
- printf("init plugin index: %s\n", plugin_path);
- FILE *fp = fopen(index_path,"w");
+ FILE *fp = fopen(index_path,"a+");
if( !fp ) {
fprintf(stderr,_("MWindow::init_plugins: "
- "can't create plugin index: %s\n"), index_path);
- return 1;
+ "can't open plugin index: %s\n"), index_path);
+ return -1;
+ }
+ int fd = fileno(fp), ret = -1;
+ if( !flock(fd, LOCK_EX) ) {
+ fseek(fp, 0, SEEK_SET);
+ ret = load_plugin_index(mwindow, fp, plugin_path);
+ }
+ if( ret > 0 ) {
+ ftruncate(fd, 0);
+ fseek(fp, 0, SEEK_SET);
+ printf("init plugin index: %s\n", plugin_path);
+ fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
+ fprintf(fp, "%s\n", plugin_path);
+ 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);
+ }
+ if( ret ) {
+ fprintf(stderr,_("MWindow::init_plugins: "
+ "can't %s plugin index: %s\n"),
+ ret>0 ? _("create") : _("lock"), index_path);
}
- fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
- fprintf(fp, "%s\n", plugin_path);
- init_plugin_index(mwindow, preferences, fp, plugin_path);
- init_ffmpeg_index(mwindow, preferences, fp);
fclose(fp);
- return load_plugin_index(mwindow, index_path, plugin_path);
+ return ret;
}
int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences)
for( char *bp=plugin_path; *bp!=0; ++bp )
*cp++ = *bp=='/' ? '_' : *bp;
*cp = 0;
- if( !load_plugin_index(mwindow, index_path, plugin_path) ) continue;
- if( init_ladspa_index(mwindow, preferences, index_path, plugin_path) ) continue;
- load_plugin_index(mwindow, index_path, plugin_path);
+ FILE *fp = fopen(index_path,"a+");
+ if( !fp ) {
+ fprintf(stderr,_("MWindow::init_ladspa_plugins: "
+ "can't open ladspa plugin index: %s\n"), index_path);
+ continue;
+ }
+ int fd = fileno(fp), ret = -1;
+ if( !flock(fd, LOCK_EX) ) {
+ fseek(fp, 0, SEEK_SET);
+ ret = load_plugin_index(mwindow, fp, plugin_path);
+ }
+ if( ret > 0 ) {
+ ftruncate(fd, 0);
+ fseek(fp, 0, SEEK_SET);
+ init_ladspa_index(mwindow, preferences, fp, plugin_path);
+ fseek(fp, 0, SEEK_SET);
+ ret = load_plugin_index(mwindow, fp, plugin_path);
+ }
+ if( ret ) {
+ fprintf(stderr,_("MWindow::init_ladspa_plugins: "
+ "can't %s ladspa plugin index: %s\n"),
+ ret>0 ? _("create") : _("lock"), index_path);
+ }
+ fclose(fp);
}
return 1;
}
scan_plugin_index(mwindow, preferences, fp, plugin_dir, ".", idx);
}
-int MWindow::init_ladspa_index(MWindow *mwindow, Preferences *preferences,
- const char *index_path, const char *plugin_dir)
-{
- char plugin_path[BCTEXTLEN], *path = FileSystem::basepath(plugin_dir);
- strcpy(plugin_path, path); delete [] path;
- printf("init ladspa index: %s\n", plugin_dir);
- FILE *fp = fopen(index_path,"w");
- 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);
- fclose(fp);
- return 0;
-}
-
void MWindow::scan_plugin_index(MWindow *mwindow, Preferences *preferences, FILE *fp,
const char *plug_dir, const char *plug_path, int &idx)
{
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;
+ const char *dat_path = File::get_cindat_path();
+ char msg_path[BCTEXTLEN];
FILE *fp = 0;
if( BC_Resources::language[0] ) {
snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.%s",
- cfg_path, lang);
+ dat_path, lang);
fp = fopen(msg_path, "r");
}
if( !fp ) {
- txt = 1;
snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.txt",
- cfg_path);
+ dat_path);
fp = fopen(msg_path, "r");
}
if( !fp ) return;
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) );
+ while( --idx>=0 && strcmp(plugins[idx]->title, title) );
if( idx >= 0 ) {
delete [] plugins[idx]->tip;
plugins[idx]->tip = cstrdup(text);
return 0;
}
+// repair session files with xlated plugin titles
+void MWindow::fix_plugin_title(char *title)
+{
+ for(int i = 0; i < plugindb->total; i++) {
+ PluginServer *server = plugindb->get(i);
+ if( !server->title ) continue;
+ const char *server_title = server->title;
+ if( !bstrcasecmp(title, _(server_title)) ) {
+ strcpy(title, server_title);
+ return;
+ }
+ }
+}
+
int MWindow::plugin_exists(const char *plugin_path, ArrayList<PluginServer*> &plugins)
{
for( int i=0; i<plugins.size(); ++i )
return !plugindb ? 0 : plugin_exists(plugin_path, *plugindb);
}
+void MWindow::remove_plugin_index()
+{
+ char index_path[BCTEXTLEN];
+ MWindow::create_defaults_path(index_path, PLUGIN_FILE);
+ ::remove(index_path);
+}
+
void MWindow::init_preferences()
{
preferences = new Preferences;
preferences->load_defaults(defaults);
+ const char *lv2_path = getenv("LV2_PATH");
+ if( lv2_path && strcmp(lv2_path, preferences->lv2_path) ) {
+ strncpy(preferences->lv2_path, lv2_path, sizeof(preferences->lv2_path));
+ remove_plugin_index();
+ }
+ else if( !lv2_path && preferences->lv2_path[0] ) {
+ File::setenv_path("LV2_PATH",preferences->lv2_path, 0);
+ }
session = new MainSession(this);
session->load_defaults(defaults);
// set x11_host, screens, window_config
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;
+ YUV::yuv.yuv_set_colors(preferences->yuv_color_space, preferences->yuv_color_range);
}
void MWindow::clean_indexes()
fprintf(stderr, _("MWindow::init_theme: prefered theme %s not found.\n"),
preferences->theme);
- const char *default_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);
{
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 )
}
void MWindow::queue_mixers(EDL *edl, int command, int wait_tracking,
- int use_inout, int update_refresh, int toggle_audio)
+ int use_inout, int update_refresh, int toggle_audio, int loop_play)
{
zwindows_lock->lock("MWindow::queue_mixers");
for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
}
zwindow->change_source(mixer_edl);
zwindow->issue_command(command,
- wait_tracking, use_inout, update_refresh, toggle_audio);
+ wait_tracking, use_inout, update_refresh, toggle_audio, loop_play);
}
zwindows_lock->unlock();
}
-void MWindow::refresh_mixers()
+void MWindow::refresh_mixers(int dir)
{
- queue_mixers(edl,CURRENT_FRAME,0,0,1,0);
+ int command = dir >= 0 ? CURRENT_FRAME : LAST_FRAME;
+ queue_mixers(edl,command,0,0,1,0,0);
}
void MWindow::stop_mixers()
for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
ZWindow *zwindow = zwindows[vidx];
if( zwindow->idx < 0 ) continue;
- zwindow->issue_command(STOP, 0, 0, 0, 0);
+ zwindow->issue_command(STOP, 0, 0, 0, 0, 0);
}
}
-void MWindow::close_mixers()
+void MWindow::close_mixers(int destroy)
{
+ ArrayList<ZWindow*> closed;
zwindows_lock->lock("MWindow::close_mixers");
- for( int i=0; i<zwindows.size(); ++i ) {
+ for( int i=zwindows.size(); --i>=0; ) {
ZWindow *zwindow = zwindows[i];
if( zwindow->idx < 0 ) continue;
+ zwindow->destroy = destroy;
ZWindowGUI *zgui = zwindow->zgui;
zgui->lock_window("MWindow::select_zwindow 0");
zgui->set_done(0);
zgui->unlock_window();
+ closed.append(zwindow);
}
zwindows_lock->unlock();
- for( int i=0; i<zwindows.size(); ++i ) {
- ZWindow *zwindow = zwindows[i];
- if( zwindow->idx < 0 ) continue;
- zwindow->close_window();
+ for( int i=0; i<closed.size(); ++i ) {
+ ZWindow *zwindow = closed[i];
+ zwindow->join();
}
}
+ZWindow *MWindow::create_mixer(Indexable *indexable)
+{
+ ArrayList<Indexable*> new_assets;
+ new_assets.append(indexable);
+ Track *track = edl->tracks->last;
+ load_assets(&new_assets, 0, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0);
+ track = !track ? edl->tracks->first : track->next;
+ Mixer *mixer = 0;
+ ZWindow *zwindow = get_mixer(mixer);
+ while( track ) {
+ track->play = track->record = 0;
+ if( track->data_type == TRACK_VIDEO ) {
+ sprintf(track->title, _("Mixer %d"), zwindow->idx);
+ }
+ mixer->mixer_ids.append(track->get_mixer_id());
+ track = track->next;
+ }
+ if( indexable->is_asset ) {
+ char *path = indexable->path;
+ char *tp = strrchr(path, '/');
+ if( !tp ) tp = path; else ++tp;
+ zwindow->set_title(tp);
+ }
+ else {
+ char *title = ((EDL*)indexable)->local_session->clip_title;
+ zwindow->set_title(title);
+ }
+ return zwindow;
+}
+
+void MWindow::create_mixers()
+{
+ if( !session->drag_assets->size() &&
+ !session->drag_clips->size() ) return;
+ undo->update_undo_before();
+
+ select_zwindow(0);
+ ArrayList<ZWindow *>new_mixers;
+
+ for( int i=0; i<session->drag_assets->size(); ++i ) {
+ Indexable *indexable = session->drag_assets->get(i);
+ if( !indexable->have_video() ) continue;
+ ZWindow *zwindow = create_mixer(indexable);
+ new_mixers.append(zwindow);
+ }
+ for( int i=0; i<session->drag_clips->size(); ++i ) {
+ Indexable *indexable = (Indexable*)session->drag_clips->get(i);
+ if( !indexable->have_video() ) continue;
+ ZWindow *zwindow = create_mixer(indexable);
+ new_mixers.append(zwindow);
+ }
+
+ tile_mixers();
+ for( int i=0; i<new_mixers.size(); ++i )
+ new_mixers[i]->start();
+
+ refresh_mixers();
+ save_backup();
+ undo->update_undo_after(_("create mixers"), LOAD_ALL);
+ restart_brender();
+ gui->update(1, 2, 1, 1, 1, 1, 0);
+ sync_parameters(CHANGE_ALL);
+}
+
void MWindow::open_mixers()
{
for( int i=0; i<edl->mixers.size(); ++i ) {
void MWindow::init_gui()
{
gui = new MWindowGUI(this);
- gui->lock_window("MWindow::init_gui");
gui->create_objects();
- gui->unlock_window();
gui->load_defaults(defaults);
}
//printf("MWindow::restart_brender 1\n");
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 ) return;
- int locked = gui->get_window_lock();
- if( locked ) gui->unlock_window();
+// cannot be holding mwindow->gui display lock
brender->stop();
- if( locked ) gui->lock_window("MWindow::stop_brender");
}
int MWindow::brender_available(int position)
}
else {
edl->session->brender_start = edl->session->brender_end = 0;
+ gui->unlock_window();
stop_brender();
+ gui->lock_window("MWindow::set_brender_active");
}
if( update ) {
gui->update_timebar(0);
int MWindow::has_commercials()
{
+#ifdef HAVE_COMMERCIAL
return theme->use_commercials;
+#else
+ return 0;
+#endif
}
void MWindow::init_commercials()
{
+#ifdef HAVE_COMMERCIAL
if( !commercials ) {
commercials = new Commercials(this);
commercial_active = 0;
}
else
commercials->add_user();
+#endif
}
void MWindow::commit_commercial()
{
+#ifdef HAVE_COMMERCIAL
if( !commercial_active ) return;
commercial_active = 0;
if( !commercials ) return;
commercials->commitDb();
+#endif
}
void MWindow::undo_commercial()
{
+#ifdef HAVE_COMMERCIAL
if( !commercial_active ) return;
commercial_active = 0;
if( !commercials ) return;
commercials->undoDb();
+#endif
}
int MWindow::put_commercial()
{
+ int result = 0;
+#ifdef HAVE_COMMERCIAL
double start = edl->local_session->get_selectionstart();
double end = edl->local_session->get_selectionend();
if( start >= end ) return 0;
const char *errmsg = 0;
int count = 0;
Tracks *tracks = edl->tracks;
- int result = 0;
//check it
for(Track *track=tracks->first; track && !errmsg; track=track->next) {
if( track->data_type != TRACK_VIDEO ) continue;
undo_commercial();
result = 1;
}
+#endif
return result;
}
}
}
+void MWindow::stop_transport()
+{
+ gui->stop_transport(gui->get_window_lock() ? "MWindow::stop_transport" : 0);
+}
+
+void MWindow::beep(double freq, double secs, double gain)
+{
+ if( !proxy_beep ) proxy_beep = new ProxyBeep(this);
+ proxy_beep->tone(freq, secs, gain);
+}
+
int MWindow::load_filenames(ArrayList<char*> *filenames,
int load_mode,
int update_filename)
// Define new_edls and new_assets to load
int result = 0, ftype = -1;
- for(int i = 0; i < filenames->size(); i++)
- {
+
+ for( int i=0; i<filenames->size(); ++i ) {
// Get type of file
File *new_file = new File;
Asset *new_asset = new Asset(filenames->get(i));
char string[BCTEXTLEN];
new_edl->create_objects();
- new_edl->copy_session(edl);
+ new_edl->copy_session(edl, -1);
new_file->set_program(edl->session->program_no);
sprintf(string, _("Loading %s"), new_asset->path);
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
result = 1;
- switch(ftype)
- {
+ switch( ftype ) {
// Convert media file to EDL
- case FILE_OK:
+ case FILE_OK:
// Warn about odd image dimensions
- if(new_asset->video_data &&
- ((new_asset->width % 2) ||
- (new_asset->height % 2)))
- {
- char string[BCTEXTLEN];
- sprintf(string, _("%s's resolution is %dx%d.\nImages with odd dimensions may not decode properly."),
- new_asset->path,
- new_asset->width,
- new_asset->height);
- MainError::show_error(string);
- }
-
- if(new_asset->program >= 0 &&
- edl->session->program_no != new_asset->program)
- {
- char string[BCTEXTLEN];
- sprintf(string, _("%s's index was built for program number %d\n"
- "Playback preference is %d.\n Using program %d."),
- new_asset->path, new_asset->program,
- edl->session->program_no, new_asset->program);
- MainError::show_error(string);
- }
+ if( new_asset->video_data &&
+ ((new_asset->width % 2) || (new_asset->height % 2)) ) {
+ char string[BCTEXTLEN];
+ sprintf(string, _("%s's resolution is %dx%d.\nImages with odd dimensions may not decode properly."),
+ new_asset->path, new_asset->width, new_asset->height);
+ MainError::show_error(string);
+ }
+ if( new_asset->program >= 0 &&
+ edl->session->program_no != new_asset->program ) {
+ char string[BCTEXTLEN];
+ sprintf(string, _("%s's index was built for program number %d\n"
+ "Playback preference is %d.\n Using program %d."),
+ new_asset->path, new_asset->program,
+ edl->session->program_no, new_asset->program);
+ MainError::show_error(string);
+ }
- if(load_mode != LOADMODE_RESOURCESONLY)
- {
- RecordLabels *labels = edl->session->label_cells ?
- new RecordLabels(new_file) : 0;
- asset_to_edl(new_edl, new_asset, labels);
- new_edls.append(new_edl);
- new_asset->Garbage::remove_user();
- delete labels;
- new_asset = 0;
- }
- else
- {
- new_assets.append(new_asset);
- new_asset = 0;
- }
+ if( load_mode != LOADMODE_RESOURCESONLY ) {
+ RecordLabels *labels = edl->session->label_cells ?
+ new RecordLabels(new_file) : 0;
+ asset_to_edl(new_edl, new_asset, labels);
+ new_edls.append(new_edl);
+ new_edl->add_user();
+ delete labels;
+ }
+ else {
+ new_assets.append(new_asset);
+ new_asset->add_user();
+ }
// Set filename to nothing for assets since save EDL would overwrite them.
- if(load_mode == LOADMODE_REPLACE ||
- load_mode == LOADMODE_REPLACE_CONCATENATE)
- {
- set_filename("");
+ if( load_mode == LOADMODE_REPLACE ||
+ load_mode == LOADMODE_REPLACE_CONCATENATE ) {
+ set_filename("");
// Reset timeline position
- for(int i = 0; i < TOTAL_PANES; i++)
- {
- new_edl->local_session->view_start[i] = 0;
- new_edl->local_session->track_start[i] = 0;
- }
+ for( int i=0; i<TOTAL_PANES; ++i ) {
+ new_edl->local_session->view_start[i] = 0;
+ new_edl->local_session->track_start[i] = 0;
}
+ }
- result = 0;
- break;
+ result = 0;
+ break;
// File not found
- 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;
+ 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:
- {
+ case FILE_UNRECOGNIZED_CODEC: {
// Test index file
- { IndexFile indexfile(this, new_asset);
- if( !(result = indexfile.open_index()) )
- indexfile.close_index();
- }
+ { IndexFile indexfile(this, new_asset);
+ if( !(result = indexfile.open_index()) )
+ indexfile.close_index(); }
// Test existing EDLs
- 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;
- }
+ for( int j=0; result && j<new_edls.total; ++j ) {
+ Asset *old_asset = new_edls[j]->assets->get_asset(new_asset->path);
+ if( old_asset ) {
+ new_asset->copy_from(old_asset,1);
+ result = 0;
+ }
+ }
+ if( result ) {
+ Asset *old_asset = edl->assets->get_asset(new_asset->path);
+ if( old_asset ) {
+ new_asset->copy_from(old_asset,1);
+ result = 0;
}
+ }
// Prompt user
- if(result)
- {
- char string[BCTEXTLEN];
- FileSystem fs;
- fs.extract_name(string, new_asset->path);
-
- strcat(string, _("'s format couldn't be determined."));
- new_asset->audio_data = 1;
- new_asset->format = FILE_PCM;
- new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
- new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
- new_asset->bits = defaults->get("AUDIO_BITS", 16);
- new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
- new_asset->signed_ = defaults->get("SIGNED_", 1);
- new_asset->header = defaults->get("HEADER", 0);
-
- FileFormat fwindow(this);
- fwindow.create_objects(new_asset, string);
- result = fwindow.run_window();
-
-
- defaults->update("AUDIO_CHANNELS", new_asset->channels);
- defaults->update("SAMPLE_RATE", new_asset->sample_rate);
- defaults->update("AUDIO_BITS", new_asset->bits);
- defaults->update("BYTE_ORDER", new_asset->byte_order);
- defaults->update("SIGNED_", new_asset->signed_);
- defaults->update("HEADER", new_asset->header);
- save_defaults();
- }
+ if( result ) {
+ char string[BCTEXTLEN];
+ FileSystem fs;
+ fs.extract_name(string, new_asset->path);
+
+ strcat(string, _("'s format couldn't be determined."));
+ new_asset->audio_data = 1;
+ new_asset->format = FILE_PCM;
+ new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
+ new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
+ new_asset->bits = defaults->get("AUDIO_BITS", 16);
+ new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
+ new_asset->signed_ = defaults->get("SIGNED_", 1);
+ new_asset->header = defaults->get("HEADER", 0);
+
+ FileFormat fwindow(this);
+ fwindow.create_objects(new_asset, string);
+ result = fwindow.run_window();
+
+ defaults->update("AUDIO_CHANNELS", new_asset->channels);
+ defaults->update("SAMPLE_RATE", new_asset->sample_rate);
+ defaults->update("AUDIO_BITS", new_asset->bits);
+ defaults->update("BYTE_ORDER", new_asset->byte_order);
+ defaults->update("SIGNED_", new_asset->signed_);
+ defaults->update("HEADER", new_asset->header);
+ save_defaults();
+ }
// Append to list
- if(!result)
- {
+ if( !result ) {
// Recalculate length
- delete new_file;
- new_file = new File;
- result = new_file->open_file(preferences, new_asset, 1, 0);
+ delete new_file;
+ new_file = new File;
+ result = new_file->open_file(preferences, new_asset, 1, 0);
- if(load_mode != LOADMODE_RESOURCESONLY)
- {
- RecordLabels *labels = edl->session->label_cells ?
- new RecordLabels(new_file) : 0;
- asset_to_edl(new_edl, new_asset, labels);
- new_edls.append(new_edl);
- new_asset->Garbage::remove_user();
- delete labels;
- new_asset = 0;
- }
- else
- {
- new_assets.append(new_asset);
- new_asset = 0;
- }
+ if( load_mode != LOADMODE_RESOURCESONLY ) {
+ RecordLabels *labels = edl->session->label_cells ?
+ new RecordLabels(new_file) : 0;
+ asset_to_edl(new_edl, new_asset, labels);
+ new_edls.append(new_edl);
+ new_edl->add_user();
+ delete labels;
}
- else
- {
- result = 1;
+ else {
+ new_assets.append(new_asset);
+ new_asset->add_user();
}
- break;
}
+ else {
+ result = 1;
+ }
+ break; }
- case FILE_IS_XML:
- {
- FileXML xml_file;
+ case FILE_IS_XML: {
+ FileXML xml_file;
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
- xml_file.read_from_file(filenames->get(i));
+ 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;
+ 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;
}
- 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)
- {
+ }
+ 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.
- EDL *nested_edl = new EDL;
- nested_edl->create_objects();
- nested_edl->set_path(filenames->get(i));
- nested_edl->load_xml(&xml_file, LOAD_ALL);
+ EDL *nested_edl = new EDL;
+ nested_edl->create_objects();
+ nested_edl->load_xml(&xml_file, LOAD_ALL);
//printf("MWindow::load_filenames %p %s\n", nested_edl, nested_edl->project_path);
- edl_to_nested(new_edl, nested_edl);
- nested_edl->Garbage::remove_user();
- }
- else
- {
+ new_edl->create_nested(nested_edl);
+ new_edl->set_path(filenames->get(i));
+ nested_edl->Garbage::remove_user();
+ }
+ else {
// Load EDL for pasting
- new_edl->load_xml(&xml_file, LOAD_ALL);
+ new_edl->load_xml(&xml_file, LOAD_ALL);
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
- test_plugins(new_edl, filenames->get(i));
+ test_plugins(new_edl, filenames->get(i));
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
- if(load_mode == LOADMODE_REPLACE ||
- load_mode == LOADMODE_REPLACE_CONCATENATE)
- {
- strcpy(session->filename, filenames->get(i));
- strcpy(new_edl->local_session->clip_title,
- filenames->get(i));
- 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);
- }
+ if( load_mode == LOADMODE_REPLACE ||
+ load_mode == LOADMODE_REPLACE_CONCATENATE ) {
+ strcpy(session->filename, filenames->get(i));
+ strcpy(new_edl->local_session->clip_title,
+ filenames->get(i));
+ 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);
- result = 0;
- break;
}
+
+ new_edls.append(new_edl);
+ new_edl->add_user();
+ result = 0;
+ break; }
}
-// edls are in new_edls
- if( result && new_edl ) new_edl->Garbage::remove_user();
-// assets are copied
- if( new_asset ) new_asset->Garbage::remove_user();
+ new_edl->Garbage::remove_user();
+ new_asset->Garbage::remove_user();
// Store for testing index
new_files.append(new_file);
// Add new assets to EDL and schedule assets for index building.
int got_indexes = 0;
- for(int i = 0; i < new_edls.size(); i++)
- {
+ for( int i=0; i<new_edls.size(); ++i ) {
EDL *new_edl = new_edls[i];
- for(int j = 0; j < new_edl->nested_edls->size(); j++)
- {
- mainindexes->add_next_asset(0,
- new_edl->nested_edls->get(j));
+ for( int j=0; j<new_edl->nested_edls.size(); ++j ) {
+ mainindexes->add_next_asset(0, new_edl->nested_edls[j]);
+ edl->nested_edls.update_index(new_edl->nested_edls[j]);
got_indexes = 1;
- edl->nested_edls->update_index(new_edl->nested_edls->get(j));
}
}
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
- for(int i = 0; i < new_assets.size(); i++)
- {
+ for( int i=0; i<new_assets.size(); ++i ) {
Asset *new_asset = new_assets[i];
File *new_file = 0;
int got_it = 0;
- for(int j = 0; j < new_files.size(); j++)
- {
+ for( int j=0; j<new_files.size(); ++j ) {
new_file = new_files[j];
- if(!strcmp(new_file->asset->path,
- new_asset->path))
- {
+ if( !strcmp(new_file->asset->path, new_asset->path) ) {
got_it = 1;
break;
}
}
mainindexes->add_next_asset(got_it ? new_file : 0, new_asset);
- got_indexes = 1;
edl->assets->update(new_asset);
+ got_indexes = 1;
}
if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
load_mode == LOADMODE_REPLACE_CONCATENATE ) ) {
select_asset(0, 0);
edl->session->proxy_scale = 1;
+ edl->session->proxy_disabled_scale = 1;
edl->session->proxy_use_scaler = 0;
edl->session->proxy_auto_scale = 0;
+ edl->session->proxy_beep = 0;
edl->local_session->preview_start = 0;
- edl->local_session->preview_end = edl->tracks->total_length();
+ edl->local_session->preview_end = -1;
edl->local_session->loop_playback = 0;
edl->local_session->set_selectionstart(0);
edl->local_session->set_selectionend(0);
}
}
gui->unlock_window(); // to update progress bar
- render_proxy(orig_idxbls);
+ int ret = render_proxy(orig_idxbls);
gui->lock_window("MWindow::load_filenames");
+ if( ret >= 0 && edl->session->proxy_beep ) {
+ if( ret > 0 )
+ beep(2000., 1.5, 0.5);
+ else
+ beep(4000., 0.25, 0.5);
+ }
}
// need to update undo before project, since mwindow is unlocked & a new load
return 0;
}
-void MWindow::render_proxy(ArrayList<Indexable *> &new_idxbls)
+int MWindow::render_proxy(ArrayList<Indexable *> &new_idxbls)
{
Asset *format_asset = new Asset;
format_asset->format = FILE_FFMPEG;
&proxy_render.orig_idxbls, &proxy_render.orig_proxies);
}
format_asset->remove_user();
+ return !result ? proxy_render.needed_proxies.size() : -1;
+}
+
+int MWindow::enable_proxy()
+{
+ int ret = 0;
+ if( edl->session->proxy_scale == 1 &&
+ edl->session->proxy_disabled_scale != 1 ) {
+ int new_scale = edl->session->proxy_disabled_scale;
+ int new_use_scaler = edl->session->proxy_use_scaler;
+ edl->session->proxy_disabled_scale = 1;
+ Asset *asset = new Asset;
+ asset->format = FILE_FFMPEG;
+ asset->load_defaults(defaults, "PROXY_", 1, 1, 0, 0, 0);
+ ret = to_proxy(asset, new_scale, new_use_scaler);
+ asset->remove_user();
+ if( ret > 0 )
+ beep(2000., 1.5, 0.5);
+ }
+ return 1;
+}
+
+int MWindow::disable_proxy()
+{
+ if( edl->session->proxy_scale != 1 &&
+ edl->session->proxy_disabled_scale == 1 ) {
+ int new_scale = 1;
+ int new_use_scaler = edl->session->proxy_use_scaler;
+ edl->session->proxy_disabled_scale = edl->session->proxy_scale;
+ 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();
+ }
+ return 1;
+}
+
+int MWindow::to_proxy(Asset *asset, int new_scale, int new_use_scaler)
+{
+ ArrayList<Indexable*> orig_idxbls;
+ ArrayList<Indexable*> proxy_assets;
+
+ edl->Garbage::add_user();
+ save_backup();
+ undo->update_undo_before(_("proxy"), this);
+ ProxyRender proxy_render(this, asset);
+
+// revert project to original size from current size
+// remove all session proxy assets at the at the current proxy_scale
+ int proxy_scale = edl->session->proxy_scale;
+
+ if( proxy_scale > 1 ) {
+ Asset *orig_asset = edl->assets->first;
+ for( ; orig_asset; orig_asset=orig_asset->next ) {
+ char new_path[BCTEXTLEN];
+ proxy_render.to_proxy_path(new_path, orig_asset, proxy_scale);
+// test if proxy asset was already added to proxy_assets
+ int got_it = 0;
+ for( int i = 0; !got_it && i<proxy_assets.size(); ++i )
+ got_it = !strcmp(proxy_assets[i]->path, new_path);
+ if( got_it ) continue;
+ Asset *proxy_asset = edl->assets->get_asset(new_path);
+ if( !proxy_asset ) continue;
+// add pointer to existing EDL asset if it exists
+// EDL won't delete it unless it's the same pointer.
+ proxy_assets.append(proxy_asset);
+ proxy_asset->add_user();
+ orig_idxbls.append(orig_asset);
+ orig_asset->add_user();
+ }
+ 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;
+ for( int i = 0; !got_it && i<proxy_assets.size(); ++i )
+ got_it = !strcmp(proxy_assets[i]->path, new_path);
+ if( got_it ) continue;
+ Asset *proxy_nested = edl->assets->get_asset(new_path);
+ if( !proxy_nested ) continue;
+// add pointer to existing EDL asset if it exists
+// EDL won't delete it unless it's the same pointer.
+ proxy_assets.append(proxy_nested);
+ proxy_nested->add_user();
+ orig_idxbls.append(orig_nested);
+ orig_nested->add_user();
+ }
+
+// convert from the proxy assets to the original assets
+ edl->set_proxy(1, 0, &proxy_assets, &orig_idxbls);
+
+// remove the references
+ for( int i=0; i<proxy_assets.size(); ++i ) {
+ Asset *proxy = (Asset *) proxy_assets[i];
+ proxy->width = proxy->actual_width;
+ proxy->height = proxy->actual_height;
+ proxy->remove_user();
+ edl->assets->remove_pointer(proxy);
+ proxy->remove_user();
+ }
+ proxy_assets.remove_all();
+ for( int i = 0; i < orig_idxbls.size(); i++ )
+ orig_idxbls[i]->remove_user();
+ orig_idxbls.remove_all();
+ }
+
+ ArrayList<char *> confirm_paths; // test for new files
+ confirm_paths.set_array_delete();
+
+// convert to new size if not original size
+ if( new_scale != 1 ) {
+ FileSystem fs;
+ Asset *orig = edl->assets->first;
+ for( ; orig; orig=orig->next ) {
+ Asset *proxy = proxy_render.add_original(orig, new_scale);
+ if( !proxy ) continue;
+ 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 ) {
+ if( exists ) // prompt user to overwrite
+ confirm_paths.append(cstrdup(proxy->path));
+ proxy_render.add_needed(orig, proxy);
+ }
+ }
+ for( int i=0,n=edl->nested_edls.size(); i<n; ++i ) {
+ EDL *orig_nested = edl->nested_edls[i];
+ Asset *proxy = proxy_render.add_original(orig_nested, new_scale);
+ if( !proxy ) continue;
+ int exists = fs.get_size(proxy->path) > 0 ? 1 : 0;
+ int got_it = exists && // if proxy exists, and is newer than orig_nested
+ fs.get_date(proxy->path) > fs.get_date(orig_nested->path) ? 1 : 0;
+ if( !got_it ) {
+ if( exists ) // prompt user to overwrite
+ confirm_paths.append(cstrdup(proxy->path));
+ proxy_render.add_needed(orig_nested, proxy);
+ }
+ }
+ }
+
+ int result = 0;
+// test for existing files
+ if( confirm_paths.size() ) {
+ result = ConfirmSave::test_files(this, &confirm_paths);
+ confirm_paths.remove_all_objects();
+ }
+
+ if( !result )
+ result = proxy_render.create_needed_proxies(new_scale);
+
+ if( !result ) // resize project
+ edl->set_proxy(new_scale, new_use_scaler,
+ &proxy_render.orig_idxbls, &proxy_render.orig_proxies);
+
+ undo->update_undo_after(_("proxy"), LOAD_ALL);
+ edl->Garbage::remove_user();
+ restart_brender();
+
+ gui->lock_window("MWindow::to_proxy");
+ update_project(LOADMODE_REPLACE);
+ gui->unlock_window();
+
+ return !result ? proxy_render.needed_proxies.size() : -1;
}
void MWindow::test_plugins(EDL *new_edl, char *path)
{
char string[BCTEXTLEN];
-// Do a check weather plugins exist
- for(Track *track = new_edl->tracks->first; track; track = track->next)
- {
- for(int k = 0; k < track->plugin_set.total; k++)
- {
+// Do a check whether plugins exist
+ for( Track *track=new_edl->tracks->first; track; track=track->next ) {
+ for( int k=0; k<track->plugin_set.total; ++k ) {
PluginSet *plugin_set = track->plugin_set[k];
- for(Plugin *plugin = (Plugin*)plugin_set->first;
- plugin;
- plugin = (Plugin*)plugin->next)
- {
- if(plugin->plugin_type == PLUGIN_STANDALONE)
- {
+ for( Plugin *plugin = (Plugin*)plugin_set->first;
+ plugin; plugin = (Plugin*)plugin->next ) {
+ if( plugin->plugin_type != PLUGIN_STANDALONE ) continue;
// ok we need to find it in plugindb
- int plugin_found = 0;
-
- for(int j = 0; j < plugindb->size(); j++)
- {
- PluginServer *server = plugindb->get(j);
- if(server->title &&
- !strcasecmp(server->title, plugin->title) &&
- ((track->data_type == TRACK_AUDIO && server->audio) ||
- (track->data_type == TRACK_VIDEO && server->video)) &&
- (!server->transition))
- plugin_found = 1;
- }
-
- if (!plugin_found)
- {
- sprintf(string,
+ PluginServer *server =
+ scan_plugindb(plugin->title, track->data_type);
+ if( !server || server->transition ) {
+ sprintf(string,
_("The %s '%s' in file '%s' is not part of your installation of Cinelerra.\n"
"The project won't be rendered as it was meant and Cinelerra might crash.\n"),
- "effect", plugin->title,
- path);
- MainError::show_error(string);
- }
+ "effect", _(plugin->title), path);
+ MainError::show_error(string);
}
}
}
- for(Edit *edit = (Edit*)track->edits->first;
- edit;
- edit = (Edit*)edit->next)
- {
- if (edit->transition)
- {
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ if( !edit->transition ) continue;
// ok we need to find transition in plugindb
-
- int transition_found = 0;
- for(int j = 0; j < plugindb->size(); j++)
- {
- PluginServer *server = plugindb->get(j);
- if(server->title &&
- !strcasecmp(server->title, edit->transition->title) &&
- ((track->data_type == TRACK_AUDIO && server->audio) ||
- (track->data_type == TRACK_VIDEO && server->video)) &&
- (server->transition))
- transition_found = 1;
- }
-
- if (!transition_found)
- {
- sprintf(string,
+ PluginServer *server =
+ scan_plugindb(edit->transition->title, track->data_type);
+ if( !server || !server->transition ) {
+ sprintf(string,
_("The %s '%s' in file '%s' is not part of your installation of Cinelerra.\n"
"The project won't be rendered as it was meant and Cinelerra might crash.\n"),
- "transition", edit->transition->title,
- path);
- MainError::show_error(string);
- }
+ "transition", _(edit->transition->title), path);
+ MainError::show_error(string);
}
}
}
}
-void MWindow::init_shm()
+void MWindow::init_shm(const char *pfn, int64_t min)
{
+ int64_t result = 0;
// Fix shared memory
- FILE *fd = fopen("/proc/sys/kernel/shmmax", "w");
- if(fd) {
- fprintf(fd, "0x7fffffff");
+ FILE *fd = fopen(pfn, "r");
+ if( fd ) {
+ fscanf(fd, "%jd", &result);
fclose(fd);
+ if( result >= min ) return;
}
- fd = 0;
- fd = fopen("/proc/sys/kernel/shmmax", "r");
- if(!fd) {
- MainError::show_error("MWindow::init_shm: couldn't open /proc/sys/kernel/shmmax for reading.\n");
+ fd = fopen(pfn, "w");
+ if( !fd ) return;
+ fprintf(fd, "0x%jx", min);
+ fclose(fd);
+
+ fd = fopen(pfn, "r");
+ if( !fd ) {
+ eprintf(_("MWindow::init_shm: couldn't open %s for reading.\n"), pfn);
return;
}
- int64_t result = 0;
fscanf(fd, "%jd", &result);
fclose(fd);
- fd = 0;
- if(result < 0x7fffffff) {
- eprintf(_("MWindow::init_shm: /proc/sys/kernel/shmmax is %p.\n"
+ if( result < min ) {
+ eprintf(_("MWindow::init_shm: %s is %p.\n"
"you probably need to be root, or:\n"
- "as root, run: echo 0x7fffffff > /proc/sys/kernel/shmmax\n"
+ "as root, run: echo 0x%jx > %s\n"
"before trying to start cinelerra.\n"
- "It should be at least 0x7fffffff for Cinelerra.\n"), (void *)result);
+ "It should be at least 0x%jx for Cinelerra.\n"),
+ pfn, (void *)result, min, pfn, min);
}
}
check_language();
init_preferences();
if(splash_window)
- splash_window->operation->update(_("Initializing Plugins"));
+ splash_window->update_status(_("Initializing Plugins"));
init_plugins(this, preferences);
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"));
+ splash_window->update_status(_("Initializing GUI"));
if(debug) PRINT_TRACE
init_theme();
init_error();
if(splash_window)
- splash_window->operation->update(_("Initializing Fonts"));
+ splash_window->update_status(_("Initializing Fonts"));
char string[BCTEXTLEN];
strcpy(string, preferences->plugin_dir);
strcat(string, "/" FONT_SEARCHPATH);
BC_Resources::init_fontconfig(string);
if(debug) PRINT_TRACE
-// Initialize before too much else is running
-// Preferences & theme are required for building MPEG table of contents
-
// Default project created here
init_edl();
if(debug) PRINT_TRACE
&MWindowGUI::keyboard_listener);
hide_splash();
- init_shm();
+ init_shm("/proc/sys/kernel/shmmax", 0x7fffffff);
+ init_shm("/proc/sys/kernel/shmmni", 0x4000);
if(debug) PRINT_TRACE
BC_WindowBase::get_resources()->vframe_shm = 1;
sync_parameters(CHANGE_PARAMS);
}
-//void MWindow::set_titles(int value)
-//{
-// edl->session->show_titles = value;
-// trackmovement(edl->local_session->track_start);
-//}
-
void MWindow::set_screens(int value)
{
screens = value;
set_editing_mode(EDITING_ARROW, 0, 1);
}
+void MWindow::toggle_camera_xyz()
+{
+ gwindow->gui->lock_window("MWindow::toggle_camera_xyz");
+ gwindow->gui->toggle_camera_xyz();
+ gwindow->gui->unlock_window();
+}
+
+void MWindow::toggle_projector_xyz()
+{
+ gwindow->gui->lock_window("MWindow::toggle_projector_xyz");
+ gwindow->gui->toggle_projector_xyz();
+ gwindow->gui->unlock_window();
+}
void MWindow::set_labels_follow_edits(int value)
{
return 0;
}
-int MWindow::edl_to_nested(EDL *new_edl,
- EDL *nested_edl)
-{
-
-// Keep frame rate, sample rate, and output size unchanged.
-// These parameters would revert the project if VWindow displayed an asset
-// of different size than the project.
-
-
-
-// Nest all video & audio outputs
- new_edl->session->video_tracks = 1;
- new_edl->session->audio_tracks = nested_edl->session->audio_channels;
- new_edl->create_default_tracks();
-
-
-
- new_edl->insert_asset(0,
- nested_edl,
- 0,
- 0,
- 0);
-
- char string[BCTEXTLEN];
- FileSystem fs;
- fs.extract_name(string, nested_edl->path);
-//printf("MWindow::edl_to_nested %p %s\n", nested_edl, nested_edl->path);
-
- strcpy(new_edl->local_session->clip_title, string);
-
- return 0;
-}
// Reset everything after a load.
void MWindow::update_project(int load_mode)
const int debug = 0;
if(debug) PRINT_TRACE
- init_brender();
edl->tracks->update_y_pixels(theme);
if(debug) PRINT_TRACE
gui->update(1, 1, 1, 1, 1, 1, 1);
if(debug) PRINT_TRACE
gui->unlock_window();
+ init_brender();
cwindow->gui->lock_window("MWindow::update_project 1");
cwindow->update(0, 0, 1, 1, 1);
if( !vwindow->is_running() ) continue;
vwindow->close_window();
}
+ for( int i=0; i<edl->vwindow_edls.size(); ++i ) {
+ VWindow *vwindow = get_viewer(1, -1);
+ vwindow->change_source(i);
+ }
if(debug) PRINT_TRACE
select_zwindow(0);
- close_mixers();
+ close_mixers(0);
for( int i=0; i<edl->mixers.size(); ++i ) {
Mixer *mixer = edl->mixers[i];
asset->reset_audio();
}
asset->reset_video();
+ remove_asset_from_caches(asset);
// File file; // re-probe the asset
// file.open_file(preferences, asset, 1, 0);
}
FileXML file;
edl->optimize();
edl->set_path(session->filename);
- char backup_path[BCTEXTLEN];
+ char backup_path[BCTEXTLEN], backup_path1[BCTEXTLEN];
snprintf(backup_path, sizeof(backup_path), "%s/%s",
File::get_config_path(), BACKUP_FILE);
- edl->save_xml(&file, backup_path, 0, 0);
+ snprintf(backup_path1, sizeof(backup_path1), "%s/%s",
+ File::get_config_path(), BACKUP_FILE1);
+ rename(backup_path, backup_path1);
+ edl->save_xml(&file, backup_path);
file.terminate_string();
FileSystem fs;
fs.complete_path(backup_path);
save_backup();
}
+
+void MWindow::save_undo_data()
+{
+ char perpetual_path[BCTEXTLEN];
+ snprintf(perpetual_path, sizeof(perpetual_path), "%s/%s",
+ File::get_config_path(), PERPETUAL_FILE);
+ FILE *fp = fopen(perpetual_path,"w");
+ if( !fp ) return;
+ undo->save(fp);
+ fclose(fp);
+}
+
+void MWindow::load_undo_data()
+{
+ char perpetual_path[BCTEXTLEN];
+ snprintf(perpetual_path, sizeof(perpetual_path), "%s/%s",
+ File::get_config_path(), PERPETUAL_FILE);
+ FILE *fp = fopen(perpetual_path,"r");
+ if( !fp ) return;
+ undo->load(fp);
+ fclose(fp);
+}
+
+
+int MWindow::copy_target(const char *path, const char *target)
+{
+ int ifd = ::open(path, O_RDONLY);
+ if( ifd < 0 ) {
+ eprintf("Cannot open asset: %s", path);
+ return 1;
+ }
+ int ret = 0;
+ int ofd = ::open(target, O_CREAT+O_TRUNC+O_WRONLY, 0777);
+ if( ofd >= 0 ) {
+ struct stat st;
+ int64_t total_bytes = !fstat(ifd, &st) ? st.st_size : 0;
+ char progress_title[BCTEXTLEN];
+ sprintf(progress_title, _("Copying: %s\n"), target);
+ BC_ProgressBox progress(-1, -1, progress_title, total_bytes);
+
+ int64_t count = 0, len = -1;
+ int bfrsz = 0x100000;
+ uint8_t *bfr = new uint8_t[bfrsz];
+ while( (len=::read(ifd, bfr, bfrsz)) > 0 ) {
+ if( len != ::write(ofd, bfr, len) ) {
+ eprintf("Error writing: %s", target);
+ break;
+ }
+ if( progress.is_cancelled() ) {
+ ret = 1;
+ break;
+ }
+ progress.update(count += len, 1);
+ }
+ delete [] bfr;
+ ::close(ofd);
+
+ progress.stop_progress();
+ if( len < 0 ) {
+ eprintf("Error reading: %s", path);
+ ret = 1;
+ }
+ }
+ else
+ eprintf("Cannot create asset target: %s", target);
+ ::close(ifd);
+ return ret;
+}
+
+int MWindow::link_target(const char *real_path, const char *link_path, int relative)
+{
+ char target[BCTEXTLEN];
+ if( relative ) {
+ const char *bp = real_path, *cp = bp;
+ const char *lp = link_path, *np = lp;
+ char *tp = target, *ep = tp+sizeof(target)-1, lch;
+ while( *lp && *bp && (lch=*lp++) == *bp++ ) {
+ if( lch == '/' ) { np = lp; cp = bp; }
+ }
+ while( tp<ep && *np ) {
+ if( *np++ != '/' ) continue;
+ *tp++ = '.'; *tp++ = '.'; *tp++ = '/';
+ }
+ while( tp<ep && *cp ) *tp++ = *cp++;
+ *tp = 0;
+ }
+ else
+ strcpy(target, real_path);
+ if( symlink(target, link_path) ) {
+ eprintf("Cannot create symlink: %s", link_path);
+ return 1;
+ }
+ return 0;
+}
+
+void MWindow::save_project(const char *dir, int save_mode, int overwrite, int reload)
+{
+ char dir_path[BCTEXTLEN];
+ strcpy(dir_path, dir);
+ FileSystem fs;
+ fs.complete_path(dir_path);
+
+ struct stat st;
+ if( !stat(dir_path, &st) ) {
+ if( !S_ISDIR(st.st_mode) ) {
+ eprintf("Path exists and is not a directory\n%s", dir_path);
+ return;
+ }
+ }
+ else {
+ if( mkdir(dir_path, S_IRWXU | S_IRWXG | S_IRWXO) ) {
+ eprintf("Cannot create directory\n%s", dir_path);
+ return;
+ }
+ }
+ char *real_dir = realpath(dir_path, 0);
+ strcpy(dir_path, real_dir);
+ free(real_dir);
+
+ EDL *save_edl = new EDL;
+ save_edl->create_objects();
+ save_edl->copy_all(edl);
+
+ char progress_title[BCTEXTLEN];
+ sprintf(progress_title, _("Saving to %s:\n"), dir);
+ int total_assets = save_edl->assets->total();
+ MainProgressBar *progress = mainprogress->start_progress(progress_title, total_assets);
+ int ret = 0;
+ Asset *current = save_edl->assets->first;
+ for( int i=0; !ret && current; ++i, current=NEXT ) {
+ char *path = current->path;
+ if( ::stat(path, &st) ) {
+ eprintf("Asset not found: %s", path);
+ continue;
+ }
+ char *real_path = realpath(path, 0);
+ const char *cp = strrchr(path, '/'), *bp = !cp ? path : cp+1;
+ char link_path[BCTEXTLEN];
+ snprintf(link_path, sizeof(link_path), "%s/%s", dir_path, bp);
+ int skip = 0;
+ if( strcmp(real_path, link_path) ) {
+ if( !::lstat(link_path, &st) ) {
+ if( overwrite )
+ ::remove(link_path);
+ else
+ skip = 1;
+ }
+ }
+ else {
+ eprintf("copy/link to self, skippped: %s", path);
+ skip = 1;
+ }
+ if( !skip ) {
+ if( save_mode == SAVE_PROJECT_COPY ) {
+ if( copy_target(real_path, link_path) )
+ ret = 1;
+ }
+ else {
+ link_target(real_path, link_path,
+ save_mode == SAVE_PROJECT_RELLINK ? 1 : 0);
+ }
+ }
+ free(real_path);
+ strcpy(path, link_path);
+
+ if( progress->is_cancelled() ) break;
+ progress->update(i);
+ }
+
+ progress->stop_progress();
+ delete progress;
+
+ char *cp = strrchr(dir_path,'/');
+ char *bp = cp ? cp+1 : dir_path;
+ char filename[BCTEXTLEN];
+ snprintf(filename, sizeof(filename), "%s/%s.xml", dir_path, bp);
+ save_edl->set_path(filename);
+ FileXML file;
+ save_edl->save_xml(&file, filename);
+ file.terminate_string();
+
+ if( !file.write_to_file(filename) ) {
+ char string[BCTEXTLEN];
+ sprintf(string, _("\"%s\" %dC written"), filename, (int)strlen(file.string()));
+ gui->lock_window("SaveProject::run 2");
+ gui->show_message(string);
+ gui->unlock_window();
+ gui->mainmenu->add_load(filename);
+ }
+ else
+ eprintf(_("Couldn't open %s."), filename);
+
+ save_edl->remove_user();
+
+ if( reload ) {
+ gui->lock_window("MWindow::save_project");
+ ArrayList<char*> filenames;
+ filenames.append(filename);
+ load_filenames(&filenames, LOADMODE_REPLACE);
+ gui->unlock_window();
+ }
+}
+
+
static inline int gcd(int m, int n)
{
int r;
if( channels < 1 ) channels = 1;
if( channels > 6 ) channels = 6;
session->audio_tracks = session->audio_channels = channels;
- switch( channels ) {
- case 6:
- session->achannel_positions[0] = 90;
- session->achannel_positions[1] = 150;
- session->achannel_positions[2] = 30;
- session->achannel_positions[3] = 210;
- session->achannel_positions[4] = 330;
- session->achannel_positions[5] = 270;
- break;
- case 2:
- 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; }
- }
+
+ int *achannel_positions = preferences->channel_positions[session->audio_channels-1];
+ memcpy(&session->achannel_positions, achannel_positions, sizeof(session->achannel_positions));
remap_audio(MWindow::AUDIO_1_TO_1);
if( delete_tracks ) {