From: Good Guy Date: Wed, 18 Oct 2017 23:04:27 +0000 (-0600) Subject: merged hv7 mod X-Git-Url: https://cinelerra-gg.org/git/?a=commitdiff_plain;h=9d832a1fff11b11aaa1108c460690ed05e2bdc05;p=goodguy%2Fhistory.git merged hv7 mod --- diff --git a/cinelerra-5.1/Cinelerra_factory b/cinelerra-5.1/Cinelerra_factory new file mode 100644 index 00000000..97c2aa40 --- /dev/null +++ b/cinelerra-5.1/Cinelerra_factory @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cinelerra-5.1/Makefile.am b/cinelerra-5.1/Makefile.am index a6426923..70f4728f 100644 --- a/cinelerra-5.1/Makefile.am +++ b/cinelerra-5.1/Makefile.am @@ -31,7 +31,7 @@ export mkinstalldirs install_sh inst_sh # install to bin binstall: install-recursive - cp -a COPYING README models ffmpeg msg info tips bin/. + cp -a COPYING README models Cinelerra_factory ffmpeg msg info tips bin/. sed -e 's/\/$(WANT_CIN)/g' < image/cin.desktop \ > "bin/applications/$(WANT_CIN).desktop" cp -a image/cin.svg "bin/pixmaps/$(WANT_CIN)".svg @@ -49,7 +49,7 @@ cinstall: cd bin; $(inst_sh) "$(DESTDIR)$(WANT_CINLIB_DIR)" \ bdwrite cutads hveg2enc mpeg2enc mplex mplexlo cd bin; $(inst_sh) "$(DESTDIR)$(datadir)/$(WANT_CIN)" \ - COPYING README models ffmpeg msg info tips doc + COPYING README models Cinelerra_factory ffmpeg msg info tips doc cd bin/locale; $(inst_sh) "$(DESTDIR)$(localedir)" . cd bin/plugins; $(inst_sh) "$(DESTDIR)$(WANT_PLUGIN_DIR)" . cd bin/ladspa; $(inst_sh) "$(DESTDIR)$(WANT_LADSPA_DIR)" . diff --git a/cinelerra-5.1/Makefile.devel b/cinelerra-5.1/Makefile.devel index ae6c41e0..04a9fd7c 100644 --- a/cinelerra-5.1/Makefile.devel +++ b/cinelerra-5.1/Makefile.devel @@ -22,7 +22,7 @@ clean: install: for dir in $(SUBDIRS); do $(MAKE) -C $$dir install; done - cp -a COPYING README models ffmpeg msg info tips bin/. + cp -a COPYING README models Cinelerra_factory ffmpeg msg info tips bin/. for d in picon*; do cp -a $$d/. bin/plugins/$$d/.; done rebuild: diff --git a/cinelerra-5.1/cinelerra/Makefile b/cinelerra-5.1/cinelerra/Makefile index 6fe88355..bd59f62e 100644 --- a/cinelerra-5.1/cinelerra/Makefile +++ b/cinelerra-5.1/cinelerra/Makefile @@ -59,7 +59,6 @@ OBJS = \ $(OBJDIR)/channel.o \ $(OBJDIR)/channelpicker.o \ $(OBJDIR)/chantables.o \ - $(OBJDIR)/cicolors.o \ $(OBJDIR)/clipedit.o \ $(OBJDIR)/clippopup.o \ $(OBJDIR)/colorpicker.o \ @@ -230,6 +229,7 @@ OBJS = \ $(OBJDIR)/pluginvclient.o \ $(OBJDIR)/preferences.o \ $(OBJDIR)/preferencesthread.o \ + $(OBJDIR)/presets.o \ $(OBJDIR)/probeprefs.o \ $(OBJDIR)/proxy.o \ $(OBJDIR)/question.o \ diff --git a/cinelerra-5.1/cinelerra/aautomation.C b/cinelerra-5.1/cinelerra/aautomation.C index 0c167602..3b58cad6 100644 --- a/cinelerra-5.1/cinelerra/aautomation.C +++ b/cinelerra-5.1/cinelerra/aautomation.C @@ -21,7 +21,7 @@ #include "aautomation.h" #include "atrack.inc" -#include "colors.h" +#include "bccolors.h" #include "edl.h" #include "edlsession.h" #include "floatauto.h" diff --git a/cinelerra-5.1/cinelerra/adeviceprefs.C b/cinelerra-5.1/cinelerra/adeviceprefs.C index cff01da0..be7ba2c6 100644 --- a/cinelerra-5.1/cinelerra/adeviceprefs.C +++ b/cinelerra-5.1/cinelerra/adeviceprefs.C @@ -22,16 +22,19 @@ #include "adeviceprefs.h" #include "audioalsa.h" #include "audiodevice.inc" +#include "bcsignals.h" #include "bitspopup.h" #include "edl.h" #include "language.h" +#include "mwindow.h" #include "playbackconfig.h" #include "preferences.h" #include "preferencesthread.h" #include "recordconfig.h" +#include "theme.h" #include -#define DEVICE_H 50 +//#define DEVICE_H 50 ADevicePrefs::ADevicePrefs(int x, int y, PreferencesWindow *pwindow, PreferencesDialog *dialog, AudioOutConfig *out_config, AudioInConfig *in_config, int mode) @@ -141,7 +144,14 @@ int ADevicePrefs::initialize(int creation) int ADevicePrefs::get_h(int recording) { - return !recording ? DEVICE_H + 30 : DEVICE_H; + int margin = pwindow->mwindow->theme->widget_border; + int result = BC_Title::calculate_h(dialog, "X", MEDIUMFONT) + margin + + BC_TextBox::calculate_h(dialog, MEDIUMFONT, 1, 1); + if( !recording ) { + result += BC_CheckBox::calculate_h(dialog) + margin; + } + + return result; } int ADevicePrefs::delete_objects() @@ -261,6 +271,7 @@ int ADevicePrefs::create_oss_objs() { char *output_char = 0; int *output_int = 0; + int margin = pwindow->mwindow->theme->widget_border; int y1 = y; BC_Resources *resources = BC_WindowBase::get_resources(); @@ -279,7 +290,7 @@ int ADevicePrefs::create_oss_objs() break; } dialog->add_subwindow(oss_enable[i] = new OSSEnable(x1, y1 + 20, output_int)); - x1 += oss_enable[i]->get_w() + 5; + x1 += oss_enable[i]->get_w() + margin; #endif switch(mode) { case MODEPLAY: @@ -299,10 +310,10 @@ int ADevicePrefs::create_oss_objs() dialog->add_subwindow(path_title); } - oss_path[i] = new ADeviceTextBox(x1, y1 + 20, output_char); + oss_path[i] = new ADeviceTextBox( + x1, y1 + path_title->get_h() + margin, output_char); dialog->add_subwindow(oss_path[i]); - - x1 += oss_path[i]->get_w() + 5; + x1 += oss_path[i]->get_w() + margin; if(i == 0) { switch(mode) { case MODEPLAY: @@ -318,14 +329,15 @@ int ADevicePrefs::create_oss_objs() bits_title = new BC_Title(x1, y, _("Bits:"), MEDIUMFONT, resources->text_default); dialog->add_subwindow(bits_title); - oss_bits = new BitsPopup(dialog, x1, y1 + 20, output_int, - 0, 0, 0, 0, 1); + oss_bits = new BitsPopup(dialog, + x1, y1 + bits_title->get_h() + margin, + output_int, 0, 0, 0, 0, 1); oss_bits->create_objects(); } - x1 += oss_bits->get_w() + 5; - y1 += DEVICE_H; -break; // apparently, 'i' must be zero + x1 += oss_bits->get_w() + margin; +// y1 += DEVICE_H; + break; } return 0; @@ -336,16 +348,16 @@ int ADevicePrefs::create_alsa_objs() #ifdef HAVE_ALSA char *output_char = 0; int *output_int = 0; - int y1 = y; + int margin = pwindow->mwindow->theme->widget_border; BC_Resources *resources = BC_WindowBase::get_resources(); - int x1 = x + menu->get_w() + 5; + int x1 = x + menu->get_w() + margin; + int y1 = y; ArrayList *alsa_titles = new ArrayList; alsa_titles->set_array_delete(); AudioALSA::list_devices(alsa_titles, 0, mode); - alsa_drivers = new ArrayList; for(int i = 0; i < alsa_titles->total; i++) alsa_drivers->append(new BC_ListBoxItem(alsa_titles->values[i])); @@ -366,7 +378,9 @@ int ADevicePrefs::create_alsa_objs() path_title = new BC_Title(x1, y, _("Device:"), MEDIUMFONT, resources->text_default); dialog->add_subwindow(path_title); - alsa_device = new ALSADevice(dialog, x1, y1 + 20, output_char, alsa_drivers); + y1 += path_title->get_h() + margin; + alsa_device = new ALSADevice(dialog, + x1, y1, output_char, alsa_drivers); alsa_device->create_objects(); int x2 = x1; @@ -385,10 +399,12 @@ int ADevicePrefs::create_alsa_objs() bits_title = new BC_Title(x1, y, _("Bits:"), MEDIUMFONT, resources->text_default); dialog->add_subwindow(bits_title); - alsa_bits = new BitsPopup(dialog, x1, y1 + 20, output_int, 0, 0, 0, 0, 1); + y1 = y + bits_title->get_h() + margin; + alsa_bits = new BitsPopup(dialog, + x1, y1, output_int, 0, 0, 0, 0, 1); alsa_bits->create_objects(); - y1 += alsa_bits->get_h() + 20 + 5; + y1 += alsa_bits->get_h(); x1 = x2; if(mode == MODEPLAY) { @@ -615,15 +631,15 @@ ADriverMenu::~ADriverMenu() void ADriverMenu::create_objects() { +#ifdef HAVE_ALSA + add_item(new ADriverItem(this, AUDIO_ALSA_TITLE, AUDIO_ALSA)); +#endif + #ifdef HAVE_OSS add_item(new ADriverItem(this, AUDIO_OSS_TITLE, AUDIO_OSS)); add_item(new ADriverItem(this, AUDIO_OSS_ENVY24_TITLE, AUDIO_OSS_ENVY24)); #endif -#ifdef HAVE_ALSA - add_item(new ADriverItem(this, AUDIO_ALSA_TITLE, AUDIO_ALSA)); -#endif - #ifdef HAVE_ESOUND if(!do_input) add_item(new ADriverItem(this, AUDIO_ESOUND_TITLE, AUDIO_ESOUND)); #endif diff --git a/cinelerra-5.1/cinelerra/adeviceprefs.h b/cinelerra-5.1/cinelerra/adeviceprefs.h index 27126107..ebe5051f 100644 --- a/cinelerra-5.1/cinelerra/adeviceprefs.h +++ b/cinelerra-5.1/cinelerra/adeviceprefs.h @@ -50,7 +50,8 @@ public: ~ADevicePrefs(); void reset(); - static int get_h(int recording = 0); +// static int get_h(int recording = 0); + int get_h(int recording = 0); int update(AudioOutConfig *out_config); // creation - set if this is the first initialize of the object // to prevent file format from being overwritten diff --git a/cinelerra-5.1/cinelerra/asset.C b/cinelerra-5.1/cinelerra/asset.C index af87bdbb..bb56d8bf 100644 --- a/cinelerra-5.1/cinelerra/asset.C +++ b/cinelerra-5.1/cinelerra/asset.C @@ -134,6 +134,8 @@ int Asset::init_values() tiff_cmodel = 0; tiff_compression = 0; + mov_sphere = 0; + jpeg_sphere = 0; use_header = 1; id = EDL::next_id(); @@ -271,6 +273,10 @@ void Asset::copy_format(Asset *asset, int do_index) tiff_cmodel = asset->tiff_cmodel; tiff_compression = asset->tiff_compression; + + + mov_sphere = asset->mov_sphere; + jpeg_sphere = asset->jpeg_sphere; } int64_t Asset::get_index_offset(int channel) @@ -360,7 +366,9 @@ int Asset::equivalent(Asset &asset, int test_audio, int test_video, EDL *edl) interlace_fixmethod == asset.interlace_fixmethod && width == asset.width && height == asset.height && - !strcmp(vcodec, asset.vcodec)); + !strcmp(vcodec, asset.vcodec) && + mov_sphere == asset.mov_sphere && + jpeg_sphere == asset.jpeg_sphere); if(result && format == FILE_FFMPEG) result = !strcmp(ff_video_options, asset.ff_video_options) && ff_video_bitrate == asset.ff_video_bitrate && @@ -506,6 +514,8 @@ int Asset::read_video(FileXML *file) file->tag.get_property("VCODEC", vcodec); video_length = file->tag.get_property("VIDEO_LENGTH", (int64_t)0); + mov_sphere = file->tag.get_property("MOV_SPHERE", 0); + jpeg_sphere = file->tag.get_property("JPEG_SPHERE", 0); single_frame = file->tag.get_property("SINGLE_FRAME", (int64_t)0); interlace_autofixoption = file->tag.get_property("INTERLACE_AUTOFIX",0); @@ -661,6 +671,8 @@ int Asset::write_video(FileXML *file) file->tag.set_property("VCODEC", vcodec); file->tag.set_property("VIDEO_LENGTH", video_length); + file->tag.set_property("MOV_SPHERE", mov_sphere); + file->tag.set_property("JPEG_SPHERE", jpeg_sphere); file->tag.set_property("SINGLE_FRAME", single_frame); file->tag.set_property("INTERLACE_AUTOFIX", interlace_autofixoption); @@ -825,6 +837,8 @@ void Asset::load_defaults(BC_Hash *defaults, tiff_cmodel = GET_DEFAULT("TIFF_CMODEL", tiff_cmodel); tiff_compression = GET_DEFAULT("TIFF_COMPRESSION", tiff_compression); + mov_sphere = GET_DEFAULT("MOV_SPHERE", mov_sphere); + jpeg_sphere = GET_DEFAULT("JPEG_SPHERE", jpeg_sphere); boundaries(); } @@ -912,8 +926,16 @@ void Asset::save_defaults(BC_Hash *defaults, UPDATE_DEFAULT("EXR_COMPRESSION", exr_compression); UPDATE_DEFAULT("TIFF_CMODEL", tiff_cmodel); UPDATE_DEFAULT("TIFF_COMPRESSION", tiff_compression); + + + + UPDATE_DEFAULT("MOV_SPHERE", mov_sphere); + UPDATE_DEFAULT("JPEG_SPHERE", jpeg_sphere); } + + + if(do_bits) { UPDATE_DEFAULT("BITS", bits); @@ -978,6 +1000,7 @@ int Asset::dump(FILE *fp) video_data, layers, program, frame_rate, width, height, vcodec, aspect_ratio,string); fprintf(fp," video_length %jd repeat %d\n", video_length, single_frame); + printf(" mov_sphere=%d jpeg_sphere=%d\n", mov_sphere, jpeg_sphere); return 0; } diff --git a/cinelerra-5.1/cinelerra/asset.h b/cinelerra-5.1/cinelerra/asset.h index 4fa58aa4..871ab225 100644 --- a/cinelerra-5.1/cinelerra/asset.h +++ b/cinelerra-5.1/cinelerra/asset.h @@ -150,6 +150,7 @@ public: char vcodec[BCTEXTLEN]; // Length in frames +// -1 means a still photo int64_t video_length; @@ -226,6 +227,9 @@ public: int ac3_bitrate; +// Insert tag for spherical playback + int mov_sphere, jpeg_sphere; + // Image file sequences. Background rendering doesn't want to write a // sequence header but instead wants to start the sequence numbering at a certain // number. This ensures deletion of all the frames which aren't being used. diff --git a/cinelerra-5.1/cinelerra/assetpopup.C b/cinelerra-5.1/cinelerra/assetpopup.C index c153e3db..75c1bfa2 100644 --- a/cinelerra-5.1/cinelerra/assetpopup.C +++ b/cinelerra-5.1/cinelerra/assetpopup.C @@ -145,14 +145,13 @@ AssetPopupInfo::~AssetPopupInfo() int AssetPopupInfo::handle_event() { int cur_x, cur_y; - popup->gui->get_abs_cursor_xy(cur_x, cur_y, 0); - - if( mwindow->session->drag_assets->total ) { - mwindow->awindow->asset_edit->edit_asset( + popup->gui->get_abs_cursor_xy(cur_x, cur_y); + if( mwindow->session->drag_assets->size() ) { + AssetEdit *asset_edit = mwindow->awindow->get_asset_editor(); + asset_edit->edit_asset( mwindow->session->drag_assets->values[0], cur_x, cur_y); } - else - if( mwindow->session->drag_clips->total ) { + else if( mwindow->session->drag_clips->size() ) { popup->gui->awindow->clip_edit->edit_clip( mwindow->session->drag_clips->values[0], cur_x, cur_y); } diff --git a/cinelerra-5.1/cinelerra/atrack.C b/cinelerra-5.1/cinelerra/atrack.C index 9387ed9d..ed9df7b9 100644 --- a/cinelerra-5.1/cinelerra/atrack.C +++ b/cinelerra-5.1/cinelerra/atrack.C @@ -177,3 +177,15 @@ int ATrack::paste_derived(int64_t start, int64_t end, int64_t total_length, File return 0; } +void ATrack::deglitch(double position, + int edit_labels, int edit_plugins, int edit_autos) +{ + int64_t samples = to_units(position, 0); + edits->deglitch(samples); + if( edit_plugins ) { + for(int i = 0; i < plugin_set.size(); i++) { + plugin_set.get(i)->deglitch(samples); + } + } +} + diff --git a/cinelerra-5.1/cinelerra/atrack.h b/cinelerra-5.1/cinelerra/atrack.h index 010b3923..74a4d935 100644 --- a/cinelerra-5.1/cinelerra/atrack.h +++ b/cinelerra-5.1/cinelerra/atrack.h @@ -76,6 +76,10 @@ public: int modify_handles(int64_t oldposition, int64_t newposition, int currentend); + void deglitch(double position, + int edit_labels, + int edit_plugins, + int edit_autos); int64_t length(); // int get_dimensions(double &view_start, diff --git a/cinelerra-5.1/cinelerra/audioconfig.C b/cinelerra-5.1/cinelerra/audioconfig.C index 727bdb2c..44c5eabe 100644 --- a/cinelerra-5.1/cinelerra/audioconfig.C +++ b/cinelerra-5.1/cinelerra/audioconfig.C @@ -30,6 +30,28 @@ AudioConfig::AudioConfig() { + audio_in_driver = AUDIO_ALSA; + afirewire_in_port = 0; + afirewire_in_channel = 63; + strcpy(oss_in_device, "/dev/dsp"); + oss_in_channels = 2; + oss_in_bits = 16; + strcpy(esound_in_server, ""); + esound_in_port = 0; + + audio_out_driver = AUDIO_ALSA; + strpcy(oss_out_device, "/dev/dsp"); + oss_out_channels = 2; + oss_out_bits = 16; + strpcy(esound_out_server, ""); + esound_out_port = 0; + + audio_duplex_driver = AUDIO_ALSA; + strcpy(oss_duplex_device, "/dev/dsp"); + oss_duplex_channels = 2; + oss_duplex_bits = 16; + strcpy(esound_duplex_server, ""); + esound_duplex_port = 0; } AudioConfig::~AudioConfig() @@ -72,7 +94,7 @@ AudioConfig& AudioConfig::operator=(AudioConfig &that) int AudioConfig::load_defaults(BC_Hash *defaults) { - audio_in_driver = defaults->get("AUDIOINDRIVER", AUDIO_OSS); + audio_in_driver = defaults->get("AUDIOINDRIVER", AUDIO_ALSA); afirewire_in_port = defaults->get("AFIREWIRE_IN_PORT", 0); afirewire_in_channel = defaults->get("AFIREWIRE_IN_CHANNEL", 63); sprintf(oss_in_device, "/dev/dsp"); @@ -83,8 +105,8 @@ int AudioConfig::load_defaults(BC_Hash *defaults) defaults->get("ESOUND_IN_SERVER", esound_in_server); esound_in_port = defaults->get("ESOUND_IN_PORT", 0); - audio_out_driver = defaults->get("AUDIO_OUT_DRIVER", AUDIO_OSS); - audio_duplex_driver = defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_OSS); + audio_out_driver = defaults->get("AUDIO_OUT_DRIVER", AUDIO_ALSA); + audio_duplex_driver = defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_ALSA); sprintf(oss_out_device, "/dev/dsp"); defaults->get("OSS_OUT_DEVICE", oss_out_device); oss_out_channels = defaults->get("OUT_CHANNELS", 2); @@ -93,7 +115,7 @@ int AudioConfig::load_defaults(BC_Hash *defaults) defaults->get("ESOUND_OUT_SERVER", esound_out_server); esound_out_port = defaults->get("ESOUND_OUT_PORT", 0); - audio_duplex_driver = defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_OSS); + audio_duplex_driver = defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_ALSA); sprintf(oss_duplex_device, "/dev/dsp"); defaults->get("OSS_DUPLEX_DEVICE", oss_duplex_device); oss_duplex_channels = defaults->get("DUPLEX_CHANNELS", 2); diff --git a/cinelerra-5.1/cinelerra/automation.C b/cinelerra-5.1/cinelerra/automation.C index 1ce714fb..2a21dd4d 100644 --- a/cinelerra-5.1/cinelerra/automation.C +++ b/cinelerra-5.1/cinelerra/automation.C @@ -24,7 +24,7 @@ #include "autos.h" #include "atrack.inc" #include "bcsignals.h" -#include "colors.h" +#include "bccolors.h" #include "edl.h" #include "edlsession.h" #include "filexml.h" diff --git a/cinelerra-5.1/cinelerra/awindow.C b/cinelerra-5.1/cinelerra/awindow.C index 7e1f56f0..d5f3204c 100644 --- a/cinelerra-5.1/cinelerra/awindow.C +++ b/cinelerra-5.1/cinelerra/awindow.C @@ -35,7 +35,6 @@ AWindow::AWindow(MWindow *mwindow) this->mwindow = mwindow; current_folder[0] = 0; asset_remove = 0; - asset_edit = 0; clip_edit = 0; label_edit = 0; } @@ -49,8 +48,8 @@ AWindow::~AWindow() gui->unlock_window(); } Thread::join(); + asset_editors.remove_all_objects(); delete asset_remove; - delete asset_edit; delete label_edit; delete clip_edit; delete effect_tip; @@ -62,7 +61,6 @@ void AWindow::create_objects() gui->create_objects(); gui->async_update_assets(); asset_remove = new AssetRemoveThread(mwindow); - asset_edit = new AssetEdit(mwindow); clip_edit = new ClipEdit(mwindow, this, 0); label_edit = new LabelEdit(mwindow, this, 0); effect_tip = new EffectTipDialog(mwindow, this); @@ -78,6 +76,21 @@ int AWindow::load_defaults(BC_Hash *defaults) } +AssetEdit *AWindow::get_asset_editor() +{ + AssetEdit *asset_edit = 0; + for( int i=0; !asset_edit && irunning() ) asset_edit = thread; + } + if( !asset_edit ) { + asset_edit = new AssetEdit(mwindow); + asset_editors.append(asset_edit); + } + return asset_edit; +} + + void AWindow::run() { gui->run_window(); diff --git a/cinelerra-5.1/cinelerra/awindow.h b/cinelerra-5.1/cinelerra/awindow.h index e7003f9a..40410b53 100644 --- a/cinelerra-5.1/cinelerra/awindow.h +++ b/cinelerra-5.1/cinelerra/awindow.h @@ -22,6 +22,7 @@ #ifndef AWINDOW_H #define AWINDOW_H +#include "arraylist.h" #include "assetedit.inc" #include "assetremove.inc" #include "awindowgui.inc" @@ -42,6 +43,7 @@ public: void run(); void create_objects(); + AssetEdit *get_asset_editor(); int load_defaults(BC_Hash *defaults); int save_defaults(BC_Hash *defaults); @@ -49,7 +51,7 @@ public: AWindowGUI *gui; MWindow *mwindow; - AssetEdit *asset_edit; + ArrayList asset_editors; AssetRemoveThread *asset_remove; ClipEdit *clip_edit; LabelEdit *label_edit; diff --git a/cinelerra-5.1/cinelerra/awindowgui.C b/cinelerra-5.1/cinelerra/awindowgui.C index 5bca38f3..1267c001 100644 --- a/cinelerra-5.1/cinelerra/awindowgui.C +++ b/cinelerra-5.1/cinelerra/awindowgui.C @@ -1806,21 +1806,21 @@ int AWindowDeleteProject::handle_event() return 1; } -AWindowInfo::AWindowInfo(MWindow *mwindow, AWindowGUI *gui, int x, int y) - : BC_Button(x, y, mwindow->theme->infoasset_data) -{ - this->mwindow = mwindow; - this->gui = gui; - set_tooltip(_("Edit information on asset")); -} - -int AWindowInfo::handle_event() -{ - int cur_x, cur_y; - gui->get_abs_cursor_xy(cur_x, cur_y, 0); - gui->awindow->asset_edit->edit_asset(gui->selected_asset(), cur_x, cur_y); - return 1; -} +// AWindowInfo::AWindowInfo(MWindow *mwindow, AWindowGUI *gui, int x, int y) +// : BC_Button(x, y, mwindow->theme->infoasset_data) +// { +// this->mwindow = mwindow; +// this->gui = gui; +// set_tooltip(_("Edit information on asset")); +// } +// +// int AWindowInfo::handle_event() +// { +// int cur_x, cur_y; +// gui->get_abs_cursor_xy(cur_x, cur_y, 0); +// gui->awindow->asset_edit->edit_asset(gui->selected_asset(), cur_x, cur_y); +// return 1; +// } AWindowRedrawIndex::AWindowRedrawIndex(MWindow *mwindow, AWindowGUI *gui, int x, int y) : BC_Button(x, y, mwindow->theme->redrawindex_data) @@ -2021,4 +2021,3 @@ int AWindowListSort::handle_event() return 1; } - diff --git a/cinelerra-5.1/cinelerra/cachebase.C b/cinelerra-5.1/cinelerra/cachebase.C index 8e02543a..40b1e1bf 100644 --- a/cinelerra-5.1/cinelerra/cachebase.C +++ b/cinelerra-5.1/cinelerra/cachebase.C @@ -121,8 +121,8 @@ int CacheBase::delete_oldest() oldest = current; } if( oldest && oldest->position >= 0 ) { + result = oldest->get_size(); del_item(oldest); - result = 1; } lock->unlock(); return result; diff --git a/cinelerra-5.1/cinelerra/cachebase.h b/cinelerra-5.1/cinelerra/cachebase.h index ae37fbb4..a548891a 100644 --- a/cinelerra-5.1/cinelerra/cachebase.h +++ b/cinelerra-5.1/cinelerra/cachebase.h @@ -78,7 +78,8 @@ public: // Called when done with the item returned by get_. // Ignore if item was 0. void unlock(); -// delete oldest member, returns 1 if item deleted or 0 if none found +// Delete oldest item. +// Return number of bytes freed if successful. Return 0 if nothing to delete. int delete_oldest(); // Calculate current size of cache in bytes int64_t get_memory_usage(); diff --git a/cinelerra-5.1/cinelerra/canvas.C b/cinelerra-5.1/cinelerra/canvas.C index 72d8a906..e07dd339 100644 --- a/cinelerra-5.1/cinelerra/canvas.C +++ b/cinelerra-5.1/cinelerra/canvas.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams + * Copyright (C) 2008-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -332,8 +332,8 @@ void Canvas::get_transfers(EDL *edl, float &canvas_x1, float &canvas_y1, float &canvas_x2, float &canvas_y2, int canvas_w, int canvas_h) { -// printf("Canvas::get_transfers %d %d\n", canvas_w, -// canvas_h); +//printf("Canvas::get_transfers %d canvas_w=%d canvas_h=%d\n", +// __LINE__, canvas_w, canvas_h); // automatic canvas size detection if(canvas_w < 0) canvas_w = get_canvas()->get_w(); if(canvas_h < 0) canvas_h = get_canvas()->get_h(); @@ -430,6 +430,11 @@ void Canvas::get_transfers(EDL *edl, { out_h = (int)(out_w / edl->get_aspect_ratio() + 0.5); canvas_y1 = canvas_h / 2 - out_h / 2; +// printf("Canvas::get_transfers %d canvas_h=%d out_h=%f canvas_y1=%f\n", +// __LINE__, +// canvas_h, +// out_h, +// canvas_y1); } canvas_x2 = canvas_x1 + out_w; canvas_y2 = canvas_y1 + out_h; @@ -459,7 +464,8 @@ void Canvas::get_transfers(EDL *edl, canvas_y1 = MAX(0, canvas_y1); canvas_x2 = MAX(canvas_x1, canvas_x2); canvas_y2 = MAX(canvas_y1, canvas_y2); -// printf("Canvas::get_transfers 2 %f,%f %f,%f -> %f,%f %f,%f\n", +// printf("Canvas::get_transfers %d %f,%f %f,%f -> %f,%f %f,%f\n", +// __LINE__, // output_x1, // output_y1, // output_x2, @@ -853,8 +859,8 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame) if( refresh_frame && (refresh_frame->get_w() != device->out_w || - refresh_frame->get_h() != device->out_h || - refresh_frame->get_color_model() != best_color_model) ) { + refresh_frame->get_h() != device->out_h ) ) { +// x11 direct render uses BC_BGR8888, use tranfer_from to remap delete refresh_frame; refresh_frame = 0; } @@ -872,7 +878,7 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame) get_canvas()->lock_window(" Canvas::output_refresh"); } else - refresh_frame->copy_from(output_frame); + refresh_frame->transfer_from(output_frame); } diff --git a/cinelerra-5.1/cinelerra/channelinfo.C b/cinelerra-5.1/cinelerra/channelinfo.C index b96be4f3..a044338e 100644 --- a/cinelerra-5.1/cinelerra/channelinfo.C +++ b/cinelerra-5.1/cinelerra/channelinfo.C @@ -1773,9 +1773,10 @@ void ChannelInfo::delete_batch() } ChannelScan::ChannelScan(MWindow *mwindow) - : BC_MenuItem(_("Scan..."), _("Shift-S"), 'S') + : BC_MenuItem(_("Scan..."), _("Ctrl-Alt-s"), 's') { - set_shift(); + set_ctrl(); + set_alt(); this->mwindow = mwindow; } diff --git a/cinelerra-5.1/cinelerra/clippopup.C b/cinelerra-5.1/cinelerra/clippopup.C index 602fbbd0..2f9df23c 100644 --- a/cinelerra-5.1/cinelerra/clippopup.C +++ b/cinelerra-5.1/cinelerra/clippopup.C @@ -141,7 +141,8 @@ int ClipPopupInfo::handle_event() popup->gui->get_abs_cursor_xy(cur_x, cur_y, 0); if( mwindow->session->drag_assets->total ) { - mwindow->awindow->asset_edit->edit_asset( + AssetEdit *asset_edit = mwindow->awindow->get_asset_editor(); + asset_edit->edit_asset( mwindow->session->drag_assets->values[0], cur_x, cur_y); } else diff --git a/cinelerra-5.1/cinelerra/colorpicker.C b/cinelerra-5.1/cinelerra/colorpicker.C index 5c43fb93..a95f6ef3 100644 --- a/cinelerra-5.1/cinelerra/colorpicker.C +++ b/cinelerra-5.1/cinelerra/colorpicker.C @@ -21,6 +21,7 @@ #include "bcbutton.h" #include "bccapture.h" +#include "bccolors.h" #include "bcdisplayinfo.h" #include "colorpicker.h" #include "condition.h" @@ -28,7 +29,7 @@ #include "language.h" #include "mutex.h" #include "mwindow.h" -#include "cicolors.h" +#include "bccolors.h" #include "vframe.h" #include diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index 24a515fa..20eff120 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -604,7 +604,7 @@ int CWindowGUI::drag_stop() if(mwindow->session->drag_assets->total) { mwindow->gui->lock_window("CWindowGUI::drag_stop 1"); - mwindow->clear(0); + mwindow->clear(0, 1); mwindow->load_assets(mwindow->session->drag_assets, mwindow->edl->local_session->get_selectionstart(), LOADMODE_PASTE, @@ -619,7 +619,7 @@ int CWindowGUI::drag_stop() if(mwindow->session->drag_clips->total) { mwindow->gui->lock_window("CWindowGUI::drag_stop 2"); - mwindow->clear(0); + mwindow->clear(0, 1); mwindow->paste_edls(mwindow->session->drag_clips, LOADMODE_PASTE, mwindow->session->track_highlighted, @@ -2167,15 +2167,24 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) float blue = (float)*row++ / max; \ if(do_yuv) \ { \ - mwindow->edl->local_session->red += red + V_TO_R * (blue - 0.5); \ - mwindow->edl->local_session->green += red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \ - mwindow->edl->local_session->blue += red + U_TO_B * (green - 0.5); \ + float r = red + V_TO_R * (blue - 0.5); \ + float g = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \ + float b = red + U_TO_B * (green - 0.5); \ + mwindow->edl->local_session->red += r; \ + mwindow->edl->local_session->green += g; \ + mwindow->edl->local_session->blue += b; \ + if(r > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = r; \ + if(g > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = g; \ + if(b > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = b; \ } \ else \ { \ mwindow->edl->local_session->red += red; \ mwindow->edl->local_session->green += green; \ mwindow->edl->local_session->blue += blue; \ + if(red > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = red; \ + if(green > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = green; \ + if(blue > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = blue; \ } \ } @@ -2184,6 +2193,9 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) mwindow->edl->local_session->red = 0; mwindow->edl->local_session->green = 0; mwindow->edl->local_session->blue = 0; + mwindow->edl->local_session->red_max = 0; + mwindow->edl->local_session->green_max = 0; + mwindow->edl->local_session->blue_max = 0; for(int i = row1; i < row2; i++) { for(int j = column1; j < column2; j++) diff --git a/cinelerra-5.1/cinelerra/cwindowtool.C b/cinelerra-5.1/cinelerra/cwindowtool.C index d73a265b..73f1f232 100644 --- a/cinelerra-5.1/cinelerra/cwindowtool.C +++ b/cinelerra-5.1/cinelerra/cwindowtool.C @@ -1,7 +1,6 @@ - /* * CINELERRA - * Copyright (C) 2008-2014 Adam Williams + * Copyright (C) 2008-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +22,7 @@ #include #include "automation.h" -#include "cicolors.h" +#include "bccolors.h" #include "clip.h" #include "condition.h" #include "cpanel.h" @@ -461,7 +460,7 @@ void CWindowCropGUI::update() CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread) - : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 250) + : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 290) { } @@ -514,6 +513,8 @@ void CWindowEyedropGUI::create_objects() y = title6->get_y() + this->v->get_h() + 2*margin; add_subwindow(sample = new BC_SubWindow(x, y, 50, 50)); + y += sample->get_h() + margin; + add_subwindow(use_max = new CWindowEyedropCheckBox(mwindow, this, x, y)); update(); unlock_window(); } @@ -528,27 +529,28 @@ void CWindowEyedropGUI::update() radius->update((int64_t)mwindow->edl->session->eyedrop_radius); - float r = mwindow->edl->local_session->red; - float g = mwindow->edl->local_session->green; - float b = mwindow->edl->local_session->blue; - red->update(r); - green->update(g); - blue->update(b); + LocalSession *local_session = mwindow->edl->local_session; + int use_max = local_session->use_max; + float r = use_max ? local_session->red_max : local_session->red; + float g = use_max ? local_session->green_max : local_session->green; + float b = use_max ? local_session->blue_max : local_session->blue; + this->red->update(r); + this->green->update(g); + this->blue->update(b); + int rx = 255*r + 0.5; bclamp(rx,0,255); int gx = 255*g + 0.5; bclamp(gx,0,255); int bx = 255*b + 0.5; bclamp(bx,0,255); char rgb_text[BCSTRLEN]; sprintf(rgb_text, "#%02x%02x%02x", rx, gx, bx); rgb_hex->update(rgb_text); - + float y, u, v; - YUV::rgb_to_yuv_f(mwindow->edl->local_session->red, - mwindow->edl->local_session->green, - mwindow->edl->local_session->blue, - y, u, v); + YUV::rgb_to_yuv_f(r, g, b, y, u, v); this->y->update(y); this->u->update(u); u += 0.5; this->v->update(v); v += 0.5; + int yx = 255*y + 0.5; bclamp(yx,0,255); int ux = 255*u + 0.5; bclamp(ux,0,255); int vx = 255*v + 0.5; bclamp(vx,0,255); @@ -690,6 +692,23 @@ int CWindowCurveToggle::handle_event() } +CWindowEyedropCheckBox::CWindowEyedropCheckBox(MWindow *mwindow, + CWindowEyedropGUI *gui, int x, int y) + : BC_CheckBox(x, y, mwindow->edl->local_session->use_max, _("Use maximum")) +{ + this->mwindow = mwindow; + this->gui = gui; +} + +int CWindowEyedropCheckBox::handle_event() +{ + mwindow->edl->local_session->use_max = get_value(); + + gui->update(); + return 1; +} + + CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread) : CWindowToolGUI(mwindow, thread, diff --git a/cinelerra-5.1/cinelerra/cwindowtool.h b/cinelerra-5.1/cinelerra/cwindowtool.h index 651627e0..93610342 100644 --- a/cinelerra-5.1/cinelerra/cwindowtool.h +++ b/cinelerra-5.1/cinelerra/cwindowtool.h @@ -253,7 +253,7 @@ public: }; - +class CWindowEyedropCheckBox; class CWindowEyedropGUI : public CWindowToolGUI { public: @@ -266,12 +266,27 @@ public: BC_Title *current; CWindowCoord *radius; + CWindowEyedropCheckBox *use_max; BC_Title *red, *green, *blue, *y, *u, *v; BC_Title *rgb_hex, *yuv_hex; BC_SubWindow *sample; }; +class CWindowEyedropCheckBox : public BC_CheckBox +{ +public: + CWindowEyedropCheckBox(MWindow *mwindow, + CWindowEyedropGUI *gui, + int x, + int y); + + int handle_event(); + MWindow *mwindow; + CWindowEyedropGUI *gui; +}; + + class CWindowCameraGUI : public CWindowToolGUI { diff --git a/cinelerra-5.1/cinelerra/edit.C b/cinelerra-5.1/cinelerra/edit.C index 3658922d..d9f55ba7 100644 --- a/cinelerra-5.1/cinelerra/edit.C +++ b/cinelerra-5.1/cinelerra/edit.C @@ -713,13 +713,17 @@ int Edit::shift_end_out(int edit_mode, next->startproject += cut_length; next->startsource += cut_length; next->length -= cut_length; -//printf("Edit::shift_end_out 2 %d\n", cut_length); +//printf("Edit::shift_end_out %d cut_length=%d\n", __LINE__, cut_length); } else { +//printf("Edit::shift_end_out %d cut_length=%d next->length=%d\n", __LINE__, cut_length, next->length); cut_length = next->length; + next->startproject += next->length; + next->startsource += next->length; next->length = 0; length += cut_length; +//track->dump(); } } else diff --git a/cinelerra-5.1/cinelerra/edits.C b/cinelerra-5.1/cinelerra/edits.C index a8e668f8..4f54457b 100644 --- a/cinelerra-5.1/cinelerra/edits.C +++ b/cinelerra-5.1/cinelerra/edits.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams + * Copyright (C) 2008-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -768,7 +768,7 @@ int Edits::modify_handles(double oldposition, double newposition, int currentend else { // move end of edit out -//printf("Edits::modify_handle 6\n"); +//printf("Edits::modify_handle %d edit_mode=%d\n", __LINE__, edit_mode); current_edit->shift_end_out(edit_mode, track->to_units(newposition, 0), track->to_units(oldposition, 0), @@ -843,3 +843,124 @@ void Edits::shift_effects_recursive(int64_t position, int64_t length, int edit_a track->shift_effects(position, length, edit_autos); } +// only used for audio but also used for plugins which inherit from Edits +void Edits::deglitch(int64_t position) +{ +// range from the splice junk appears + int64_t threshold = (int64_t)((double)edl->session->sample_rate / + edl->session->frame_rate) / 2; + Edit *current = 0; + +// the last edit before the splice + Edit *edit1 = 0; + if(first) + { + for(current = first; current; current = NEXT) + { + if(current->startproject + current->length >= position - threshold) + { + edit1 = current; + break; + } + } + +// ignore if it ends after the splice + if(current && current->startproject + current->length >= position) + { + edit1 = 0; + } + } + +// the first edit after the splice + Edit *edit2 = 0; + if(last) + { + for(current = last; current; current = PREVIOUS) + { + if(current->startproject < position + threshold) + { + edit2 = current; + break; + } + } + + // ignore if it starts before the splice + if(current && current->startproject < position) + { + edit2 = 0; + } + } + + + + +// printf("Edits::deglitch %d position=%ld edit1=%p edit2=%p\n", __LINE__, +// position, +// edit1, +// edit2); +// delete junk between the edits + if(edit1 != edit2) + { + if(edit1 != 0) + { +// end the starting edit later + current = edit1->next; + while(current != 0 && + current != edit2 && + current->startproject < position) + { + Edit* next = NEXT; + + edit1->length += current->length; + remove(current); + + current = next; + } + } + + if(edit2 != 0) + { +// start the ending edit earlier + current = edit2->previous; + while(current != 0 && + current != edit1 && + current->startproject >= position) + { + Edit *previous = PREVIOUS; + + int64_t length = current->length; +//printf("Edits::deglitch %d length=%ld\n", __LINE__, length); + if(!edit2->silence() && + length > edit2->startsource) + { + length = edit2->startsource; + } + + // shift edit2 by using material from its source + edit2->startproject -= length; + edit2->startsource -= length; + // assume enough is at the end + edit2->length += length; + + // shift edit2 & its source earlier by remainder + if(length < current->length) + { + int64_t remainder = current->length - length; + edit2->startproject -= remainder; + // assume enough is at the end + edit2->length += remainder; + } + + remove(current); + + + current = previous; + } + } + } + +} + + + + diff --git a/cinelerra-5.1/cinelerra/edits.h b/cinelerra-5.1/cinelerra/edits.h index d35917c7..040c6bfa 100644 --- a/cinelerra-5.1/cinelerra/edits.h +++ b/cinelerra-5.1/cinelerra/edits.h @@ -123,6 +123,7 @@ public: int edit_plugins, int edit_autos, Edits *trim_edits); + void deglitch(int64_t position); virtual int optimize(); virtual int clone_derived(Edit* new_edit, Edit* old_edit) { return 0; } diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index d6810aa7..cd20a7b0 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -808,12 +808,23 @@ void EDL::set_outpoint(double position) } } +void EDL::deglitch(double position) +{ + if( !session->cursor_on_frames ) return; + Track *current_track = tracks->first; + for( ; current_track; current_track=current_track->next ) { + if( !current_track->record ) continue; + if( current_track->data_type != TRACK_AUDIO ) continue; + ATrack *atrack = (ATrack*)current_track; + atrack->deglitch(position, + session->labels_follow_edits, + session->plugins_follow_edits, + session->autos_follow_edits); + } +} -int EDL::clear(double start, - double end, - int clear_labels, - int clear_plugins, - int edit_autos) +int EDL::clear(double start, double end, + int clear_labels, int clear_plugins, int edit_autos) { if(start == end) { diff --git a/cinelerra-5.1/cinelerra/edl.h b/cinelerra-5.1/cinelerra/edl.h index 3b1d2253..45740cdf 100644 --- a/cinelerra-5.1/cinelerra/edl.h +++ b/cinelerra-5.1/cinelerra/edl.h @@ -189,6 +189,7 @@ public: int clear_labels, int clear_plugins, int edit_autos); + void deglitch(double position); // Insert the asset at a point in the EDL void insert_asset(Asset *asset, EDL *nested_edl, diff --git a/cinelerra-5.1/cinelerra/edl.inc b/cinelerra-5.1/cinelerra/edl.inc index 0b6f218a..337d4bd4 100644 --- a/cinelerra-5.1/cinelerra/edl.inc +++ b/cinelerra-5.1/cinelerra/edl.inc @@ -48,9 +48,9 @@ class EDL; #define EDIT_HANDLE_MODES 3 // Behavior for the edit handles based on mouse button -#define MOVE_ALL_EDITS 0 -#define MOVE_ONE_EDIT 1 -#define MOVE_NO_EDITS 2 +#define MOVE_ALL_EDITS 0 // default for left button +#define MOVE_ONE_EDIT 1 // default for middle button +#define MOVE_NO_EDITS 2 // default for right button #define MOVE_EDITS_DISABLED 3 // AWindow folders diff --git a/cinelerra-5.1/cinelerra/edlsession.C b/cinelerra-5.1/cinelerra/edlsession.C index 5876b919..d4c6df80 100644 --- a/cinelerra-5.1/cinelerra/edlsession.C +++ b/cinelerra-5.1/cinelerra/edlsession.C @@ -116,15 +116,15 @@ EDLSession::EDLSession(EDL *edl) record_write_length = 131072; record_realtime_toc = 1; - safe_regions = 0; + safe_regions = 0; sample_rate = 48000; - scrub_speed = 2.; - show_assets = 1; - show_titles = 1; + scrub_speed = 2.; + show_assets = 1; + show_titles = 1; test_playback_edits = 1; time_format = TIME_HMSF; - nudge_format = 1; - tool_window = 0; + nudge_format = 1; + tool_window = 0; for(int i = 0; i < MAXCHANNELS; i++) { vchannel_x[i] = 64*i; vchannel_y[i] = 0; @@ -133,13 +133,13 @@ EDLSession::EDLSession(EDL *edl) aconfig_in = new AudioInConfig; vconfig_in = new VideoInConfig; recording_format = new Asset; - video_every_frame = 0; - video_asynchronous = 0; + video_every_frame = 0; +// video_asynchronous = 0; video_tracks = 1; video_write_length = 30; - view_follows_playback = 1; - vwindow_meter = 0; - vwindow_zoom = 1.; + view_follows_playback = 1; + vwindow_meter = 0; + vwindow_zoom = 1.; playback_config = new PlaybackConfig; } @@ -159,7 +159,7 @@ int EDLSession::need_rerender(EDLSession *ptr) return ((playback_preload != ptr->playback_preload) || (interpolation_type != ptr->interpolation_type) || (video_every_frame != ptr->video_every_frame) || - (video_asynchronous != ptr->video_asynchronous) || +// (video_asynchronous != ptr->video_asynchronous) || (real_time_playback != ptr->real_time_playback) || (playback_software_position != ptr->playback_software_position) || (test_playback_edits != ptr->test_playback_edits) || @@ -167,7 +167,9 @@ int EDLSession::need_rerender(EDLSession *ptr) (decode_subtitles != ptr->decode_subtitles) || (subtitle_number != ptr->subtitle_number) || (interpolate_raw != ptr->interpolate_raw) || - (white_balance_raw != ptr->white_balance_raw)); + (white_balance_raw != ptr->white_balance_raw) || + (proxy_scale != ptr->proxy_scale) || + (proxy_use_scaler != ptr->proxy_use_scaler)); } void EDLSession::equivalent_output(EDLSession *session, double *result) @@ -328,7 +330,7 @@ int EDLSession::load_defaults(BC_Hash *defaults) } video_channels = defaults->get("VCHANNELS", video_channels); video_every_frame = defaults->get("VIDEO_EVERY_FRAME", 0); - video_asynchronous = defaults->get("VIDEO_ASYNCHRONOUS", 0); +// video_asynchronous = defaults->get("VIDEO_ASYNCHRONOUS", 0); video_tracks = defaults->get("VTRACKS", video_tracks); video_write_length = defaults->get("VIDEO_WRITE_LENGTH", 30); view_follows_playback = defaults->get("VIEW_FOLLOWS_PLAYBACK", 1); @@ -441,7 +443,7 @@ int EDLSession::save_defaults(BC_Hash *defaults) defaults->update("SAFE_REGIONS", safe_regions); defaults->update("SAMPLERATE", sample_rate); defaults->update("SCRUB_SPEED", scrub_speed); - defaults->update("SI_USEDURATION",si_useduration); + defaults->update("SI_USEDURATION",si_useduration); defaults->update("SI_DURATION",si_duration); defaults->update("SHOW_ASSETS", show_assets); defaults->update("SHOW_TITLES", show_titles); @@ -458,7 +460,7 @@ int EDLSession::save_defaults(BC_Hash *defaults) } defaults->update("VCHANNELS", video_channels); defaults->update("VIDEO_EVERY_FRAME", video_every_frame); - defaults->update("VIDEO_ASYNCHRONOUS", video_asynchronous); +// defaults->update("VIDEO_ASYNCHRONOUS", video_asynchronous); defaults->update("VTRACKS", video_tracks); defaults->update("VIDEO_WRITE_LENGTH", video_write_length); defaults->update("VIEW_FOLLOWS_PLAYBACK", view_follows_playback); @@ -723,7 +725,7 @@ int EDLSession::save_video_config(FileXML *file) file->tag.set_property("COLORMODEL", string); ilacemode_to_xmltext(string, interlace_mode); file->tag.set_property("INTERLACE_MODE",string); - file->tag.set_property("CHANNELS", video_channels); + file->tag.set_property("CHANNELS", video_channels); for(int i = 0; i < video_channels; i++) { sprintf(string, "VCHANNEL_X_%d", i); @@ -872,7 +874,7 @@ int EDLSession::copy(EDLSession *session) video_channels = session->video_channels; *vconfig_in = *session->vconfig_in; video_every_frame = session->video_every_frame; - video_asynchronous = session->video_asynchronous; +// video_asynchronous = session->video_asynchronous; video_tracks = session->video_tracks; video_write_length = session->video_write_length; view_follows_playback = session->view_follows_playback; diff --git a/cinelerra-5.1/cinelerra/edlsession.h b/cinelerra-5.1/cinelerra/edlsession.h index d5d610ee..89748b65 100644 --- a/cinelerra-5.1/cinelerra/edlsession.h +++ b/cinelerra-5.1/cinelerra/edlsession.h @@ -214,7 +214,7 @@ public: // play every frame int video_every_frame; // decode video asynchronously - int video_asynchronous; +// int video_asynchronous; int video_tracks; // number of frames to write to disk at a time during video recording. int video_write_length; diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index e031dcdb..1b4e100d 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -328,6 +328,8 @@ int FFStream::decode_activate() if( decoder->capabilities & AV_CODEC_CAP_DR1 ) avctx->flags |= CODEC_FLAG_EMU_EDGE; avcodec_parameters_to_context(avctx, st->codecpar); + if( !av_dict_get(copts, "threads", NULL, 0) ) + avctx->thread_count = ffmpeg->ff_cpus(); ret = avcodec_open2(avctx, decoder, &copts); } if( ret >= 0 ) { @@ -2001,6 +2003,8 @@ int FFMPEG::open_encoder(const char *type, const char *spec) av_dict_set(&sopts, "cin_bitrate", 0, 0); av_dict_set(&sopts, "cin_quality", 0, 0); + if( !av_dict_get(sopts, "threads", NULL, 0) ) + ctx->thread_count = ff_cpus(); ret = avcodec_open2(ctx, codec, &sopts); if( ret >= 0 ) { ret = avcodec_parameters_from_context(st->codecpar, ctx); @@ -2682,6 +2686,8 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled) } if( ret >= 0 ) { avcodec_parameters_to_context(avctx, st->codecpar); + if( !av_dict_get(copts, "threads", NULL, 0) ) + avctx->thread_count = ff_cpus(); ret = avcodec_open2(avctx, decoder, &copts); } av_dict_free(&copts); diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C index 0fb926b2..4b9c1be8 100644 --- a/cinelerra-5.1/cinelerra/file.C +++ b/cinelerra-5.1/cinelerra/file.C @@ -75,6 +75,7 @@ #include "samples.h" #include "vframe.h" +//static int temp_debug = 0; //suppress noref warning void *vorbis0_ov_callbacks[] = { &OV_CALLBACKS_DEFAULT, &OV_CALLBACKS_NOCLOSE, @@ -99,8 +100,10 @@ File::~File() format_completion->unlock(); } - if( temp_frame ) delete temp_frame; - + if( temp_frame ) { +//printf("File::~File %d temp_debug=%d\n", __LINE__, --temp_debug); + delete temp_frame; + } close_file(0); @@ -298,7 +301,6 @@ void File::set_white_balance_raw(int value) this->white_balance_raw = value; } - void File::set_cache_frames(int value) { // caching only done locally @@ -319,7 +321,7 @@ int File::purge_cache() int File::delete_oldest() { -// caching only done locally +// return the number of bytes freed return frame_cache->delete_oldest(); } @@ -474,8 +476,6 @@ int File::open_file(Preferences *preferences, this->wr = wr; file = 0; - if( debug ) printf("File::open_file %d\n", __LINE__); - if( debug ) printf("File::open_file %p %d\n", this, __LINE__); switch( this->asset->format ) { @@ -1113,14 +1113,7 @@ int File::read_frame(VFrame *frame, int is_thread) const int debug = 0; //printf("File::read_frame pos=%jd cache=%d 1frame=%d\n", // current_frame, use_cache, asset->single_frame); - if( debug ) PRINT_TRACE - -//printf("File::read_frame %d\n", __LINE__); - if( video_thread && !is_thread ) return video_thread->read_frame(frame); - -//printf("File::read_frame %d\n", __LINE__); - if( debug ) PRINT_TRACE if( !file ) return 1; if( debug ) PRINT_TRACE int result = 0; @@ -1128,6 +1121,7 @@ int File::read_frame(VFrame *frame, int is_thread) int advance_position = 1; int cache_active = use_cache || asset->single_frame ? 1 : 0; int64_t cache_position = !asset->single_frame ? current_frame : -1; + // Test cache if( cache_active && frame_cache->get_frame(frame, cache_position, current_layer, asset->frame_rate) ) { @@ -1138,8 +1132,9 @@ int File::read_frame(VFrame *frame, int is_thread) // Need temp else if( frame->get_color_model() != BC_COMPRESSED && (supported_colormodel != frame->get_color_model() || - frame->get_w() != asset->width || - frame->get_h() != asset->height) ) { + (!file->can_scale_input() && + (frame->get_w() != asset->width || + frame->get_h() != asset->height))) ) { // printf("File::read_frame %d\n", __LINE__); // Can't advance position here because it needs to be added to cache @@ -1150,14 +1145,8 @@ int File::read_frame(VFrame *frame, int is_thread) } } -// printf("File::read_frame %d\n", __LINE__); if( !temp_frame ) { - temp_frame = new VFrame(0, - -1, - asset->width, - asset->height, - supported_colormodel, - -1); + temp_frame = new VFrame(asset->width, asset->height, supported_colormodel); } // printf("File::read_frame %d\n", __LINE__); @@ -1191,10 +1180,7 @@ int File::read_frame(VFrame *frame, int is_thread) return 0; } -int File::can_copy_from(Asset *asset, - int64_t position, - int output_w, - int output_h) +int File::can_copy_from(Asset *asset, int64_t position, int output_w, int output_h) { if( asset && file ) { return asset->width == output_w && diff --git a/cinelerra-5.1/cinelerra/file.h b/cinelerra-5.1/cinelerra/file.h index 4d80870a..f62739e0 100644 --- a/cinelerra-5.1/cinelerra/file.h +++ b/cinelerra-5.1/cinelerra/file.h @@ -86,8 +86,9 @@ public: // to delete the file object. Otherwise we'd delete just the cached frames // while the list of open files grew. void set_cache_frames(int value); -// Delete frame cache. Return 0 if successful. Return 1 if -// nothing to delete. +// Delete oldest frame from cache. +// Return number of bytes freed if successful. +// Return 0 if nothing to delete. int purge_cache(); // Delete oldest frame from cache. Return 0 if successful. Return 1 if // nothing to delete. diff --git a/cinelerra-5.1/cinelerra/filebase.h b/cinelerra-5.1/cinelerra/filebase.h index 3555e1e2..1fc58c0b 100644 --- a/cinelerra-5.1/cinelerra/filebase.h +++ b/cinelerra-5.1/cinelerra/filebase.h @@ -127,6 +127,7 @@ public: virtual int colormodel_supported(int colormodel) { return BC_RGB888; } // This file can copy compressed frames directly from the asset virtual int can_copy_from(Asset *asset, int64_t position) { return 0; } + virtual int can_scale_input() { return 0; } virtual int get_render_strategy(ArrayList* render_strategies) { return VRENDER_VPIXEL; } // Manages an audio history buffer diff --git a/cinelerra-5.1/cinelerra/fileffmpeg.C b/cinelerra-5.1/cinelerra/fileffmpeg.C index 99fa7119..f3f53568 100644 --- a/cinelerra-5.1/cinelerra/fileffmpeg.C +++ b/cinelerra-5.1/cinelerra/fileffmpeg.C @@ -338,33 +338,13 @@ int FileFFMPEG::colormodel_supported(int colormodel) int FileFFMPEG::get_best_colormodel(Asset *asset, int driver) { switch(driver) { - case PLAYBACK_X11: - return BC_RGB888; - case PLAYBACK_X11_XV: - case PLAYBACK_ASYNCHRONOUS: - return BC_YUV888; - case PLAYBACK_X11_GL: - return BC_YUV888; - case PLAYBACK_DV1394: - case PLAYBACK_FIREWIRE: - return BC_YUV422P; - case VIDEO4LINUX2: - return BC_RGB888; - case VIDEO4LINUX2JPEG: - return BC_COMPRESSED; - case CAPTURE_DVB: - case VIDEO4LINUX2MPEG: - return BC_YUV422P; - case CAPTURE_JPEG_WEBCAM: - return BC_COMPRESSED; - case CAPTURE_YUYV_WEBCAM: - return BC_YUV422; - case CAPTURE_FIREWIRE: - case CAPTURE_IEC61883: - return BC_YUV422P; +// the direct X11 color model requires scaling in the codec + case PLAYBACK_X11: return BC_BGR8888; +// case PLAYBACK_X11: return BC_RGB888; + case PLAYBACK_X11_GL: return BC_RGB888; } - return BC_RGB888; + return BC_YUV420P; } int FileFFMPEG::can_render(const char *fformat, const char *type) diff --git a/cinelerra-5.1/cinelerra/fileffmpeg.h b/cinelerra-5.1/cinelerra/fileffmpeg.h index 51e19151..973cde15 100644 --- a/cinelerra-5.1/cinelerra/fileffmpeg.h +++ b/cinelerra-5.1/cinelerra/fileffmpeg.h @@ -50,6 +50,7 @@ public: int write_frames(VFrame ***frames,int len); int read_samples(double *buffer,int64_t len); int read_frame(VFrame *frame); + int can_scale_input() { return 1; } int64_t get_memory_usage(void); int colormodel_supported(int colormodel); static int get_best_colormodel(Asset *asset, int driver); diff --git a/cinelerra-5.1/cinelerra/filejpeg.C b/cinelerra-5.1/cinelerra/filejpeg.C index e3f57bb8..3abfa99f 100644 --- a/cinelerra-5.1/cinelerra/filejpeg.C +++ b/cinelerra-5.1/cinelerra/filejpeg.C @@ -163,6 +163,59 @@ int FileJPEG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit) frame->get_color_model(), 1); +// insert spherical tag + if(asset->jpeg_sphere) + { + const char *sphere_tag = + "http://ns.adobe.com/xap/1.0/\x00\n" + "\n" + "\n" + "\n" + " \n" + " equirectangular\n" + " \n" + "\n" + "\n" + ""; + +// calculate length by skipping the \x00 byte + int skip = 32; + int tag_len = strlen(sphere_tag + skip) + skip; + int tag_len2 = tag_len + 2; + int tag_len3 = tag_len + 4; + + data->allocate_compressed_data( + mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor) + tag_len3); + data->set_compressed_size( + mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor) + tag_len3); + + int jfif_size = 0x14; + uint8_t *ptr = data->get_data(); + memcpy(ptr, + mjpeg_output_buffer((mjpeg_t*)jpeg_unit->compressor), + jfif_size); + ptr += jfif_size; + *ptr++ = 0xff; + *ptr++ = 0xe1; + *ptr++ = (tag_len2 >> 8) & 0xff; + *ptr++ = tag_len2 & 0xff; + memcpy(ptr, + sphere_tag, + tag_len); + ptr += tag_len; + memcpy(ptr, + mjpeg_output_buffer((mjpeg_t*)jpeg_unit->compressor) + jfif_size, + mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor) - jfif_size); + } + else + { + data->allocate_compressed_data(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor)); + data->set_compressed_size(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor)); + memcpy(data->get_data(), + mjpeg_output_buffer((mjpeg_t*)jpeg_unit->compressor), + mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor)); + } data->allocate_compressed_data(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor)); data->set_compressed_size(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor)); memcpy(data->get_data(), @@ -295,7 +348,7 @@ JPEGConfigVideo::JPEGConfigVideo(BC_WindowBase *parent_window, Asset *asset) parent_window->get_abs_cursor_x(1), parent_window->get_abs_cursor_y(1), 400, - 100) + 200) { this->parent_window = parent_window; this->asset = asset; @@ -310,17 +363,13 @@ void JPEGConfigVideo::create_objects() int x = 10, y = 10; lock_window("JPEGConfigVideo::create_objects"); add_subwindow(new BC_Title(x, y, _("Quality:"))); - add_subwindow(new BC_ISlider(x + 80, - y, - 0, - 200, - 200, - 0, - 100, - asset->jpeg_quality, - 0, - 0, + BC_ISlider *slider; + add_subwindow(slider = new BC_ISlider(x + 80, y, + 0, 200, 200, 0, 100, asset->jpeg_quality, 0, 0, &asset->jpeg_quality)); + y += slider->get_h() + 10; + add_subwindow(new BC_CheckBox(x, y, + &asset->jpeg_sphere, _("Tag for spherical playback"))); add_subwindow(new BC_OKButton(this)); show_window(1); diff --git a/cinelerra-5.1/cinelerra/filelist.C b/cinelerra-5.1/cinelerra/filelist.C index 8f79da07..4614f3f8 100644 --- a/cinelerra-5.1/cinelerra/filelist.C +++ b/cinelerra-5.1/cinelerra/filelist.C @@ -296,7 +296,7 @@ int FileList::read_frame(VFrame *frame) FILE *in; -// Fix path for VFS +// Fix path for VFS. Not used anymore. if(!strncmp(asset->path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX))) sprintf(string, "%s%s", RENDERFARM_FS_PREFIX, path); else diff --git a/cinelerra-5.1/cinelerra/filempeg.C b/cinelerra-5.1/cinelerra/filempeg.C index 0526875b..8310942c 100644 --- a/cinelerra-5.1/cinelerra/filempeg.C +++ b/cinelerra-5.1/cinelerra/filempeg.C @@ -998,7 +998,9 @@ int FileMPEG::get_best_colormodel(Asset *asset, int driver) switch(driver) { case PLAYBACK_X11: - return BC_RGB888; +// return BC_RGB888; +// the direct X11 color model requires scaling in the codec + return BC_BGR8888; case PLAYBACK_X11_XV: case PLAYBACK_ASYNCHRONOUS: return zmpeg3_cmdl(asset->vmpeg_cmodel) > 0 ? diff --git a/cinelerra-5.1/cinelerra/filempeg.h b/cinelerra-5.1/cinelerra/filempeg.h index 0c870bd1..9b8db9dd 100644 --- a/cinelerra-5.1/cinelerra/filempeg.h +++ b/cinelerra-5.1/cinelerra/filempeg.h @@ -110,6 +110,7 @@ public: static const char *zmpeg3_cmdl_name(int cmdl); // This file can copy frames directly from the asset int can_copy_from(Asset *asset, int64_t position); + int can_scale_input() { return 1; } private: void to_streamchannel(int channel, int &stream_out, int &channel_out); diff --git a/cinelerra-5.1/cinelerra/formattools.C b/cinelerra-5.1/cinelerra/formattools.C index 60d0b6c2..7d94acdc 100644 --- a/cinelerra-5.1/cinelerra/formattools.C +++ b/cinelerra-5.1/cinelerra/formattools.C @@ -118,6 +118,7 @@ void FormatTools::create_objects( int x = init_x; int y = init_y; int ylev = init_y; + int margin = mwindow->theme->widget_border; this->locked_compressor = locked_compressor; this->recording = recording; @@ -179,10 +180,10 @@ void FormatTools::create_objects( x = init_x; window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:"))); - x += 90; + x += format_title->get_w() + margin; window->add_subwindow(format_text = new BC_TextBox(x, y, 160, 1, File::formattostr(asset->format))); - x += format_text->get_w(); + x += format_text->get_w() + margin; //printf("FormatTools::create_objects %d %p\n", __LINE__, window); window->add_subwindow(format_button = new FormatFormat(x, y, this)); format_button->create_objects(); @@ -194,14 +195,13 @@ void FormatTools::create_objects( format_ffmpeg->create_objects(); x = init_x; y += format_button->get_h() + 10; - if(do_audio) - { - window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT, BC_WindowBase::get_resources()->audiovideo_color)); - x += 80; + if( do_audio ) { + window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT, + BC_WindowBase::get_resources()->audiovideo_color)); + x += audio_title->get_w() + margin; window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y)); - x += aparams_button->get_w() + 10; - if(prompt_audio) - { + x += aparams_button->get_w() + margin; + if(prompt_audio) { window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data)); } x = init_x; @@ -225,30 +225,27 @@ void FormatTools::create_objects( } //printf("FormatTools::create_objects 7\n"); - if(do_video) - { - if(horizontal_layout && do_audio){ + if( do_video ) { + if( horizontal_layout && do_audio ) { x += 370; y = ylev; } //printf("FormatTools::create_objects 8\n"); - window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT, BC_WindowBase::get_resources()->audiovideo_color)); - x += 80; - if(prompt_video_compression) - { + window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT, + BC_WindowBase::get_resources()->audiovideo_color)); + x += video_title->get_w() + margin; + if(prompt_video_compression) { window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y)); - x += vparams_button->get_w() + 10; + x += vparams_button->get_w() + margin; } //printf("FormatTools::create_objects 9\n"); - if(prompt_video) - { + if(prompt_video) { window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data)); y += video_switch->get_h(); } - else - { + else { y += vparams_button->get_h(); } diff --git a/cinelerra-5.1/cinelerra/keyframe.C b/cinelerra-5.1/cinelerra/keyframe.C index 54b1612f..28ff8c6f 100644 --- a/cinelerra-5.1/cinelerra/keyframe.C +++ b/cinelerra-5.1/cinelerra/keyframe.C @@ -139,8 +139,7 @@ void KeyFrame::get_contents(BC_Hash *ptr, char **text, char **extra) } void KeyFrame::update_parameter(BC_Hash *params, - const char *text, - char *extra) + const char *text, const char *extra) { FileXML output; FileXML input; diff --git a/cinelerra-5.1/cinelerra/keyframe.h b/cinelerra-5.1/cinelerra/keyframe.h index d21ae125..29cdb3c5 100644 --- a/cinelerra-5.1/cinelerra/keyframe.h +++ b/cinelerra-5.1/cinelerra/keyframe.h @@ -66,9 +66,7 @@ public: // extra text in a newly allocated string void get_contents(BC_Hash *ptr, char **text, char **extra); // Update a single parameter or the anonymous text depending on which argument is nonzero - void update_parameter(BC_Hash *params, - const char *text, - char *extra); + void update_parameter(BC_Hash *params, const char *text, const char *extra); private: char data[MESSAGESIZE]; diff --git a/cinelerra-5.1/cinelerra/keyframegui.C b/cinelerra-5.1/cinelerra/keyframegui.C index 197ceed9..8e6019f0 100644 --- a/cinelerra-5.1/cinelerra/keyframegui.C +++ b/cinelerra-5.1/cinelerra/keyframegui.C @@ -1,27 +1,29 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams - * + * Copyright (C) 2017 Adam Williams + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #include "bchash.h" #include "bcsignals.h" #include "edl.h" +#include "file.h" +#include "filesystem.h" #include "keyframe.h" #include "keyframes.h" #include "keyframegui.h" @@ -33,6 +35,8 @@ #include "mwindow.h" #include "mwindowgui.h" #include "plugin.h" +#include "preferences.h" +#include "presets.h" #include "theme.h" #include "trackcanvas.h" #include "tracks.h" @@ -46,50 +50,59 @@ KeyFrameThread::KeyFrameThread(MWindow *mwindow) keyframe = 0; keyframe_data = new ArrayList[KEYFRAME_COLUMNS]; plugin_title[0] = 0; + is_factory = 0; + preset_text[0] = 0; window_title[0] = 0; - column_titles[0] = (char*)_("Parameter"); - column_titles[1] = (char*)_("Value"); + column_titles[0] = (char*)"Parameter"; + column_titles[1] = (char*)"Value"; column_width[0] = 0; column_width[1] = 0; + presets_data = new ArrayList; + presets_db = new PresetsDB; } KeyFrameThread::~KeyFrameThread() { - close_window(); - for(int i = 0; i < KEYFRAME_COLUMNS; i++) + for( int i=0; iremove_all_objects(); + delete presets_data; + is_factories.remove_all(); + preset_titles.remove_all_objects(); } +#ifdef EDIT_KEYFRAME void KeyFrameThread::update_values() { // Get the current selection before deleting the tables int selection = -1; - for(int i = 0; i < keyframe_data[0].size(); i++) { - if(keyframe_data[0].get(i)->get_selected()) { + for( int i=0; iget_selected() ) { selection = i; break; } } - for(int i = 0; i < KEYFRAME_COLUMNS; i++) + for( int i=0; igui->lock_window("KeyFrameThread::update_values"); - if(!plugin || !mwindow->edl->tracks->plugin_exists(plugin)) { + if( !plugin || !mwindow->edl->tracks->plugin_exists(plugin) ) { mwindow->gui->unlock_window(); return; } KeyFrame *keyframe = 0; - if(this->keyframe && plugin->keyframe_exists(this->keyframe)) { + if( this->keyframe && plugin->keyframe_exists(this->keyframe) ) { // If user edited a specific keyframe, use it. keyframe = this->keyframe; } - else if(plugin->track) { + else + if( plugin->track ) { // Use currently highlighted keyframe keyframe = plugin->get_prev_keyframe( plugin->track->to_units( @@ -97,43 +110,62 @@ void KeyFrameThread::update_values() PLAY_FORWARD); } - if(keyframe) { + if( keyframe ) { BC_Hash hash; - char *text = 0, *extra = 0; - keyframe->get_contents(&hash, &text, &extra); - - for(int i = 0; i < hash.size(); i++) - { + char *text = 0, *data = 0; + keyframe->get_contents(&hash, &text, &data); + + for( int i=0; isession->keyframedialog_column1; column_width[1] = mwindow->session->keyframedialog_column2; - if(selection >= 0 && selection < keyframe_data[0].size()) { - for(int i = 0; i < KEYFRAME_COLUMNS; i++) + if( selection >= 0 && selection < keyframe_data[0].size() ) { + for( int i=0; iset_selected(1); } mwindow->gui->unlock_window(); } +#endif void KeyFrameThread::start_window(Plugin *plugin, KeyFrame *keyframe) { - if(!BC_DialogThread::is_running()) { - if(!mwindow->edl->tracks->plugin_exists(plugin)) return; + if( !BC_DialogThread::is_running() ) { + if( !mwindow->edl->tracks->plugin_exists(plugin) ) return; this->keyframe = keyframe; this->plugin = plugin; plugin->calculate_title(plugin_title, 0); - sprintf(window_title, _(PROGRAM_NAME ": %s Keyframe"), plugin_title); + sprintf(window_title, PROGRAM_NAME ": %s Keyframe", plugin_title); + +// Load all the presets from disk + char path[BCTEXTLEN]; + FileSystem fs; +// system wide presets + sprintf(path, "%s/%s", File::get_cindat_path(), FACTORY_FILE); + fs.complete_path(path); + presets_db->load_from_file(path, 1, 1); +// user presets + sprintf(path, "%s/%s", File::get_config_path(), PRESETS_FILE); + fs.complete_path(path); + presets_db->load_from_file(path, 0, 0); + + calculate_preset_list(); + +#ifdef EDIT_KEYFRAME update_values(); +#endif mwindow->gui->unlock_window(); BC_DialogThread::start(); mwindow->gui->lock_window("KeyFrameThread::start_window"); @@ -146,24 +178,32 @@ void KeyFrameThread::start_window(Plugin *plugin, KeyFrame *keyframe) BC_Window* KeyFrameThread::new_gui() { mwindow->gui->lock_window("KeyFrameThread::new_gui"); - - int x = mwindow->gui->get_abs_cursor_x(0) - + + int x = mwindow->gui->get_abs_cursor_x(0) - mwindow->session->plugindialog_w / 2; - int y = mwindow->gui->get_abs_cursor_y(0) - + int y = mwindow->gui->get_abs_cursor_y(0) - mwindow->session->plugindialog_h / 2; - KeyFrameWindow *window = new KeyFrameWindow(mwindow, - this, x, y, window_title); - window->create_objects(); + KeyFrameWindow *window = new KeyFrameWindow(mwindow, + this, + x, + y, + window_title); + window->create_objects(); + + mwindow->gui->unlock_window(); + return window; } void KeyFrameThread::handle_done_event(int result) { - if( !result ) - apply_value(); +// Apply the preset + if( !result ) { + apply_preset(preset_text, is_factory); + } } void KeyFrameThread::handle_close_event(int result) @@ -172,85 +212,217 @@ void KeyFrameThread::handle_close_event(int result) keyframe = 0; } +void KeyFrameThread::close_window() +{ + lock_window("KeyFrameThread::close_window"); + if( get_gui() ) { + get_gui()->lock_window("KeyFrameThread::close_window"); + get_gui()->set_done(1); + get_gui()->unlock_window(); + } + unlock_window(); +} + + + +void KeyFrameThread::calculate_preset_list() +{ + presets_data->remove_all_objects(); + is_factories.remove_all(); + preset_titles.remove_all_objects(); + int total_presets = presets_db->get_total_presets(plugin_title, 0); + +// sort the list + presets_db->sort(plugin_title); + + for( int i=0; iget_preset_title( plugin_title, i); + if( !orig_title ) continue; + int is_factory = presets_db->get_is_factory(plugin_title, i); + sprintf(text, "%s%s", is_factory ? "*" : "", orig_title); + presets_data->append(new BC_ListBoxItem(text)); + + preset_titles.append(strdup(orig_title)); + is_factories.append(is_factory); + } +} + void KeyFrameThread::update_gui(int update_value_text) { - if(BC_DialogThread::is_running()) { +#ifdef EDIT_KEYFRAME + if( BC_DialogThread::is_running() ) { mwindow->gui->lock_window("KeyFrameThread::update_gui"); update_values(); mwindow->gui->unlock_window(); lock_window("KeyFrameThread::update_gui"); KeyFrameWindow *window = (KeyFrameWindow*)get_gui(); - if(window) { + if( window ) { window->lock_window("KeyFrameThread::update_gui"); window->keyframe_list->update(keyframe_data, - (const char **)column_titles, + column_titles, column_width, KEYFRAME_COLUMNS, window->keyframe_list->get_xposition(), window->keyframe_list->get_yposition(), window->keyframe_list->get_highlighted_item()); - if( update_value_text ) { - int selection_number = window->keyframe_list->get_selection_number(0, 0); - if( selection_number >= 0 && selection_number < keyframe_data[1].size()) { - char *edit_value = keyframe_data[1].get(selection_number)->get_text(); - window->value_text->update(edit_value); - } + if( update_value_text && + window->keyframe_list->get_selection_number(0, 0) >= 0 && + window->keyframe_list->get_selection_number(0, 0) < keyframe_data[1].size() ) { + window->value_text->update( + keyframe_data[1].get(window->keyframe_list->get_selection_number(0, 0))->get_text()); } window->unlock_window(); } unlock_window(); } +#endif +} + +void KeyFrameThread::save_preset(const char *title, int is_factory) +{ + get_gui()->unlock_window(); + mwindow->gui->lock_window("KeyFrameThread::save_preset"); + +// Test EDL for plugin existence + if( !mwindow->edl->tracks->plugin_exists(plugin) ) { + mwindow->gui->unlock_window(); + get_gui()->lock_window("KeyFrameThread::save_preset 2"); + return; + } + +// Get current plugin keyframe + EDL *edl = mwindow->edl; + Track *track = plugin->track; + KeyFrame *keyframe = plugin->get_prev_keyframe( + track->to_units(edl->local_session->get_selectionstart(1), 0), + PLAY_FORWARD); + +// Send to database + presets_db->save_preset(plugin_title, title, keyframe->get_data()); + + mwindow->gui->unlock_window(); + get_gui()->lock_window("KeyFrameThread::save_preset 2"); + +// Update list + calculate_preset_list(); + ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data, + 0, 0, 1); +} + +void KeyFrameThread::delete_preset(const char *title, int is_factory) +{ + get_gui()->unlock_window(); + mwindow->gui->lock_window("KeyFrameThread::save_preset"); + +// Test EDL for plugin existence + if( !mwindow->edl->tracks->plugin_exists(plugin) ) { + mwindow->gui->unlock_window(); + get_gui()->lock_window("KeyFrameThread::delete_preset 1"); + return; + } + + presets_db->delete_preset(plugin_title, title, is_factory); + + mwindow->gui->unlock_window(); + get_gui()->lock_window("KeyFrameThread::delete_preset 2"); + +// Update list + calculate_preset_list(); + ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data, + 0, 0, 1); } + +void KeyFrameThread::apply_preset(const char *title, int is_factory) +{ + if( presets_db->preset_exists(plugin_title, title, is_factory) ) { + get_gui()->unlock_window(); + mwindow->gui->lock_window("KeyFrameThread::apply_preset"); + +// Test EDL for plugin existence + if( !mwindow->edl->tracks->plugin_exists(plugin) ) { + mwindow->gui->unlock_window(); + get_gui()->lock_window("KeyFrameThread::apply_preset 1"); + return; + } + + mwindow->undo->update_undo_before(); + +#ifdef USE_KEYFRAME_SPANNING + KeyFrame keyframe; + presets_db->load_preset(plugin_title, title, &keyframe, is_factory); + plugin->keyframes->update_parameter(&keyframe); +#else + KeyFrame *keyframe = plugin->get_keyframe(); + presets_db->load_preset(plugin_title, title, keyframe, is_factory); +#endif + mwindow->save_backup(); + mwindow->undo->update_undo_after(_("apply preset"), LOAD_AUTOMATION); + + mwindow->update_plugin_guis(0); + mwindow->gui->draw_overlays(1); + mwindow->sync_parameters(CHANGE_PARAMS); + + + update_gui(1); + mwindow->gui->unlock_window(); + get_gui()->lock_window("KeyFrameThread::apply_preset"); + } +} + +#ifdef EDIT_KEYFRAME void KeyFrameThread::apply_value() { - const char *text = 0; - BC_Hash hash; + const char *text = 0, *data = 0; + BC_Hash *hash = 0; KeyFrameWindow *window = (KeyFrameWindow*)get_gui(); int selection = window->keyframe_list->get_selection_number(0, 0); //printf("KeyFrameThread::apply_value %d %d\n", __LINE__, selection); - if(selection < 0) return; - - if(selection == keyframe_data[0].size() - 1) + if( selection < 0 ) return; + + if( selection == keyframe_data[0].size() - 2 ) text = window->value_text->get_text(); + else if( selection == keyframe_data[0].size() - 1 ) + data = window->value_text->get_text(); else { - char *key = keyframe_data[0].get(selection)->get_text(); + const char *key = keyframe_data[0].get(selection)->get_text(); const char *value = window->value_text->get_text(); - hash.update(key, value); + hash = new BC_Hash(); + hash->update(key, value); } get_gui()->unlock_window(); mwindow->gui->lock_window("KeyFrameThread::apply_value"); - if(plugin && mwindow->edl->tracks->plugin_exists(plugin)) { + if( plugin && mwindow->edl->tracks->plugin_exists(plugin) ) { mwindow->undo->update_undo_before(); - if(mwindow->session->keyframedialog_all) { + if( mwindow->session->keyframedialog_all ) { // Search for all keyframes in selection but don't create a new one. Track *track = plugin->track; int64_t start = track->to_units(mwindow->edl->local_session->get_selectionstart(0), 0); int64_t end = track->to_units(mwindow->edl->local_session->get_selectionend(0), 0); int got_it = 0; - for(KeyFrame *current = (KeyFrame*)plugin->keyframes->last; - current; - current = (KeyFrame*)PREVIOUS) { + KeyFrame *current = (KeyFrame*)plugin->keyframes->last; + for( ; current; current=(KeyFrame*)PREVIOUS ) { got_it = 1; - if(current && current->position < end) { - current->update_parameter(&hash, text, 0); + if( current && current->position < end ) { + current->update_parameter(hash, text, data); // Stop at beginning of range - if(current->position <= start) break; + if( current->position <= start ) break; } } - if(!got_it) { - KeyFrame* keyframe = (KeyFrame*)plugin->keyframes->default_auto; - keyframe->update_parameter(&hash, text, 0); + if( !got_it ) { + current = (KeyFrame*)plugin->keyframes->default_auto; + current->update_parameter(hash, text, data); } } else { // Create new keyframe if enabled KeyFrame *keyframe = plugin->get_keyframe(); - keyframe->update_parameter(&hash, text, 0); + keyframe->update_parameter(hash, text, data); } } else { @@ -258,28 +430,37 @@ printf("KeyFrameThread::apply_value %d: plugin doesn't exist\n", __LINE__); } mwindow->save_backup(); - mwindow->undo->update_undo_after(_("edit keyframe"), LOAD_AUTOMATION); + mwindow->undo->update_undo_after(_("edit keyframe"), LOAD_AUTOMATION); mwindow->update_plugin_guis(0); mwindow->gui->draw_overlays(1); mwindow->sync_parameters(CHANGE_PARAMS); - - - mwindow->gui->unlock_window(); update_gui(0); get_gui()->lock_window("KeyFrameThread::apply_value"); + delete hash; } +#endif + KeyFrameWindow::KeyFrameWindow(MWindow *mwindow, - KeyFrameThread *thread, int x, int y, char *title_string) - : BC_Window(title_string, x, y, - mwindow->session->keyframedialog_w, - mwindow->session->keyframedialog_h, - 320, 240, 1, 0, 1) + KeyFrameThread *thread, + int x, + int y, + char *title_string) + : BC_Window(title_string, + x, + y, + mwindow->session->keyframedialog_w, + mwindow->session->keyframedialog_h, + 320, + 240, + 1, + 0, + 1) { this->mwindow = mwindow; this->thread = thread; @@ -294,29 +475,104 @@ void KeyFrameWindow::create_objects() thread->column_width[1] = mwindow->session->keyframedialog_column2; lock_window("KeyFrameWindow::create_objects"); +#ifdef EDIT_KEYFRAME + + add_subwindow(title1 = new BC_Title(theme->keyframe_list_x, - theme->keyframe_list_y - - BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) - + theme->keyframe_list_y - + BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) - theme->widget_border, - _("Keyframe parameters:"), LARGEFONT)); + _("Keyframe parameters:"), + LARGEFONT)); add_subwindow(keyframe_list = new KeyFrameList(thread, - this, theme->keyframe_list_x, theme->keyframe_list_y, - theme->keyframe_list_w, theme->keyframe_list_h)); + this, + theme->keyframe_list_x, + theme->keyframe_list_y, + theme->keyframe_list_w, + theme->keyframe_list_h)); +// add_subwindow(title2 = new BC_Title(theme->keyframe_text_x, +// theme->keyframe_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border, +// _("Global Text:"))); +// add_subwindow(keyframe_text = new KeyFrameText(thread, +// this, +// theme->keyframe_text_x, +// theme->keyframe_text_y, +// theme->keyframe_text_w)); add_subwindow(title3 = new BC_Title(theme->keyframe_value_x, theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border, _("Edit value:"))); add_subwindow(value_text = new KeyFrameValue(thread, - this, theme->keyframe_value_x, theme->keyframe_value_y, theme->keyframe_value_w)); + this, + theme->keyframe_value_x, + theme->keyframe_value_y, + theme->keyframe_value_w)); add_subwindow(all_toggle = new KeyFrameAll(thread, - this, theme->keyframe_all_x, theme->keyframe_all_y)); + this, + theme->keyframe_all_x, + theme->keyframe_all_y)); + +#endif + - add_subwindow(new KeyFrameParamsOK(thread, this)); + + add_subwindow(title4 = new BC_Title(theme->presets_list_x, + theme->presets_list_y - + BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) - + theme->widget_border, + _("Presets:"), + LARGEFONT)); + add_subwindow(preset_list = new KeyFramePresetsList(thread, + this, + theme->presets_list_x, + theme->presets_list_y, + theme->presets_list_w, + theme->presets_list_h)); + add_subwindow(title5 = new BC_Title(theme->presets_text_x, + theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border, + _("Preset title:"))); + add_subwindow(preset_text = new KeyFramePresetsText(thread, + this, + theme->presets_text_x, + theme->presets_text_y, + theme->presets_text_w)); + add_subwindow(delete_preset = new KeyFramePresetsDelete(thread, + this, + theme->presets_delete_x, + theme->presets_delete_y)); + add_subwindow(save_preset = new KeyFramePresetsSave(thread, + this, + theme->presets_save_x, + theme->presets_save_y)); + add_subwindow(apply_preset = new KeyFramePresetsApply(thread, + this, + theme->presets_apply_x, + theme->presets_apply_y)); + + + + + add_subwindow(new KeyFramePresetsOK(thread, this)); add_subwindow(new BC_CancelButton(this)); show_window(); unlock_window(); } +// called when going in & out of a factory preset +void KeyFrameWindow::update_editing() +{ + if( thread->is_factory ) { + delete_preset->disable(); + save_preset->disable(); + } + else { + delete_preset->enable(); + save_preset->enable(); + } +} + + + int KeyFrameWindow::resize_event(int w, int h) { Theme *theme = mwindow->theme; @@ -324,24 +580,74 @@ int KeyFrameWindow::resize_event(int w, int h) mwindow->session->keyframedialog_h = h; theme->get_keyframedialog_sizes(this); +#ifdef EDIT_KEYFRAME + title1->reposition_window(theme->keyframe_list_x, theme->keyframe_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border); +// title2->reposition_window(theme->keyframe_text_x, +// theme->keyframe_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border); title3->reposition_window(theme->keyframe_value_x, theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border); - keyframe_list->reposition_window(theme->keyframe_list_x, theme->keyframe_list_y, - theme->keyframe_list_w, theme->keyframe_list_h); - value_text->reposition_window(theme->keyframe_value_x, theme->keyframe_value_y, + keyframe_list->reposition_window(theme->keyframe_list_x, + theme->keyframe_list_y, + theme->keyframe_list_w, + theme->keyframe_list_h); +// text->reposition_window(theme->keyframe_text_x, +// theme->keyframe_text_y, +// theme->keyframe_text_w); + value_text->reposition_window(theme->keyframe_value_x, + theme->keyframe_value_y, theme->keyframe_value_w); - all_toggle->reposition_window(theme->keyframe_all_x, theme->keyframe_all_y); + all_toggle->reposition_window(theme->keyframe_all_x, + theme->keyframe_all_y); + +#endif // EDIT_KEYFRAME + + + + + title4->reposition_window(theme->presets_list_x, + theme->presets_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border); + title5->reposition_window(theme->presets_text_x, + theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border); + preset_list->reposition_window(theme->presets_list_x, + theme->presets_list_y, + theme->presets_list_w, + theme->presets_list_h); + preset_text->reposition_window(theme->presets_text_x, + theme->presets_text_y, + theme->presets_text_w); + delete_preset->reposition_window(theme->presets_delete_x, + theme->presets_delete_y); + save_preset->reposition_window(theme->presets_save_x, + theme->presets_save_y); + apply_preset->reposition_window(theme->presets_apply_x, + theme->presets_apply_y); return 0; } + + + +#ifdef EDIT_KEYFRAME + + KeyFrameList::KeyFrameList(KeyFrameThread *thread, - KeyFrameWindow *window, int x, int y, int w, int h) - : BC_ListBox(x, y, w, h, LISTBOX_TEXT, - thread->keyframe_data, (const char **)thread->column_titles, - thread->column_width, KEYFRAME_COLUMNS) + KeyFrameWindow *window, + int x, + int y, + int w, + int h) + : BC_ListBox(x, + y, + w, + h, + LISTBOX_TEXT, + thread->keyframe_data, + thread->column_titles, + thread->column_width, + KEYFRAME_COLUMNS) { this->thread = thread; this->window = window; @@ -368,9 +674,40 @@ int KeyFrameList::column_resize_event() } + + +// KeyFrameText::KeyFrameText(KeyFrameThread *thread, +// KeyFrameWindow *window, +// int x, +// int y, +// int w) +// : BC_TextBox(x, +// y, +// w, +// 1, +// "") +// { +// this->thread = thread; +// this->window = window; +// } +// +// int KeyFrameText::handle_event() +// { +// return 0; +// } + + + KeyFrameValue::KeyFrameValue(KeyFrameThread *thread, - KeyFrameWindow *window, int x, int y, int w) - : BC_TextBox(x, y, w, 1, "") + KeyFrameWindow *window, + int x, + int y, + int w) + : BC_TextBox(x, + y, + w, + 1, + (char*)"") { this->thread = thread; this->window = window; @@ -378,14 +715,21 @@ KeyFrameValue::KeyFrameValue(KeyFrameThread *thread, int KeyFrameValue::handle_event() { - thread->update_values(); + thread->apply_value(); return 0; } + + + KeyFrameAll::KeyFrameAll(KeyFrameThread *thread, - KeyFrameWindow *window, int x, int y) - : BC_CheckBox(x, y, thread->mwindow->session->keyframedialog_all, + KeyFrameWindow *window, + int x, + int y) + : BC_CheckBox(x, + y, + thread->mwindow->session->keyframedialog_all, _("Apply to all selected keyframes")) { this->thread = thread; @@ -398,18 +742,160 @@ int KeyFrameAll::handle_event() return 1; } -KeyFrameParamsOK::KeyFrameParamsOK(KeyFrameThread *thread, KeyFrameWindow *window) +#endif // EDIT_KEYFRAME + + + + + + + + + + +KeyFramePresetsList::KeyFramePresetsList(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y, + int w, + int h) + : BC_ListBox(x, + y, + w, + h, + LISTBOX_TEXT, + thread->presets_data) +{ + this->thread = thread; + this->window = window; +} + +int KeyFramePresetsList::selection_changed() +{ + int number = get_selection_number(0, 0); + if( number >= 0 ) { + strcpy(thread->preset_text, thread->preset_titles.get(number)); + thread->is_factory = thread->is_factories.get(number); +// show title without factory symbol in the textbox + window->preset_text->update( + thread->presets_data->get(number)->get_text()); + window->update_editing(); + } + + return 0; +} + +int KeyFramePresetsList::handle_event() +{ + thread->apply_preset(thread->preset_text, thread->is_factory); + window->set_done(0); + return 0; +} + + +KeyFramePresetsText::KeyFramePresetsText(KeyFrameThread *thread, + KeyFrameWindow *window, int x, int y, int w) + : BC_TextBox(x, y, w, 1, thread->preset_text) +{ + this->thread = thread; + this->window = window; +} + +// user entered a title +int KeyFramePresetsText::handle_event() +{ + strcpy(thread->preset_text, get_text()); +// once changed, it's now not a factory preset + thread->is_factory = 0; + window->update_editing(); + return 0; +} + + +KeyFramePresetsDelete::KeyFramePresetsDelete(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y) + : BC_GenericButton(x, y, _("Delete")) +{ + this->thread = thread; + this->window = window; +} + +int KeyFramePresetsDelete::handle_event() +{ + if( !thread->is_factory ) { + thread->delete_preset(thread->preset_text, thread->is_factory); + } + return 1; +} + + +KeyFramePresetsSave::KeyFramePresetsSave(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y) +: BC_GenericButton(x, y, _("Save")) +{ + this->thread = thread; + this->window = window; +} + +int KeyFramePresetsSave::handle_event() +{ + if( !thread->is_factory ) { + thread->save_preset(thread->preset_text, thread->is_factory); + } + return 1; +} + + + + + + + + +KeyFramePresetsApply::KeyFramePresetsApply(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y) + : BC_GenericButton(x, y, _("Apply")) +{ + this->thread = thread; + this->window = window; +} + +int KeyFramePresetsApply::handle_event() +{ + thread->apply_preset(thread->preset_text, thread->is_factory); + return 1; +} + + +KeyFramePresetsOK::KeyFramePresetsOK(KeyFrameThread *thread, + KeyFrameWindow *window) : BC_OKButton(window) { this->thread = thread; this->window = window; } -int KeyFrameParamsOK::keypress_event() +int KeyFramePresetsOK::keypress_event() { if( get_keypress() == RETURN ) { - thread->apply_value(); - return 1; +// Apply the preset + if( thread->presets_db->preset_exists(thread->plugin_title, + thread->preset_text, thread->is_factory) ) { + window->set_done(0); + return 1; + } + else { + if( !thread->is_factory ) { + thread->save_preset(thread->preset_text, thread->is_factory); + return 1; + } + } } return 0; } diff --git a/cinelerra-5.1/cinelerra/keyframegui.h b/cinelerra-5.1/cinelerra/keyframegui.h index 9f98c068..c6cdb85c 100644 --- a/cinelerra-5.1/cinelerra/keyframegui.h +++ b/cinelerra-5.1/cinelerra/keyframegui.h @@ -1,22 +1,22 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams - * + * Copyright (C) 2017 Adam Williams + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #ifndef KEYFRAMEGUI_H @@ -25,12 +25,17 @@ #include "bcdialog.h" #include "guicast.h" +#include "presets.inc" class KeyFrameWindow; + + #define KEYFRAME_COLUMNS 2 // Enable editing of detailed keyframe parameters. +#define EDIT_KEYFRAME + class KeyFrameThread : public BC_DialogThread { public: @@ -44,8 +49,13 @@ public: void handle_close_event(int result); void update_values(); void save_value(char *value); + void save_preset(const char *title, int is_factory); + void delete_preset(const char *title, int is_factory); + void apply_preset(const char *title, int is_factory); void apply_value(); + void calculate_preset_list(); void update_gui(int update_value_text = 1); + void close_window(); ArrayList *keyframe_data; Plugin *plugin; @@ -53,38 +63,134 @@ public: MWindow *mwindow; char window_title[BCTEXTLEN]; char plugin_title[BCTEXTLEN]; - char *column_titles[KEYFRAME_COLUMNS]; + +// the currently selected preset is a factory preset + int is_factory; +// title of the currently selected preset from the DB + char preset_text[BCTEXTLEN]; + + const char *column_titles[KEYFRAME_COLUMNS]; int column_width[KEYFRAME_COLUMNS]; +// list of preset text to display + ArrayList *presets_data; +// flag for each preset shown + ArrayList is_factories; +// title of each preset shown + ArrayList preset_titles; + PresetsDB *presets_db; }; +#ifdef EDIT_KEYFRAME + + class KeyFrameList : public BC_ListBox { public: KeyFrameList(KeyFrameThread *thread, - KeyFrameWindow *window, int x, int y, int w, int h); + KeyFrameWindow *window, + int x, + int y, + int w, + int h); int selection_changed(); int handle_event(); int column_resize_event(); KeyFrameThread *thread; KeyFrameWindow *window; }; +#endif -class KeyFrameParamList : public BC_ListBox +class KeyFramePresetsList : public BC_ListBox { public: - KeyFrameParamList(KeyFrameThread *thread, - KeyFrameWindow *window, int x, int y, int w, int h); + KeyFramePresetsList(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y, + int w, + int h); int selection_changed(); int handle_event(); KeyFrameThread *thread; KeyFrameWindow *window; }; +class KeyFramePresetsText : public BC_TextBox +{ +public: + KeyFramePresetsText(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y, + int w); + int handle_event(); + KeyFrameThread *thread; + KeyFrameWindow *window; +}; + + +class KeyFramePresetsDelete : public BC_GenericButton +{ +public: + KeyFramePresetsDelete(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y); + int handle_event(); + KeyFrameThread *thread; + KeyFrameWindow *window; +}; + +class KeyFramePresetsSave : public BC_GenericButton +{ +public: + KeyFramePresetsSave(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y); + int handle_event(); + KeyFrameThread *thread; + KeyFrameWindow *window; +}; + +class KeyFramePresetsApply : public BC_GenericButton +{ +public: + KeyFramePresetsApply(KeyFrameThread *thread, + KeyFrameWindow *window, + int x, + int y); + int handle_event(); + KeyFrameThread *thread; + KeyFrameWindow *window; +}; + +/* + * class KeyFrameText : public BC_TextBox + * { + * public: + * KeyFrameText(KeyFrameThread *thread, + * KeyFrameWindow *window, + * int x, + * int y, + * int w); + * int handle_event(); + * KeyFrameThread *thread; + * KeyFrameWindow *window; + * }; + */ + +#ifdef EDIT_KEYFRAME + + class KeyFrameValue : public BC_TextBox { public: KeyFrameValue(KeyFrameThread *thread, - KeyFrameWindow *window, int x, int y, int w); + KeyFrameWindow *window, + int x, + int y, + int w); int handle_event(); KeyFrameThread *thread; KeyFrameWindow *window; @@ -94,29 +200,42 @@ class KeyFrameAll : public BC_CheckBox { public: KeyFrameAll(KeyFrameThread *thread, - KeyFrameWindow *window, int x, int y); + KeyFrameWindow *window, + int x, + int y); int handle_event(); KeyFrameThread *thread; KeyFrameWindow *window; }; -class KeyFrameParamsOK : public BC_OKButton +#endif + + +class KeyFramePresetsOK : public BC_OKButton { public: - KeyFrameParamsOK(KeyFrameThread *thread, + KeyFramePresetsOK(KeyFrameThread *thread, KeyFrameWindow *window); int keypress_event(); KeyFrameThread *thread; KeyFrameWindow *window; }; + + class KeyFrameWindow : public BC_Window { public: KeyFrameWindow(MWindow *mwindow, - KeyFrameThread *thread, int x, int y, char *title); + KeyFrameThread *thread, + int x, + int y, + char *title); void create_objects(); int resize_event(int w, int h); + void update_editing(); + +#ifdef EDIT_KEYFRAME // List of parameters, values, & whether the parameter is defined by the current keyframe. KeyFrameList *keyframe_list; @@ -125,10 +244,34 @@ public: // Value text of the current parameter KeyFrameValue *value_text; KeyFrameAll *all_toggle; - BC_Title *title1, *title3; +#endif + + KeyFramePresetsList *preset_list; + KeyFramePresetsText *preset_text; + KeyFramePresetsDelete *delete_preset; + KeyFramePresetsSave *save_preset; + KeyFramePresetsApply *apply_preset; + +#ifdef EDIT_KEYFRAME + + BC_Title *title1; +// BC_Title *title2; + BC_Title *title3; +#endif + + BC_Title *title4; + BC_Title *title5; MWindow *mwindow; KeyFrameThread *thread; }; + + + #endif + + + + + diff --git a/cinelerra-5.1/cinelerra/localsession.C b/cinelerra-5.1/cinelerra/localsession.C index 5d8249fe..0008bcd3 100644 --- a/cinelerra-5.1/cinelerra/localsession.C +++ b/cinelerra-5.1/cinelerra/localsession.C @@ -104,6 +104,8 @@ LocalSession::LocalSession(EDL *edl) floatauto_type = FloatAuto::SMOOTH; red = green = blue = 0; + red_max = green_max = blue_max = 0; + use_max = 0; } LocalSession::~LocalSession() @@ -138,14 +140,17 @@ void LocalSession::copy_from(LocalSession *that) preview_end = that->preview_end; red = that->red; green = that->green; + blue = that->blue; + red_max = that->red_max; + green_max = that->green_max; + blue_max = that->blue_max; + use_max = that->use_max; for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) { automation_mins[i] = that->automation_mins[i]; automation_maxs[i] = that->automation_maxs[i]; } floatauto_type = that->floatauto_type; - - blue = that->blue; } void LocalSession::save_xml(FileXML *file, double start) @@ -192,6 +197,10 @@ void LocalSession::save_xml(FileXML *file, double start) file->tag.set_property("RED", red); file->tag.set_property("GREEN", green); file->tag.set_property("BLUE", blue); + file->tag.set_property("RED_MAX", red_max); + file->tag.set_property("GREEN_MAX", green_max); + file->tag.set_property("BLUE_MAX", blue_max); + file->tag.set_property("USE_MAX", use_max); for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) { if (!Automation::autogrouptypes_fixedrange[i]) { @@ -217,6 +226,9 @@ void LocalSession::synchronize_params(LocalSession *that) red = that->red; green = that->green; blue = that->blue; + red_max = that->red_max; + green_max = that->green_max; + blue_max = that->blue_max; } @@ -261,7 +273,10 @@ void LocalSession::load_xml(FileXML *file, unsigned long load_flags) red = file->tag.get_property("RED", red); green = file->tag.get_property("GREEN", green); blue = file->tag.get_property("BLUE", blue); - + red_max = file->tag.get_property("RED_MAX", red_max); + green_max = file->tag.get_property("GREEN_MAX", green_max); + blue_max = file->tag.get_property("BLUE_MAX", blue_max); + use_max = file->tag.get_property("USE_MAX", use_max); for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) { if (!Automation::autogrouptypes_fixedrange[i]) { @@ -310,6 +325,10 @@ int LocalSession::load_defaults(BC_Hash *defaults) red = defaults->get("RED", 0.0); green = defaults->get("GREEN", 0.0); blue = defaults->get("BLUE", 0.0); + red_max = defaults->get("RED_MAX", 0.0); + green_max = defaults->get("GREEN_MAX", 0.0); + blue_max = defaults->get("BLUE_MAX", 0.0); + use_max = defaults->get("USE_MAX", 0); for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) { if (!Automation::autogrouptypes_fixedrange[i]) { @@ -340,6 +359,10 @@ int LocalSession::save_defaults(BC_Hash *defaults) defaults->update("RED", red); defaults->update("GREEN", green); defaults->update("BLUE", blue); + defaults->update("RED_MAX", red_max); + defaults->update("GREEN_MAX", green_max); + defaults->update("BLUE_MAX", blue_max); + defaults->update("USE_MAX", use_max); for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) { if (!Automation::autogrouptypes_fixedrange[i]) { diff --git a/cinelerra-5.1/cinelerra/localsession.h b/cinelerra-5.1/cinelerra/localsession.h index 547fcb8a..e2ee664e 100644 --- a/cinelerra-5.1/cinelerra/localsession.h +++ b/cinelerra-5.1/cinelerra/localsession.h @@ -109,6 +109,8 @@ public: // Eye dropper float red, green, blue; + float red_max, green_max, blue_max; + int use_max; private: // The reason why selection ranges and inpoints have to be separate: // The selection position has to change to set new in points. diff --git a/cinelerra-5.1/cinelerra/mainclock.C b/cinelerra-5.1/cinelerra/mainclock.C index f03ac9d0..3fbbc576 100644 --- a/cinelerra-5.1/cinelerra/mainclock.C +++ b/cinelerra-5.1/cinelerra/mainclock.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 1997-2011 Adam Williams + * Copyright (C) 1997-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +27,8 @@ #include "theme.h" MainClock::MainClock(MWindow *mwindow, int x, int y, int w) - : BC_Title(x, y, "", MEDIUM_7SEGMENT, BLACK, 0, w) + : BC_Title(x, y, "", CLOCKFONT, //MEDIUM_7SEGMENT, + mwindow->theme->clock_fg_color, 0, w) { this->mwindow = mwindow; position_offset = 0; diff --git a/cinelerra-5.1/cinelerra/menueffects.C b/cinelerra-5.1/cinelerra/menueffects.C index bc089e7f..a0a661fd 100644 --- a/cinelerra-5.1/cinelerra/menueffects.C +++ b/cinelerra-5.1/cinelerra/menueffects.C @@ -516,7 +516,7 @@ void MenuEffectThread::run() mwindow->undo->update_undo_before("", 0); if(load_mode == LOADMODE_PASTE) - mwindow->clear(0); + mwindow->clear(0, 1); mwindow->load_assets(&assets, -1, load_mode, 0, 0, mwindow->edl->session->labels_follow_edits, diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index e700e71f..a7bd7e3d 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -316,7 +316,7 @@ public: // Clears active region in EDL. // If clear_handle, edit boundaries are cleared if the range is 0. // Called by paste, record, menueffects, render, and CWindow drop. - void clear(int clear_handle); + void clear(int clear_handle, int deglitch); void clear_labels(); int clear_labels(double start, double end); void concatenate_tracks(); diff --git a/cinelerra-5.1/cinelerra/mwindow.inc b/cinelerra-5.1/cinelerra/mwindow.inc index 48d26484..366236ff 100644 --- a/cinelerra-5.1/cinelerra/mwindow.inc +++ b/cinelerra-5.1/cinelerra/mwindow.inc @@ -26,7 +26,10 @@ #define DEFAULT_THEME "UnFlat" #define DEFAULT_PICON "cinfinity" #define CONFIG_FILE "Cinelerra_rc" +// user presets #define PRESETS_FILE "Cinelerra_presets" +// factory presets +#define FACTORY_FILE "Cinelerra_factory" #define PICTURE_FILE "Cinelerra_picture" #define PLUGIN_FILE "Cinelerra_plugins" #define LADSPA_FILE "ladspa_plugins." diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C index 0e4121b1..4e1c5c74 100644 --- a/cinelerra-5.1/cinelerra/mwindowedit.C +++ b/cinelerra-5.1/cinelerra/mwindowedit.C @@ -301,7 +301,7 @@ void MWindow::asset_to_rate() void MWindow::clear_entry() { undo->update_undo_before(); - clear(1); + clear(1, 1); edl->optimize(); save_backup(); @@ -315,7 +315,7 @@ void MWindow::clear_entry() send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1); } -void MWindow::clear(int clear_handle) +void MWindow::clear(int clear_handle, int deglitch) { double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); @@ -326,6 +326,12 @@ void MWindow::clear(int clear_handle) edl->session->plugins_follow_edits, edl->session->autos_follow_edits); } + +// always needed by paste operations + if(deglitch) + { + edl->deglitch(start); + } } void MWindow::set_automation_mode(int mode) @@ -525,6 +531,7 @@ void MWindow::cut(double start, double end, double new_position) edl->session->labels_follow_edits, edl->session->plugins_follow_edits, edl->session->autos_follow_edits); + edl->deglitch(start); edl->optimize(); @@ -862,15 +869,20 @@ void MWindow::finish_modify_handles() if( (session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) || (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT) ) { +//printf("MWindow::finish_modify_handles %d\n", __LINE__); edl->local_session->set_selectionstart(session->drag_position); edl->local_session->set_selectionend(session->drag_position); + edl->deglitch(session->drag_position); } else if( edit_mode != MOVE_NO_EDITS ) { +//printf("MWindow::finish_modify_handles %d\n", __LINE__); edl->local_session->set_selectionstart(session->drag_start); edl->local_session->set_selectionend(session->drag_start); + edl->deglitch(session->drag_start); } +// clamp the selection to 0 if( edl->local_session->get_selectionstart(1) < 0 ) { edl->local_session->set_selectionstart(0); edl->local_session->set_selectionend(0); @@ -1047,6 +1059,10 @@ void MWindow::mute_selection() edl->paste_silence(start, end, 0, edl->session->plugins_follow_edits, edl->session->autos_follow_edits); + edl->deglitch(start); + edl->deglitch(end); + + save_backup(); undo->update_undo_after(_("mute"), LOAD_EDITS); @@ -1108,7 +1124,7 @@ int MWindow::paste(double start, int edit_plugins, int edit_autos) { - clear(0); + clear(0, 1); // Want to insert with assets shared with the master EDL. insert(start, file, @@ -1131,7 +1147,7 @@ void MWindow::paste() gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); FileXML file; file.read_from_string(string); - clear(0); + clear(0, 1); insert(start, &file, edl->session->labels_follow_edits, @@ -1609,6 +1625,8 @@ void MWindow::paste_silence() edl->session->labels_follow_edits, edl->session->plugins_follow_edits, edl->session->autos_follow_edits); + edl->deglitch(start); + edl->deglitch(end); edl->optimize(); save_backup(); undo->update_undo_after(_("silence"), LOAD_EDITS | LOAD_TIMEBAR); @@ -2145,6 +2163,10 @@ void MWindow::trim_selection() edl->session->labels_follow_edits, edl->session->plugins_follow_edits, edl->session->autos_follow_edits); + edl->deglitch(0); + edl->deglitch(edl->local_session->get_selectionend() - + edl->local_session->get_selectionstart()); + save_backup(); undo->update_undo_after(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR); diff --git a/cinelerra-5.1/cinelerra/new.C b/cinelerra-5.1/cinelerra/new.C index 9f0c70d5..14df0a12 100644 --- a/cinelerra-5.1/cinelerra/new.C +++ b/cinelerra-5.1/cinelerra/new.C @@ -84,8 +84,7 @@ int New::handle_event() void New::create_new_edl() { - if(!new_edl) - { + if( !new_edl ) { new_edl = new EDL; new_edl->create_objects(); new_edl->load_defaults(mwindow->defaults); @@ -96,12 +95,9 @@ void New::create_new_edl() int New::create_new_project() { mwindow->cwindow->playback_engine->que->send_command(STOP, - CHANGE_NONE, - 0, - 0); + CHANGE_NONE, 0, 0); - for(int i = 0; i < mwindow->vwindows.size(); i++) - { + for( int i=0; ivwindows.size(); ++i ) { VWindow *vwindow = mwindow->vwindows.get(i); if( !vwindow->is_running() ) continue; vwindow->playback_engine->que->send_command(STOP, CHANGE_NONE, 0, 0); @@ -113,8 +109,6 @@ int New::create_new_project() mwindow->gui->lock_window(); mwindow->reset_caches(); - - memcpy(new_edl->session->achannel_positions, &mwindow->preferences->channel_positions[ MAXCHANNELS * (new_edl->session->audio_channels - 1)], @@ -152,8 +146,6 @@ NewThread::~NewThread() close_window(); } - - BC_Window* NewThread::new_gui() { mwindow->edl->save_defaults(mwindow->defaults); @@ -170,29 +162,22 @@ BC_Window* NewThread::new_gui() return nwindow; } - - void NewThread::handle_close_event(int result) { - if( !new_project->new_edl ) return; new_project->new_edl->save_defaults(mwindow->defaults); mwindow->defaults->save(); - if(result) - { + if( result ) { // Aborted if( !new_project->new_edl->Garbage::remove_user() ) new_project->new_edl = 0; } - else - { + else { new_project->create_new_project(); } } - - int NewThread::load_defaults() { auto_aspect = mwindow->defaults->get("AUTOASPECT", 0); @@ -207,8 +192,7 @@ int NewThread::save_defaults() int NewThread::update_aspect() { - if(auto_aspect) - { + if( auto_aspect ) { char string[BCTEXTLEN]; mwindow->create_aspect_ratio(new_project->new_edl->session->aspect_w, new_project->new_edl->session->aspect_h, @@ -223,8 +207,6 @@ int NewThread::update_aspect() } - - NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y) : BC_Window(_(PROGRAM_NAME ": New Project"), x, y, WIDTH, HEIGHT, -1, -1, 0, 0, 1) @@ -238,7 +220,7 @@ NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y) NewWindow::~NewWindow() { lock_window("NewWindow::~NewWindow"); - if(format_presets) delete format_presets; + if( format_presets ) delete format_presets; unlock_window(); } @@ -261,8 +243,6 @@ void NewWindow::create_objects() x = format_presets->x; y = format_presets->y; - - y += 40; y1 = y; add_subwindow(new BC_Title(x, y, _("Audio"), LARGEFONT)); @@ -365,10 +345,7 @@ void NewWindow::create_objects() add_subwindow(aspect_h_text = new NewAspectH(this, "", x1, y)); x1 += aspect_h_text->get_w(); add_subwindow(new AspectPulldown(mwindow, - aspect_w_text, - aspect_h_text, - x1, - y)); + aspect_w_text, aspect_h_text, x1, y)); x1 = aspect_w_text->get_x(); y += aspect_w_text->get_h() + 5; @@ -419,11 +396,6 @@ int NewWindow::update() } - - - - - NewPresets::NewPresets(MWindow *mwindow, NewWindow *gui, int x, int y) : FormatPresets(mwindow, gui, 0, x, y) { @@ -445,7 +417,6 @@ EDL* NewPresets::get_edl() } - NewATracks::NewATracks(NewWindow *nwindow, const char *text, int x, int y) : BC_TextBox(x, y, 90, 1, text) { @@ -478,6 +449,7 @@ int NewATracksTumbler::handle_down_event() return 1; } + NewAChannels::NewAChannels(NewWindow *nwindow, const char *text, int x, int y) : BC_TextBox(x, y, 90, 1, text) { @@ -490,6 +462,7 @@ int NewAChannels::handle_event() return 1; } + NewAChannelsTumbler::NewAChannelsTumbler(NewWindow *nwindow, int x, int y) : BC_Tumbler(x, y) { @@ -523,18 +496,10 @@ int NewSampleRate::handle_event() return 1; } + SampleRatePulldown::SampleRatePulldown(MWindow *mwindow, BC_TextBox *output, int x, int y) - : BC_ListBox(x, - y, - 100, - 200, - LISTBOX_TEXT, - &mwindow->theme->sample_rates, - 0, - 0, - 1, - 0, - 1) + : BC_ListBox(x, y, 100, 200, LISTBOX_TEXT, + &mwindow->theme->sample_rates, 0, 0, 1, 0, 1) { this->mwindow = mwindow; this->output = output; @@ -548,19 +513,6 @@ int SampleRatePulldown::handle_event() } - - - - - - - - - - - - - NewVTracks::NewVTracks(NewWindow *nwindow, const char *text, int x, int y) : BC_TextBox(x, y, 90, 1, text) { @@ -573,6 +525,7 @@ int NewVTracks::handle_event() return 1; } + NewVTracksTumbler::NewVTracksTumbler(NewWindow *nwindow, int x, int y) : BC_Tumbler(x, y) { @@ -593,6 +546,7 @@ int NewVTracksTumbler::handle_down_event() return 1; } + NewVChannels::NewVChannels(NewWindow *nwindow, const char *text, int x, int y) : BC_TextBox(x, y, 90, 1, text) { @@ -605,6 +559,7 @@ int NewVChannels::handle_event() return 1; } + NewVChannelsTumbler::NewVChannelsTumbler(NewWindow *nwindow, int x, int y) : BC_Tumbler(x, y) { @@ -625,6 +580,7 @@ int NewVChannelsTumbler::handle_down_event() return 1; } + NewFrameRate::NewFrameRate(NewWindow *nwindow, const char *text, int x, int y) : BC_TextBox(x, y, 90, 1, text) { @@ -637,21 +593,11 @@ int NewFrameRate::handle_event() return 1; } + FrameRatePulldown::FrameRatePulldown(MWindow *mwindow, - BC_TextBox *output, - int x, - int y) - : BC_ListBox(x, - y, - 100, - 200, - LISTBOX_TEXT, - &mwindow->theme->frame_rates, - 0, - 0, - 1, - 0, - 1) + BC_TextBox *output, int x, int y) + : BC_ListBox(x, y, 150, 250, LISTBOX_TEXT, + &mwindow->theme->frame_rates, 0, 0, 1, 0, 1) { this->mwindow = mwindow; this->output = output; @@ -665,26 +611,15 @@ int FrameRatePulldown::handle_event() } FrameSizePulldown::FrameSizePulldown(Theme *theme, - BC_TextBox *output_w, - BC_TextBox *output_h, - int x, - int y) - : BC_ListBox(x, - y, - 100, - 250, - LISTBOX_TEXT, - &theme->frame_sizes, - 0, - 0, - 1, - 0, - 1) + BC_TextBox *output_w, BC_TextBox *output_h, int x, int y) + : BC_ListBox(x, y, 150, 250, LISTBOX_TEXT, + &theme->frame_sizes, 0, 0, 1, 0, 1) { this->theme = theme; this->output_w = output_w; this->output_h = output_h; } + int FrameSizePulldown::handle_event() { char *text = get_selection(0, 0)->get_text(); @@ -694,8 +629,7 @@ int FrameSizePulldown::handle_event() strcpy(string, text); ptr = strrchr(string, 'x'); - if(ptr) - { + if( ptr ) { ptr++; h = atol(ptr); @@ -709,6 +643,7 @@ int FrameSizePulldown::handle_event() return 1; } + NewOutputW::NewOutputW(NewWindow *nwindow, int x, int y) : BC_TextBox(x, y, 70, 1, nwindow->new_edl->session->output_w) { @@ -721,6 +656,7 @@ int NewOutputW::handle_event() return 1; } + NewOutputH::NewOutputH(NewWindow *nwindow, int x, int y) : BC_TextBox(x, y, 70, 1, nwindow->new_edl->session->output_h) { @@ -733,6 +669,7 @@ int NewOutputH::handle_event() return 1; } + NewAspectW::NewAspectW(NewWindow *nwindow, const char *text, int x, int y) : BC_TextBox(x, y, 70, 1, text) { @@ -745,6 +682,7 @@ int NewAspectW::handle_event() return 1; } + NewAspectH::NewAspectH(NewWindow *nwindow, const char *text, int x, int y) : BC_TextBox(x, y, 70, 1, text) { @@ -757,27 +695,17 @@ int NewAspectH::handle_event() return 1; } + AspectPulldown::AspectPulldown(MWindow *mwindow, - BC_TextBox *output_w, - BC_TextBox *output_h, - int x, - int y) - : BC_ListBox(x, - y, - 100, - 200, - LISTBOX_TEXT, - &mwindow->theme->aspect_ratios, - 0, - 0, - 1, - 0, - 1) + BC_TextBox *output_w, BC_TextBox *output_h, int x, int y) + : BC_ListBox(x, y, 100, 200, LISTBOX_TEXT, + &mwindow->theme->aspect_ratios, 0, 0, 1, 0, 1) { this->mwindow = mwindow; this->output_w = output_w; this->output_h = output_h; } + int AspectPulldown::handle_event() { char *text = get_selection(0, 0)->get_text(); @@ -787,8 +715,7 @@ int AspectPulldown::handle_event() strcpy(string, text); ptr = strrchr(string, ':'); - if(ptr) - { + if( ptr ) { ptr++; h = atof(ptr); @@ -802,6 +729,7 @@ int AspectPulldown::handle_event() return 1; } + ColormodelItem::ColormodelItem(const char *text, int value) : BC_ListBoxItem(text) { @@ -809,21 +737,9 @@ ColormodelItem::ColormodelItem(const char *text, int value) } ColormodelPulldown::ColormodelPulldown(MWindow *mwindow, - BC_TextBox *output_text, - int *output_value, - int x, - int y) - : BC_ListBox(x, - y, - 200, - 150, - LISTBOX_TEXT, - (ArrayList*)&mwindow->colormodels, - 0, - 0, - 1, - 0, - 1) + BC_TextBox *output_text, int *output_value, int x, int y) + : BC_ListBox(x, y, 200, 150, LISTBOX_TEXT, + (ArrayList*)&mwindow->colormodels, 0, 0, 1, 0, 1) { this->mwindow = mwindow; this->output_text = output_text; @@ -840,8 +756,8 @@ int ColormodelPulldown::handle_event() const char* ColormodelPulldown::colormodel_to_text() { - for(int i = 0; i < mwindow->colormodels.total; i++) - if(mwindow->colormodels.values[i]->value == *output_value) + for( int i=0; icolormodels.total; ++i ) + if( mwindow->colormodels.values[i]->value == *output_value ) return mwindow->colormodels.values[i]->get_text(); return _("Unknown"); } @@ -910,12 +826,6 @@ int NewAspectAuto::handle_event() } - - - - - - NewSwapExtents::NewSwapExtents(MWindow *mwindow, NewWindow *gui, int x, int y) : BC_Button(x, y, mwindow->theme->get_image_set("swap_extents")) { @@ -936,6 +846,3 @@ int NewSwapExtents::handle_event() return 1; } - - - diff --git a/cinelerra-5.1/cinelerra/packagerenderer.C b/cinelerra-5.1/cinelerra/packagerenderer.C index 178082a4..e0508099 100644 --- a/cinelerra-5.1/cinelerra/packagerenderer.C +++ b/cinelerra-5.1/cinelerra/packagerenderer.C @@ -158,15 +158,8 @@ void PackageRenderer::create_output() strncpy(asset->path, package->path, sizeof(asset->path)); file = new File; - file->set_processors(preferences->processors); - -//printf("PackageRenderer::create_output %d\n", __LINE__); - result = file->open_file(preferences, - asset, - 0, - 1); -//printf("PackageRenderer::create_output %d %d\n", __LINE__, result); + result = file->open_file(preferences, asset, 0, 1); if(result && mwindow) { @@ -251,7 +244,12 @@ void PackageRenderer::create_engine() direct_frame_copying = 0; -//printf("PackageRenderer::create_engine %d\n", __LINE__); +//printf("PackageRenderer::create_engine %d video_write_length=%d\n", __LINE__, video_write_length); +// starting frames are corrupted if video_write_length > 2. Work around it, for now. + if(video_write_length > 2) + { + video_write_length = 2; + } file->start_video_thread(video_write_length, command->get_edl()->session->color_model, preferences->processors > 1 ? 2 : 1, @@ -416,7 +414,8 @@ void PackageRenderer::do_video() VFrame *preview_output; video_device->new_output_buffer(&preview_output, - command->get_edl()->session->color_model); + command->get_edl()->session->color_model, + command->get_edl()); preview_output->copy_from(video_output_ptr); video_device->write_buffer(preview_output, @@ -742,6 +741,7 @@ int PackageRenderer::direct_frame_copy(EDL *edl, //printf("Render::direct_frame_copy 2\n"); if(!package->use_brender) + { error |= ((VEdit*)playable_edit)->read_frame(compressed_output, video_position, PLAY_FORWARD, @@ -749,7 +749,9 @@ int PackageRenderer::direct_frame_copy(EDL *edl, 1, 0, 0); - +//printf("Render::direct_frame_copy %d %d\n", __LINE__, compressed_output->get_compressed_size()); + } + if(!error && video_preroll > 0) { diff --git a/cinelerra-5.1/cinelerra/playbackconfig.C b/cinelerra-5.1/cinelerra/playbackconfig.C index 1c329474..22fee714 100644 --- a/cinelerra-5.1/cinelerra/playbackconfig.C +++ b/cinelerra-5.1/cinelerra/playbackconfig.C @@ -239,7 +239,7 @@ const char *VideoOutConfig::default_video_device = "/dev/video0"; VideoOutConfig::VideoOutConfig() { - driver = PLAYBACK_X11_XV; + driver = PLAYBACK_X11; x11_host[0] = 0; x11_use_fields = USE_NO_FIELDS; @@ -259,6 +259,7 @@ VideoOutConfig::VideoOutConfig() contrast = 32768; whiteness = 32768; out_channel = -1; + use_direct_x11 = 1; } VideoOutConfig::~VideoOutConfig() @@ -276,6 +277,7 @@ int VideoOutConfig::operator==(VideoOutConfig &that) return (driver == that.driver) && !strcmp(x11_host, that.x11_host) && (x11_use_fields == that.x11_use_fields) && + (use_direct_x11 == that.use_direct_x11) && (brightness == that.brightness) && (hue == that.hue) && (color == that.color) && @@ -309,6 +311,7 @@ void VideoOutConfig::copy_from(VideoOutConfig *src) this->driver = src->driver; strcpy(this->x11_host, src->x11_host); this->x11_use_fields = src->x11_use_fields; + this->use_direct_x11 = src->use_direct_x11; firewire_channel = src->firewire_channel; firewire_port = src->firewire_port; diff --git a/cinelerra-5.1/cinelerra/playbackconfig.h b/cinelerra-5.1/cinelerra/playbackconfig.h index 99323f64..1896a5da 100644 --- a/cinelerra-5.1/cinelerra/playbackconfig.h +++ b/cinelerra-5.1/cinelerra/playbackconfig.h @@ -99,6 +99,7 @@ public: int driver; int out_channel; + int use_direct_x11; // X11 options char x11_host[BCTEXTLEN]; diff --git a/cinelerra-5.1/cinelerra/playbackprefs.C b/cinelerra-5.1/cinelerra/playbackprefs.C index cadec09d..91adc592 100644 --- a/cinelerra-5.1/cinelerra/playbackprefs.C +++ b/cinelerra-5.1/cinelerra/playbackprefs.C @@ -68,30 +68,19 @@ void PlaybackPrefs::create_objects() x = mwindow->theme->preferencesoptions_x; y = mwindow->theme->preferencesoptions_y; - //int margin = mwindow->theme->widget_border; + int margin = mwindow->theme->widget_border; // Audio - add_subwindow(new BC_Title(x, - y, - _("Audio Out"), - LARGEFONT)); - - - y += get_text_height(LARGEFONT) + 5; - - BC_Title *title1, *title2; + add_subwindow(title1 = new BC_Title(x, y, _("Audio Out"), LARGEFONT)); + y += title1->get_h() + margin; add_subwindow(title2 = new BC_Title(x, y, _("Playback buffer samples:"), MEDIUMFONT)); - x2 = MAX(title2->get_w(), title2->get_w()) + 10; + x2 = title2->get_x() + title2->get_w() + margin; SET_TRACE sprintf(string, "%d", playback_config->aconfig->fragment_size); PlaybackModuleFragment *menu; - add_subwindow(menu = new PlaybackModuleFragment(x2, - y, - pwindow, - this, - string)); + add_subwindow(menu = new PlaybackModuleFragment(x2, y, pwindow, this, string)); menu->add_item(new BC_MenuItem("1024")); menu->add_item(new BC_MenuItem("2048")); menu->add_item(new BC_MenuItem("4096")); @@ -141,26 +130,29 @@ SET_TRACE // Video - y += audio_device->get_h(); + y += audio_device->get_h(0) + margin; SET_TRACE - add_subwindow(new BC_Bar(5, y, get_w() - 10)); + add_subwindow(new BC_Bar(x, y, get_w() - x * 2)); y += 5; SET_TRACE - add_subwindow(new BC_Title(x, y, _("Video Out"), LARGEFONT)); - y += 30; + add_subwindow(title1 = new BC_Title(x, y, _("Video Out"), LARGEFONT)); + y += title1->get_h() + margin; SET_TRACE add_subwindow(window = new VideoEveryFrame(pwindow, this, x, y)); - - add_subwindow(new BC_Title(x + 200, y + 5, _("Framerate achieved:"))); - add_subwindow(framerate_title = new BC_Title(x + 350, y + 5, "--", MEDIUMFONT, RED)); + int x1 = x + window->get_w() + 30; + const char *txt = _("Framerate achieved:"); + int y1 = y + (window->get_h() - BC_Title::calculate_h(this, txt)) / 2; + add_subwindow(title1 = new BC_Title(x1, y1, txt)); + x1 += title1->get_w() + margin; + add_subwindow(framerate_title = new BC_Title(x1, y1, _("--"), MEDIUMFONT, RED)); draw_framerate(0); - y += window->get_h() + 5; + y += window->get_h() + 2*margin; - add_subwindow(asynchronous = new VideoAsynchronous(pwindow, x, y)); - y += asynchronous->get_h() + 10; +// add_subwindow(asynchronous = new VideoAsynchronous(pwindow, x, y)); +// y += asynchronous->get_h() + 10; SET_TRACE add_subwindow(title1 = new BC_Title(x, y, _("Scaling equation: Enlarge / Reduce "))); @@ -174,14 +166,13 @@ SET_TRACE add_subwindow(title1 = new BC_Title(x, y, _("DVD Subtitle to display:"))); PlaybackSubtitleNumber *subtitle_number; - subtitle_number = new PlaybackSubtitleNumber(x + title1->get_w() + 10, - y, - pwindow, - this); + x1 = x + title1->get_w() + margin; + subtitle_number = new PlaybackSubtitleNumber(x1, y, pwindow, this); subtitle_number->create_objects(); x2 = x + title1->get_w() + 10 + subtitle_number->get_w() + 30; PlaybackSubtitle *subtitle_toggle; + x1 += subtitle_number->get_w() + margin; add_subwindow(subtitle_toggle = new PlaybackSubtitle(x2, y, pwindow, this)); y += subtitle_toggle->get_h(); @@ -197,18 +188,18 @@ SET_TRACE add_subwindow(interpolate_raw = new PlaybackInterpolateRaw( x, y, pwindow, this)); - y += interpolate_raw->get_h(); + y += interpolate_raw->get_h() + margin; - add_subwindow(white_balance_raw = new PlaybackWhiteBalanceRaw( x, y, + add_subwindow(white_balance_raw = new PlaybackWhiteBalanceRaw(x, y, pwindow, this)); - y += white_balance_raw->get_h() + 10; - if(!pwindow->thread->edl->session->interpolate_raw) - white_balance_raw->disable(); + if(!pwindow->thread->edl->session->interpolate_raw) + white_balance_raw->disable(); + y += white_balance_raw->get_h() + margin; - y += white_balance_raw->get_h() + 5; add_subwindow(vdevice_title = new BC_Title(x, y, _("Video Driver:"))); - video_device = new VDevicePrefs(x + vdevice_title->get_w() + 10, y, - pwindow, this, playback_config->vconfig, 0, MODEPLAY); + y += vdevice_title->get_h() + margin; + video_device = new VDevicePrefs(x, y, pwindow, this, + playback_config->vconfig, 0, MODEPLAY); video_device->initialize(0); } @@ -327,7 +318,7 @@ PlaybackInterpolateRaw::PlaybackInterpolateRaw( int x, int y, int PlaybackInterpolateRaw::handle_event() { pwindow->thread->edl->session->interpolate_raw = get_value(); - if(!pwindow->thread->edl->session->interpolate_raw) { + if( !pwindow->thread->edl->session->interpolate_raw ) { playback->white_balance_raw->update(0, 0); playback->white_balance_raw->disable(); } @@ -338,7 +329,6 @@ int PlaybackInterpolateRaw::handle_event() return 1; } - PlaybackWhiteBalanceRaw::PlaybackWhiteBalanceRaw( int x, int y, PreferencesWindow *pwindow, PlaybackPrefs *playback) : BC_CheckBox(x, @@ -358,23 +348,22 @@ int PlaybackWhiteBalanceRaw::handle_event() return 1; } - -VideoAsynchronous::VideoAsynchronous(PreferencesWindow *pwindow, int x, int y) - : BC_CheckBox(x, y, - pwindow->thread->edl->session->video_every_frame && - pwindow->thread->edl->session->video_asynchronous, - _("Decode frames asynchronously")) -{ - this->pwindow = pwindow; - if(!pwindow->thread->edl->session->video_every_frame) - disable(); -} - -int VideoAsynchronous::handle_event() -{ - pwindow->thread->edl->session->video_asynchronous = get_value(); - return 1; -} +// VideoAsynchronous::VideoAsynchronous(PreferencesWindow *pwindow, int x, int y) +// : BC_CheckBox(x, y, +// pwindow->thread->edl->session->video_every_frame && +// pwindow->thread->edl->session->video_asynchronous, +// _("Decode frames asynchronously")) +// { +// this->pwindow = pwindow; +// if(!pwindow->thread->edl->session->video_every_frame) +// disable(); +// } +// +// int VideoAsynchronous::handle_event() +// { +// pwindow->thread->edl->session->video_asynchronous = get_value(); +// return 1; +// } VideoEveryFrame::VideoEveryFrame(PreferencesWindow *pwindow, @@ -388,14 +377,14 @@ VideoEveryFrame::VideoEveryFrame(PreferencesWindow *pwindow, int VideoEveryFrame::handle_event() { pwindow->thread->edl->session->video_every_frame = get_value(); - if(!pwindow->thread->edl->session->video_every_frame) { - playback_prefs->asynchronous->update(0, 0); - playback_prefs->asynchronous->disable(); - } - else { - playback_prefs->asynchronous->update(pwindow->thread->edl->session->video_asynchronous, 0); - playback_prefs->asynchronous->enable(); - } +// if(!pwindow->thread->edl->session->video_every_frame) { +// playback_prefs->asynchronous->update(0, 0); +// playback_prefs->asynchronous->disable(); +// } +// else { +// playback_prefs->asynchronous->update(pwindow->thread->edl->session->video_asynchronous, 0); +// playback_prefs->asynchronous->enable(); +// } return 1; } diff --git a/cinelerra-5.1/cinelerra/playbackprefs.h b/cinelerra-5.1/cinelerra/playbackprefs.h index 167d3bd6..f2befa9f 100644 --- a/cinelerra-5.1/cinelerra/playbackprefs.h +++ b/cinelerra-5.1/cinelerra/playbackprefs.h @@ -30,7 +30,7 @@ class PlaybackViewFollows; class PlaybackSoftwareTimer; class PlaybackRealTime; class PlaybackMap51_2; -class VideoAsynchronous; +//class VideoAsynchronous; class VideoEveryFrame; class PlaybackPreload; class PlaybackInterpolateRaw; @@ -70,7 +70,7 @@ public: BC_Title *framerate_title; PlaybackInterpolateRaw *interpolate_raw; PlaybackWhiteBalanceRaw *white_balance_raw; - VideoAsynchronous *asynchronous; +// VideoAsynchronous *asynchronous; BC_Title *vdevice_title; PlaybackAudioOffset *audio_offset; @@ -127,6 +127,14 @@ public: PreferencesWindow *pwindow; }; +// class VideoAsynchronous : public BC_CheckBox +// { +// public: +// VideoAsynchronous(PreferencesWindow *pwindow, int x, int y); +// int handle_event(); +// PreferencesWindow *pwindow; +// }; + class PlaybackMap51_2 : public BC_CheckBox { public: @@ -137,14 +145,6 @@ public: PlaybackPrefs *playback_prefs; }; -class VideoAsynchronous : public BC_CheckBox -{ -public: - VideoAsynchronous(PreferencesWindow *pwindow, int x, int y); - int handle_event(); - PreferencesWindow *pwindow; -}; - class VideoEveryFrame : public BC_CheckBox { public: diff --git a/cinelerra-5.1/cinelerra/pluginclient.C b/cinelerra-5.1/cinelerra/pluginclient.C index 03e8c3f1..aaec69d8 100644 --- a/cinelerra-5.1/cinelerra/pluginclient.C +++ b/cinelerra-5.1/cinelerra/pluginclient.C @@ -730,39 +730,29 @@ int PluginClient::get_interpolation_type() float PluginClient::get_red() { - if(server->mwindow) - return server->mwindow->edl->local_session->red; - else - if(server->edl) - return server->edl->local_session->red; - else - return 0; + EDL *edl = server->mwindow ? server->mwindow->edl : server->edl; + return !edl ? 0 : edl->local_session->use_max ? + edl->local_session->red_max : + edl->local_session->red; } float PluginClient::get_green() { - if(server->mwindow) - return server->mwindow->edl->local_session->green; - else - if(server->edl) - return server->edl->local_session->green; - else - return 0; + EDL *edl = server->mwindow ? server->mwindow->edl : server->edl; + return !edl ? 0 : edl->local_session->use_max ? + edl->local_session->green_max : + edl->local_session->green; } float PluginClient::get_blue() { - if(server->mwindow) - return server->mwindow->edl->local_session->blue; - else - if(server->edl) - return server->edl->local_session->blue; - else - return 0; + EDL *edl = server->mwindow ? server->mwindow->edl : server->edl; + return !edl ? 0 : edl->local_session->use_max ? + edl->local_session->blue_max : + edl->local_session->blue; } - int64_t PluginClient::get_source_position() { return source_position; diff --git a/cinelerra-5.1/cinelerra/presets.C b/cinelerra-5.1/cinelerra/presets.C new file mode 100644 index 00000000..8a289090 --- /dev/null +++ b/cinelerra-5.1/cinelerra/presets.C @@ -0,0 +1,438 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "bcsignals.h" +#include "bcwindowbase.inc" +#include "file.h" +#include "filesystem.h" +#include "filexml.h" +#include "keyframe.h" +#include "messages.inc" +#include "mwindow.h" +#include "pluginserver.h" +#include "preferences.inc" +#include "presets.h" + +#include +#include + +PresetsDB::PresetsDB() +{ +} + +void PresetsDB::clear() +{ + plugins.remove_all_objects(); +} + +void PresetsDB::load_from_file(char *path, int is_factory, int clear_it) +{ + if( clear_it ) clear(); + FileXML file; + + file.read_from_file(path); + load_common(&file, is_factory); +} + +void PresetsDB::load_from_string(char *string, int is_factory, int clear_it) +{ + if( clear_it ) clear(); + + FileXML file; + file.read_from_string(string); + load_common(&file, is_factory); +} + + + +void PresetsDB::load_common(FileXML *file, int is_factory) +{ + int result = 0; + char string[BCTEXTLEN]; + + do { + result = file->read_tag(); + if( ! result ) { + if( file->tag.title_is("PLUGIN") ) { + PresetsDBPlugin *plugin = 0; + sprintf(string, "Unknown"); + const char *title = file->tag.get_property("TITLE", string); + +// Search for existing plugin + for( int i=0; ititle, title) ) { + plugin = plugins[i]; + break; + } + } + +// Create new plugin + if( !plugin ) { + plugin = new PresetsDBPlugin(title); + plugins.append(plugin); + } + + plugin->load(file, is_factory); + } + } + } while(!result); +} + + +void PresetsDB::save() +{ + FileXML file; + for( int i=0; iget_total_presets(1) > 0 ) { + plugin->save(&file); + } + } + file.terminate_string(); + + char path[BCTEXTLEN]; + sprintf(path, "%s/%s", File::get_config_path(), PRESETS_FILE); + FileSystem fs; + fs.complete_path(path); + file.write_to_file(path); +} + + +int PresetsDB::get_total_presets(char *plugin_title, int user_only) +{ + for( int i=0; ititle, plugin_title) ) { + return plugin->get_total_presets(user_only); + } + } + + return 0; +} + + +// move factory presets to the start, followed by sorted preset titles +void PresetsDB::sort(char *plugin_title) +{ + PresetsDBPlugin *plugin = 0; + for( int i=0; !plugin && ititle, plugin_title) ) + plugin = plugins[i]; + } + + if( plugin ) { + int done = 0; + int total_presets = plugin->get_total_presets(0); + while( !done ) { + done = 1; + for( int i=0; ikeyframes[i]; + PresetsDBKeyframe *keyframe2 = plugin->keyframes[i+1]; + + if( (keyframe2->is_factory && !keyframe1->is_factory) || + (keyframe2->is_factory == keyframe1->is_factory && + strcmp(keyframe2->title, keyframe1->title) < 0) ) { + plugin->keyframes.set(i, keyframe2); + plugin->keyframes.set(i + 1, keyframe1); + done = 0; + } + } + } + } +} + + +char* PresetsDB::get_preset_title(char *plugin_title, int number) +{ + for( int i=0; ititle, plugin_title) ) { + if( number < plugin->keyframes.size() ) + return plugin->keyframes[number]->title; + printf("PresetsDB::get_preset_title %d buffer overrun\n", __LINE__); + break; + } + } + return 0; +} + + +int PresetsDB::get_is_factory(char *plugin_title, int number) +{ + for( int i=0; ititle, plugin_title) ) { + if( number < plugin->keyframes.size() ) + return plugin->keyframes[number]->is_factory; + printf("PresetsDB::get_preset_title %d buffer overrun\n", __LINE__); + break; + } + } + return 0; +} + + +char* PresetsDB::get_preset_data(char *plugin_title, int number) +{ + for( int i=0; ititle, plugin_title) ) { + if( number < plugin->keyframes.size() ) + return plugin->keyframes[number]->data; + printf("PresetsDB::get_preset_data %d buffer overrun\n", __LINE__); + break; + } + } + return 0; +} + +PresetsDBPlugin* PresetsDB::get_plugin(const char *plugin_title) +{ + for( int i=0; ititle, plugin_title) ) + return plugin; + } + return 0; +} + +PresetsDBPlugin* PresetsDB::new_plugin(const char *plugin_title) +{ + PresetsDBPlugin *result = new PresetsDBPlugin(plugin_title); + plugins.append(result); + return result; +} + + +void PresetsDB::save_preset(const char *plugin_title, + const char *preset_title, + char *data) +{ + PresetsDBPlugin *plugin = get_plugin(plugin_title); + if( !plugin ) plugin = new_plugin(plugin_title); + PresetsDBKeyframe *keyframe = plugin->get_keyframe(preset_title, 0); + if( !keyframe ) keyframe = plugin->new_keyframe(preset_title); + keyframe->set_data(data); + save(); + +} + + +void PresetsDB::delete_preset(const char *plugin_title, + const char *preset_title, + int is_factory) +{ + PresetsDBPlugin *plugin = get_plugin(plugin_title); + if( plugin ) { + plugin->delete_keyframe(preset_title); + } + save(); +} + +void PresetsDB::load_preset(const char *plugin_title, + const char *preset_title, + KeyFrame *keyframe, + int is_factory) +{ + PresetsDBPlugin *plugin = get_plugin(plugin_title); + if( plugin ) { + plugin->load_preset(preset_title, keyframe, is_factory); + } +} + +int PresetsDB::preset_exists(const char *plugin_title, + const char *preset_title, + int is_factory) +{ + PresetsDBPlugin *plugin = get_plugin(plugin_title); + if( plugin ) { + return plugin->preset_exists(preset_title, is_factory); + } + return 0; +} + + + + +PresetsDBKeyframe::PresetsDBKeyframe(const char *title, int is_factory) +{ + this->title = strdup(title); + data = 0; + this->is_factory = is_factory; +} + +PresetsDBKeyframe::~PresetsDBKeyframe() +{ + delete [] title; + delete [] data; +} + +void PresetsDBKeyframe::set_data(char *data) +{ + delete [] this->data; + this->data = new char[strlen(data) + 1]; + strcpy(this->data, data); +} + + +PresetsDBPlugin::PresetsDBPlugin(const char *title) +{ + this->title = strdup(title); +} + +PresetsDBPlugin::~PresetsDBPlugin() +{ + keyframes.remove_all_objects(); + delete [] title; +} + +int PresetsDBPlugin::get_total_presets(int user_only) +{ + if( !user_only ) + return keyframes.size(); + int result = 0; + for( int j=0; jis_factory ) ++result; + return result; +} + +void PresetsDBPlugin::load(FileXML *file, int is_factory) +{ + int result = 0; + char string[BCTEXTLEN]; + + do { + result = file->read_tag(); + if( !result ) { + if( file->tag.title_is("/PLUGIN") ) break; + else + if( file->tag.title_is("KEYFRAME") ) { + sprintf(string, "Unknown"); + const char *keyframe_title = file->tag.get_property("TITLE", string); + PresetsDBKeyframe *keyframe = new PresetsDBKeyframe(keyframe_title, is_factory); + + char data[MESSAGESIZE]; + file->read_text_until("/KEYFRAME", data, MESSAGESIZE); + keyframe->set_data(data); + keyframes.append(keyframe); + + } + } + } while(!result); +} + +void PresetsDBPlugin::save(FileXML *file) +{ + file->tag.set_title("PLUGIN"); + file->tag.set_property("TITLE", title); + file->append_tag(); + file->append_newline(); + + for( int j=0; jis_factory ) { + file->tag.set_title("KEYFRAME"); + file->tag.set_property("TITLE", keyframe->title); + file->append_tag(); + file->append_text(keyframe->data); + file->tag.set_title("/KEYFRAME"); + file->append_tag(); + file->append_newline(); + } + } + + file->tag.set_title("/PLUGIN"); + file->append_tag(); + file->append_newline(); +} + +PresetsDBKeyframe* PresetsDBPlugin::get_keyframe(const char *title, + int is_factory) +{ + for( int i=0; ititle, title) && + keyframe->is_factory == is_factory ) + return keyframe; + } + return 0; +} + +void PresetsDBPlugin::delete_keyframe(const char *title) +{ + for( int i=0; ititle, title) && !keyframe->is_factory ) + keyframes.remove_object_number(i); + return; + } +} + + +PresetsDBKeyframe* PresetsDBPlugin::new_keyframe(const char *title) +{ + PresetsDBKeyframe *keyframe = new PresetsDBKeyframe(title, 0); + keyframes.append(keyframe); + return keyframe; +} + +void PresetsDBPlugin::load_preset(const char *preset_title, + KeyFrame *keyframe, + int is_factory) +{ + PresetsDBKeyframe *src = get_keyframe(preset_title, is_factory); + if( src ) { + keyframe->set_data(src->data); +// Save as the plugin's default, Need the path +//printf("PresetsDBPlugin::load_preset %d %s\n", __LINE__, title); + PluginServer *server = MWindow::scan_plugindb(title, -1); + if( server ) { + char path[BCTEXTLEN]; + server->get_defaults_path(path); + FileSystem fs; + fs.complete_path(path); + + FILE *fd = fopen(path, "w"); + if( fd ) { + if( !fwrite(src->data, strlen(src->data), 1, fd) ) { + fprintf(stderr, "PresetsDBPlugin::load_preset %d \"%s\": %s\n", + __LINE__, + path, + strerror(errno)); + } + + fclose(fd); + } + else { + fprintf(stderr, "PresetsDBPlugin::load_preset %d \"%s\": %s\n", + __LINE__, path, strerror(errno)); + } + } + } +} + +int PresetsDBPlugin::preset_exists(const char *preset_title, int is_factory) +{ + PresetsDBKeyframe *src = get_keyframe(preset_title, is_factory); + return src ? 1 : 0; +} + diff --git a/cinelerra-5.1/cinelerra/presets.h b/cinelerra-5.1/cinelerra/presets.h new file mode 100644 index 00000000..1db071e9 --- /dev/null +++ b/cinelerra-5.1/cinelerra/presets.h @@ -0,0 +1,128 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef PRESETS_H +#define PRESETS_H + + +#include "arraylist.h" +#include "filexml.inc" +#include "keyframe.inc" + + +// Front end for a DB of presets for all plugins + +// A single preset +class PresetsDBKeyframe +{ +public: + PresetsDBKeyframe(const char *title, int is_factory); + ~PresetsDBKeyframe(); + + void set_data(char *data); + + char *title; + char *data; +// is a factory preset + int is_factory; +}; + +// Presets for a single plugin +class PresetsDBPlugin +{ +public: + PresetsDBPlugin(const char *title); + ~PresetsDBPlugin(); + + + void load(FileXML *file, int is_factory); + void save(FileXML *file); + +// Get a preset by name + PresetsDBKeyframe* get_keyframe(const char *title, int is_factory); +// Create a new keyframe + PresetsDBKeyframe* new_keyframe(const char *title); + void delete_keyframe(const char *title); +// Load a preset into the keyframe + void load_preset(const char *preset_title, + KeyFrame *keyframe, + int is_factory); + int preset_exists(const char *preset_title, int is_factory); + int get_total_presets(int user_only); + + ArrayList keyframes; + char *title; +}; + +class PresetsDB +{ +public: + PresetsDB(); + +// Load the database from the file. + void load_from_file(char *path, int is_factory, int clear_it); +// load the database from a string + void load_from_string(char *string, int is_factory, int clear_it); + void load_common(FileXML *file, int is_factory); + +// Save the database to the file. + void save(); + void sort(char *plugin_title); + +// Get the total number of presets for a plugin + int get_total_presets(char *plugin_title, int user_only); +// Get the title of a preset + char* get_preset_title(char *plugin_title, int number); + int get_is_factory(char *plugin_title, int number); +// Get the data for a preset + char* get_preset_data(char *plugin_title, int number); +// Get a pluginDB by name + PresetsDBPlugin* get_plugin(const char *plugin_title); +// Create a pluginDB + PresetsDBPlugin* new_plugin(const char *plugin_title); + void save_preset(const char *plugin_title, + const char *preset_title, + char *data); + void delete_preset(const char *plugin_title, + const char *preset_title, + int is_factory); +// Load a preset into the keyframe + void load_preset(const char *plugin_title, + const char *preset_title, + KeyFrame *keyframe, + int is_factory); + int preset_exists(const char *plugin_title, + const char *preset_title, + int is_factory); + +private: +// Remove all plugin data + void clear(); + + ArrayList plugins; +}; + + + +#endif + + + diff --git a/cinelerra-5.1/cinelerra/presets.inc b/cinelerra-5.1/cinelerra/presets.inc new file mode 100644 index 00000000..cae1427b --- /dev/null +++ b/cinelerra-5.1/cinelerra/presets.inc @@ -0,0 +1,32 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef PRESETS_INC +#define PRESETS_INC + + +class PresetsDB; + +#endif + + + + diff --git a/cinelerra-5.1/cinelerra/presetsgui.C b/cinelerra-5.1/cinelerra/presetsgui.C new file mode 100644 index 00000000..c5dbe8e9 --- /dev/null +++ b/cinelerra-5.1/cinelerra/presetsgui.C @@ -0,0 +1,508 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#if 0 + + + + +#include "edl.h" +#include "keyframe.h" +#include "keys.h" +#include "language.h" +#include "localsession.h" +#include "mainsession.h" +#include "mainundo.h" +#include "mwindow.h" +#include "mwindowgui.h" +#include "plugin.h" +#include "presets.h" +#include "presetsgui.h" +#include "theme.h" +#include "trackcanvas.h" +#include "tracks.h" + + + + + + + + + + + +PresetsThread::PresetsThread(MWindow *mwindow) + : BC_DialogThread() +{ + this->mwindow = mwindow; + plugin = 0; + data = new ArrayList; + presets_db = new PresetsDB; + plugin_title[0] = 0; + window_title[0] = 0; +} + +PresetsThread::~PresetsThread() +{ + delete data; +} + +void PresetsThread::calculate_list() +{ + data->remove_all_objects(); + int total_presets = presets_db->get_total_presets(plugin_title); + for(int i = 0; i < total_presets; i++) + { + data->append(new BC_ListBoxItem(presets_db->get_preset_title( + plugin_title, + i))); + } +} + + +void PresetsThread::start_window(Plugin *plugin) +{ + if(!BC_DialogThread::is_running()) + { + this->plugin = plugin; + plugin->calculate_title(plugin_title, 0); + sprintf(window_title, PROGRAM_NAME ": %s Presets", plugin_title); + + +// Calculate database + presets_db->load(); + calculate_list(); + + + mwindow->gui->unlock_window(); + BC_DialogThread::start(); + mwindow->gui->lock_window("PresetsThread::start_window"); + } +} + +BC_Window* PresetsThread::new_gui() +{ + mwindow->gui->lock_window("PresetsThread::new_gui"); + int x = mwindow->gui->get_abs_cursor_x(0) - + mwindow->session->plugindialog_w / 2; + int y = mwindow->gui->get_abs_cursor_y(0) - + mwindow->session->plugindialog_h / 2; + + PresetsWindow *window = new PresetsWindow(mwindow, + this, + x, + y, + window_title); + + window->create_objects(); + mwindow->gui->unlock_window(); + return window; +} + +void PresetsThread::handle_done_event(int result) +{ +// Apply the preset + if(!result) + { + char *title = ((PresetsWindow*)get_gui())->title_text->get_text(); + apply_preset(title); + } +} + +void PresetsThread::handle_close_event(int result) +{ +} + +void PresetsThread::save_preset(char *title) +{ + get_gui()->unlock_window(); + mwindow->gui->lock_window("PresetsThread::save_preset"); + +// Test EDL for plugin existence + if(!mwindow->edl->tracks->plugin_exists(plugin)) + { + mwindow->gui->unlock_window(); + get_gui()->lock_window("PresetsThread::save_preset 2"); + return; + } + + +// Get current plugin keyframe + EDL *edl = mwindow->edl; + Track *track = plugin->track; + KeyFrame *keyframe = plugin->get_prev_keyframe( + track->to_units(edl->local_session->get_selectionstart(1), 0), + PLAY_FORWARD); + +// Send to database + presets_db->save_preset(plugin_title, title, keyframe->get_data()); + + mwindow->gui->unlock_window(); + get_gui()->lock_window("PresetsThread::save_preset 2"); + + +// Update list + calculate_list(); + ((PresetsWindow*)get_gui())->list->update(data, + 0, + 0, + 1); +} + +void PresetsThread::delete_preset(char *title) +{ + get_gui()->unlock_window(); + mwindow->gui->lock_window("PresetsThread::save_preset"); + +// Test EDL for plugin existence + if(!mwindow->edl->tracks->plugin_exists(plugin)) + { + mwindow->gui->unlock_window(); + get_gui()->lock_window("PresetsThread::delete_preset 1"); + return; + } + + presets_db->delete_preset(plugin_title, title); + + mwindow->gui->unlock_window(); + get_gui()->lock_window("PresetsThread::delete_preset 2"); + + +// Update list + calculate_list(); + ((PresetsWindow*)get_gui())->list->update(data, + 0, + 0, + 1); +} + + +void PresetsThread::apply_preset(char *title) +{ + if(presets_db->preset_exists(plugin_title, title)) + { + get_gui()->unlock_window(); + mwindow->gui->lock_window("PresetsThread::apply_preset"); + +// Test EDL for plugin existence + if(!mwindow->edl->tracks->plugin_exists(plugin)) + { + mwindow->gui->unlock_window(); + get_gui()->lock_window("PresetsThread::delete_preset 1"); + return; + } + + mwindow->undo->update_undo_before(); + KeyFrame *keyframe = plugin->get_keyframe(); + presets_db->load_preset(plugin_title, title, keyframe); + mwindow->save_backup(); + mwindow->undo->update_undo_after(_("apply preset"), LOAD_AUTOMATION); + + mwindow->update_plugin_guis(); + mwindow->gui->canvas->draw_overlays(); + mwindow->gui->canvas->flash(); + mwindow->sync_parameters(CHANGE_PARAMS); + + mwindow->gui->unlock_window(); + get_gui()->lock_window("PresetsThread::apply_preset"); + } +} + + + + + +PresetsList::PresetsList(PresetsThread *thread, + PresetsWindow *window, + int x, + int y, + int w, + int h) + : BC_ListBox(x, + y, + w, + h, + LISTBOX_TEXT, + thread->data) +{ + this->thread = thread; + this->window = window; +} + +int PresetsList::selection_changed() +{ + window->title_text->update( + thread->data->get(get_selection_number(0, 0))->get_text()); + return 0; +} + +int PresetsList::handle_event() +{ + window->set_done(0); + return 0; +} + + + + + + + + + + +PresetsText::PresetsText(PresetsThread *thread, + PresetsWindow *window, + int x, + int y, + int w) + : BC_TextBox(x, + y, + w, + 1, + "") +{ + this->thread = thread; + this->window = window; +} + +int PresetsText::handle_event() +{ + return 0; +} + + + + + + + + + + + + + + + + + +PresetsDelete::PresetsDelete(PresetsThread *thread, + PresetsWindow *window, + int x, + int y) + : BC_GenericButton(x, y, _("Delete")) +{ + this->thread = thread; + this->window = window; +} + +int PresetsDelete::handle_event() +{ + thread->delete_preset(window->title_text->get_text()); + return 1; +} + + + + + + + +PresetsSave::PresetsSave(PresetsThread *thread, + PresetsWindow *window, + int x, + int y) +: BC_GenericButton(x, y, _("Save")) +{ + this->thread = thread; + this->window = window; +} + +int PresetsSave::handle_event() +{ + thread->save_preset(window->title_text->get_text()); + return 1; +} + + + + + + + + +PresetsApply::PresetsApply(PresetsThread *thread, + PresetsWindow *window, + int x, + int y) + : BC_GenericButton(x, y, _("Apply")) +{ + this->thread = thread; + this->window = window; +} + +int PresetsApply::handle_event() +{ + thread->apply_preset(window->title_text->get_text()); + return 1; +} + + + +PresetsOK::PresetsOK(PresetsThread *thread, + PresetsWindow *window) + : BC_OKButton(window) +{ + this->thread = thread; + this->window = window; +} + +int PresetsOK::keypress_event() +{ + if(get_keypress() == RETURN) + { +printf("PresetsOK::keypress_event %d\n", __LINE__); + if(thread->presets_db->preset_exists(thread->plugin_title, + window->title_text->get_text())) + { +printf("PresetsOK::keypress_event %d\n", __LINE__); + window->set_done(0); + return 1; + } + else + { +printf("PresetsOK::keypress_event %d\n", __LINE__); + thread->save_preset(window->title_text->get_text()); + return 1; + } + } + return 0; +} + + + + + + + + + + +PresetsWindow::PresetsWindow(MWindow *mwindow, + PresetsThread *thread, + int x, + int y, + char *title_string) + : BC_Window(title_string, + x, + y, + mwindow->session->presetdialog_w, + mwindow->session->presetdialog_h, + 320, + 240, + 1, + 0, + 1) +{ + this->mwindow = mwindow; + this->thread = thread; +} + +void PresetsWindow::create_objects() +{ + Theme *theme = mwindow->theme; + + lock_window("PresetsWindow::create_objects"); + theme->get_presetdialog_sizes(this); + + add_subwindow(title1 = new BC_Title(theme->presets_list_x, + theme->presets_list_y - BC_Title::calculate_h(this, "P") - theme->widget_border, + _("Saved presets:"))); + add_subwindow(list = new PresetsList(thread, + this, + theme->presets_list_x, + theme->presets_list_y, + theme->presets_list_w, + theme->presets_list_h)); + add_subwindow(title2 = new BC_Title(theme->presets_text_x, + theme->presets_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border, + _("Preset title:"))); + add_subwindow(title_text = new PresetsText(thread, + this, + theme->presets_text_x, + theme->presets_text_y, + theme->presets_text_w)); + add_subwindow(delete_button = new PresetsDelete(thread, + this, + theme->presets_delete_x, + theme->presets_delete_y)); + add_subwindow(save_button = new PresetsSave(thread, + this, + theme->presets_save_x, + theme->presets_save_y)); + add_subwindow(apply_button = new PresetsApply(thread, + this, + theme->presets_apply_x, + theme->presets_apply_y)); + + add_subwindow(new PresetsOK(thread, this)); + add_subwindow(new BC_CancelButton(this)); + + show_window(); + unlock_window(); +} + +int PresetsWindow::resize_event(int w, int h) +{ + Theme *theme = mwindow->theme; + mwindow->session->presetdialog_w = w; + mwindow->session->presetdialog_h = h; + theme->get_presetdialog_sizes(this); + + title1->reposition_window(theme->presets_list_x, + theme->presets_list_y - BC_Title::calculate_h(this, "P") - theme->widget_border); + title2->reposition_window(theme->presets_text_x, + theme->presets_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border); + list->reposition_window(theme->presets_list_x, + theme->presets_list_y, + theme->presets_list_w, + theme->presets_list_h); + title_text->reposition_window(theme->presets_text_x, + theme->presets_text_y, + theme->presets_text_w); + delete_button->reposition_window(theme->presets_delete_x, + theme->presets_delete_y); + save_button->reposition_window(theme->presets_save_x, + theme->presets_save_y); + apply_button->reposition_window(theme->presets_apply_x, + theme->presets_apply_y); + return 0; +} + + + + + + +#endif + diff --git a/cinelerra-5.1/cinelerra/presetsgui.h b/cinelerra-5.1/cinelerra/presetsgui.h new file mode 100644 index 00000000..abd63e82 --- /dev/null +++ b/cinelerra-5.1/cinelerra/presetsgui.h @@ -0,0 +1,170 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef PRESETSGUI_H +#define PRESETSGUI_H + + +// Presets for effects & transitions +#if 0 + +#include "bcdialog.h" +#include "guicast.h" +#include "mwindow.inc" +#include "plugin.inc" +#include "presets.inc" + +class PresetsWindow; + + + + + +class PresetsThread : public BC_DialogThread +{ +public: + PresetsThread(MWindow *mwindow); + ~PresetsThread(); + + void calculate_list(); + void start_window(Plugin *plugin); + BC_Window* new_gui(); + void handle_done_event(int result); + void handle_close_event(int result); + void save_preset(char *title); + void delete_preset(char *title); + void apply_preset(char *title); + + char window_title[BCTEXTLEN]; + char plugin_title[BCTEXTLEN]; + MWindow *mwindow; + Plugin *plugin; + ArrayList *data; + PresetsDB *presets_db; +}; + +class PresetsList : public BC_ListBox +{ +public: + PresetsList(PresetsThread *thread, + PresetsWindow *window, + int x, + int y, + int w, + int h); + int selection_changed(); + int handle_event(); + PresetsThread *thread; + PresetsWindow *window; +}; + +class PresetsText : public BC_TextBox +{ +public: + PresetsText(PresetsThread *thread, + PresetsWindow *window, + int x, + int y, + int w); + int handle_event(); + PresetsThread *thread; + PresetsWindow *window; +}; + + +class PresetsDelete : public BC_GenericButton +{ +public: + PresetsDelete(PresetsThread *thread, + PresetsWindow *window, + int x, + int y); + int handle_event(); + PresetsThread *thread; + PresetsWindow *window; +}; + +class PresetsSave : public BC_GenericButton +{ +public: + PresetsSave(PresetsThread *thread, + PresetsWindow *window, + int x, + int y); + int handle_event(); + PresetsThread *thread; + PresetsWindow *window; +}; + +class PresetsApply : public BC_GenericButton +{ +public: + PresetsApply(PresetsThread *thread, + PresetsWindow *window, + int x, + int y); + int handle_event(); + PresetsThread *thread; + PresetsWindow *window; +}; + +class PresetsOK : public BC_OKButton +{ +public: + PresetsOK(PresetsThread *thread, + PresetsWindow *window); + int keypress_event(); + PresetsThread *thread; + PresetsWindow *window; +}; + + +class PresetsWindow : public BC_Window +{ +public: + PresetsWindow(MWindow *mwindow, + PresetsThread *thread, + int x, + int y, + char *title_string); + + void create_objects(); + int resize_event(int w, int h); + + PresetsList *list; + PresetsText *title_text; + PresetsDelete *delete_button; + PresetsSave *save_button; + PresetsApply *apply_button; + BC_Title *title1; + BC_Title *title2; + MWindow *mwindow; + PresetsThread *thread; +}; + + + +#endif + +#endif + + + diff --git a/cinelerra-5.1/cinelerra/presetsgui.inc b/cinelerra-5.1/cinelerra/presetsgui.inc new file mode 100644 index 00000000..688ec11e --- /dev/null +++ b/cinelerra-5.1/cinelerra/presetsgui.inc @@ -0,0 +1,33 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef PRESETSGUI_INC +#define PRESETSGUI_INC + + +class PresetsThread; +class PresetsWindow; + +#endif + + + + diff --git a/cinelerra-5.1/cinelerra/record.C b/cinelerra-5.1/cinelerra/record.C index 4cd0ae44..3ea53a42 100644 --- a/cinelerra-5.1/cinelerra/record.C +++ b/cinelerra-5.1/cinelerra/record.C @@ -230,6 +230,8 @@ int Record::load_defaults() video_zoom = defaults->get("RECORD_VIDEO_Z", (float)1); picture->load_defaults(); reverse_interlace = defaults->get("REVERSE_INTERLACE", 0); + do_cursor = defaults->get("RECORD_CURSOR", 0); + do_big_cursor = defaults->get("RECORD_BIG_CURSOR", 0); for( int i=0; iget(string, 0); @@ -266,6 +268,8 @@ int Record::save_defaults() defaults->update("RECORD_VIDEO_Z", video_zoom); picture->save_defaults(); defaults->update("REVERSE_INTERLACE", reverse_interlace); + defaults->update("RECORD_CURSOR", do_cursor); + defaults->update("RECORD_BIG_CURSOR", do_big_cursor); for( int i=0; iupdate(string, dc_offset[i]); @@ -401,7 +405,7 @@ void Record::run() mwindow->undo->update_undo_before(); // For pasting, clear the active region if(load_mode == LOADMODE_PASTE) - mwindow->clear(0); + mwindow->clear(0, 1); int loadmode = load_mode == LOADMODE_RESOURCESONLY ? LOADMODE_ASSETSONLY : load_mode; mwindow->paste_edls(&new_edls, loadmode, 0, -1, @@ -437,9 +441,10 @@ void Record::run() void Record::stop(int wait) { stop_operation(); - if( wait && running() ) + if( record_gui ) record_gui->set_done(1); - join(); + if( wait ) + join(); window_lock->lock("Record::stop"); delete record_thread; record_thread = 0; delete record_monitor; record_monitor = 0; @@ -995,6 +1000,7 @@ void Record::open_video_input() master_channel->copy_usage(vdevice->channel); picture->copy_usage(vdevice->picture); vdevice->set_field_order(reverse_interlace); + vdevice->set_do_cursor(do_cursor, do_big_cursor); vdevice->set_adevice(adevice); if( adevice ) adevice->set_vdevice(vdevice); set_dev_channel(get_current_channel()); @@ -1207,11 +1213,15 @@ void Record::set_power_off(int value) record_gui->power_off->update(value); } -int Record::set_video_picture() +void Record::set_video_picture() { if( default_asset->video_data && vdevice ) vdevice->set_picture(picture); - return 0; +} + +void Record::set_do_cursor() +{ + vdevice->set_do_cursor(do_cursor, do_big_cursor); } void Record::set_translation(int x, int y) diff --git a/cinelerra-5.1/cinelerra/record.h b/cinelerra-5.1/cinelerra/record.h index 423b4b09..d8fb0102 100644 --- a/cinelerra-5.1/cinelerra/record.h +++ b/cinelerra-5.1/cinelerra/record.h @@ -147,7 +147,8 @@ public: void set_play_gain(double gain); void set_video_monitoring(int mode); void stop_operation(); - int set_video_picture(); + void set_video_picture(); + void set_do_cursor(); // Set screencapture translation void set_translation(int x, int y); @@ -283,6 +284,9 @@ public: float video_zoom; // Reverse the interlace in the video window display only int reverse_interlace; +// record the cursor for screencapture + int do_cursor; + int do_big_cursor; // Color model for uncompressed device interface int color_model; // Picture quality and parameters the device supports diff --git a/cinelerra-5.1/cinelerra/recordgui.C b/cinelerra-5.1/cinelerra/recordgui.C index 00b257e9..0b3810d8 100644 --- a/cinelerra-5.1/cinelerra/recordgui.C +++ b/cinelerra-5.1/cinelerra/recordgui.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams + * Copyright (C) 2008-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -116,7 +116,6 @@ RecordGUI::RecordGUI(MWindow *mwindow, Record *record) RecordGUI::~RecordGUI() { -TRACE("RecordGUI::~RecordGUI 1"); delete status_thread; delete batch_source; delete batch_mode; @@ -126,7 +125,6 @@ TRACE("RecordGUI::~RecordGUI 1"); delete batch_start; delete batch_duration; delete load_mode; -TRACE("RecordGUI::~RecordGUI 2"); } @@ -1612,5 +1610,3 @@ int RecordGUIResetTranslation::handle_event() return 1; } - - diff --git a/cinelerra-5.1/cinelerra/recordgui.h b/cinelerra-5.1/cinelerra/recordgui.h index 40c18df1..4b506bd4 100644 --- a/cinelerra-5.1/cinelerra/recordgui.h +++ b/cinelerra-5.1/cinelerra/recordgui.h @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams + * Copyright (C) 2008-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cinelerra-5.1/cinelerra/recordmonitor.C b/cinelerra-5.1/cinelerra/recordmonitor.C index c72317fb..b04587a7 100644 --- a/cinelerra-5.1/cinelerra/recordmonitor.C +++ b/cinelerra-5.1/cinelerra/recordmonitor.C @@ -79,55 +79,36 @@ void RecordMonitor::create_objects() mwindow->session->rwindow_fullscreen = 0; if( !record->default_asset->video_data ) - min_w = MeterPanel::get_meters_width( - mwindow->theme, + min_w = MeterPanel::get_meters_width(mwindow->theme, record->default_asset->channels, 1); - - -//SET_TRACE window = new RecordMonitorGUI(mwindow, record, this, min_w); -//SET_TRACE window->create_objects(); -//SET_TRACE if( record->default_asset->video_data ) { // Configure the output for record monitoring VideoOutConfig config; -//SET_TRACE device = new VideoDevice; -//SET_TRACE - - // Override default device for X11 drivers if(mwindow->edl->session->playback_config->vconfig->driver == PLAYBACK_X11_XV) config.driver = PLAYBACK_X11_XV; config.x11_use_fields = 0; - -//SET_TRACE - device->open_output(&config, record->default_asset->frame_rate, record->default_asset->width, record->default_asset->height, window->canvas, 0); -//SET_TRACE scope_thread = new RecordScopeThread(mwindow, this); - if(mwindow->session->record_scope) - { + if(mwindow->session->record_scope) { scope_thread->start(); } - thread = new RecordMonitorThread(mwindow, record, this); -//SET_TRACE thread->start_playback(); -//SET_TRACE } -//SET_TRACE Thread::start(); } @@ -273,6 +254,8 @@ RecordMonitorGUI::RecordMonitorGUI(MWindow *mwindow, reverse_interlace = 0; meters = 0; canvas = 0; + cursor_toggle = 0; + big_cursor_toggle = 0; current_operation = MONITOR_NONE; signal_status = 0; } @@ -284,19 +267,15 @@ RecordMonitorGUI::~RecordMonitorGUI() delete signal_status; #endif delete canvas; - if( bitmap ) delete bitmap; + delete cursor_toggle; + delete big_cursor_toggle; + delete bitmap; if( channel_picker ) delete channel_picker; #ifdef HAVE_FIREWIRE - if( avc1394transport_thread ) - delete avc1394transport_thread; - if( avc ) { - delete avc; - } - if( avc1394_transport ) { - delete avc1394_transport; - } - if( avc1394transport_title ) - delete avc1394transport_title; + delete avc1394transport_thread; + delete avc; + delete avc1394_transport; + delete avc1394transport_title; #endif unlock_window(); } @@ -312,8 +291,9 @@ void RecordMonitorGUI::create_objects() driver == VIDEO4LINUX2MPEG || driver == CAPTURE_JPEG_WEBCAM || driver == CAPTURE_YUYV_WEBCAM); + int do_cursor = driver == SCREENCAPTURE; int do_scopes = do_channel || driver == SCREENCAPTURE; - int do_interlace = (driver == VIDEO4LINUX2JPEG); + int do_interlace = driver == VIDEO4LINUX2JPEG; int background_done = 0; int do_audio = record->default_asset->audio_data; int do_video = record->default_asset->video_data; @@ -399,13 +379,23 @@ void RecordMonitorGUI::create_objects() x += reverse_interlace->get_w() + mwindow->theme->widget_border; } - if(do_scopes) - { + if( do_scopes ) { scope_toggle = new ScopeEnable(mwindow, thread, x, y); add_subwindow(scope_toggle); x += scope_toggle->get_w() + mwindow->theme->widget_border; } + if( do_cursor ) { + add_subwindow(cursor_toggle = new DoCursor(record, + x, + y)); + x += cursor_toggle->get_w() + mwindow->theme->widget_border; + add_subwindow(big_cursor_toggle = new DoBigCursor(record, + x, + y)); + x += big_cursor_toggle->get_w() + mwindow->theme->widget_border; + } + add_subwindow(monitor_menu = new BC_PopupMenu(0, 0, 0, "", 0)); monitor_menu->add_item(new RecordMonitorFullsize(mwindow, this)); } @@ -469,10 +459,8 @@ int RecordMonitorGUI::button_release_event() int RecordMonitorGUI::cursor_motion_event() { -//SET_TRACE if( canvas && canvas->get_canvas() ) { canvas->get_canvas()->unhide_cursor(); -//SET_TRACE return canvas->cursor_motion_event(); } return 0; @@ -588,11 +576,25 @@ int RecordMonitorGUI::resize_event(int w, int h) } #endif - if(channel_picker) channel_picker->reposition(); - if(reverse_interlace) reverse_interlace->reposition_window(reverse_interlace->get_x(), - reverse_interlace->get_y()); - if(canvas && do_video) - { + + if( channel_picker ) { + channel_picker->reposition(); + } + if( reverse_interlace ) { + reverse_interlace->reposition_window( + reverse_interlace->get_x(), + reverse_interlace->get_y()); + } + if( cursor_toggle ) { + cursor_toggle->reposition_window( + cursor_toggle->get_x(), + cursor_toggle->get_y()); + big_cursor_toggle->reposition_window( + big_cursor_toggle->get_x(), + big_cursor_toggle->get_y()); + } + + if( canvas && do_video ) { canvas->reposition_window(0, mwindow->theme->rmonitor_canvas_x, mwindow->theme->rmonitor_canvas_y, @@ -600,14 +602,14 @@ int RecordMonitorGUI::resize_event(int w, int h) mwindow->theme->rmonitor_canvas_h); } - if(do_meters) { + if( do_meters ) { meters->reposition_window(mwindow->theme->rmonitor_meter_x, mwindow->theme->rmonitor_meter_y, do_video ? -1 : mwindow->theme->rmonitor_meter_w, mwindow->theme->rmonitor_meter_h); meters->set_meters(record->default_asset->channels,1); } - else if(meters) { + else if( meters ) { meters->set_meters(0,0); } @@ -665,6 +667,41 @@ int RecordMonitorGUI::create_bitmap() return 0; } + +DoCursor::DoCursor(Record *record, int x, int y) + : BC_CheckBox(x, y, record->do_cursor, _("Record cursor")) +{ + this->record = record; +} + +DoCursor::~DoCursor() +{ +} + +int DoCursor::handle_event() +{ + record->do_cursor = get_value(); + return 0; +} + + +DoBigCursor::DoBigCursor(Record *record, int x, int y) + : BC_CheckBox(x, y, record->do_big_cursor, _("Big cursor")) +{ + this->record = record; +} + +DoBigCursor::~DoBigCursor() +{ +} + +int DoBigCursor::handle_event() +{ + record->do_big_cursor = get_value(); + return 0; +} + + void RecordMonitorGUI::enable_signal_status(int enable) { #ifdef HAVE_DVB @@ -1079,7 +1116,9 @@ int RecordMonitorThread::render_frame() void RecordMonitorThread::new_output_frame() { - record_monitor->device->new_output_buffer(&output_frame, output_colormodel); + record_monitor->device->new_output_buffer(&output_frame, + output_colormodel, + record->edl); } void RecordMonitorThread:: diff --git a/cinelerra-5.1/cinelerra/recordmonitor.h b/cinelerra-5.1/cinelerra/recordmonitor.h index ac3bd1d6..65bf732d 100644 --- a/cinelerra-5.1/cinelerra/recordmonitor.h +++ b/cinelerra-5.1/cinelerra/recordmonitor.h @@ -86,6 +86,8 @@ public: class ReverseInterlace; class RecordMonitorCanvas; +class DoCursor; +class DoBigCursor; class RecordMonitorGUI : public BC_Window { @@ -113,6 +115,8 @@ public: #endif RecordChannelPicker *channel_picker; ScopeEnable *scope_toggle; + DoCursor *cursor_toggle; + DoBigCursor *big_cursor_toggle; ReverseInterlace *reverse_interlace; int cursor_x_origin, cursor_y_origin; int translate_x_origin, translate_y_origin; @@ -235,6 +239,24 @@ public: Record *record; }; +class DoCursor : public BC_CheckBox +{ +public: + DoCursor(Record *record, int x, int y); + ~DoCursor(); + int handle_event(); + Record *record; +}; + +class DoBigCursor : public BC_CheckBox +{ +public: + DoBigCursor(Record *record, int x, int y); + ~DoBigCursor(); + int handle_event(); + Record *record; +}; + class ReverseInterlace : public BC_CheckBox { public: diff --git a/cinelerra-5.1/cinelerra/recordprefs.C b/cinelerra-5.1/cinelerra/recordprefs.C index 6ff61825..5851eb90 100644 --- a/cinelerra-5.1/cinelerra/recordprefs.C +++ b/cinelerra-5.1/cinelerra/recordprefs.C @@ -54,18 +54,21 @@ RecordPrefs::~RecordPrefs() void RecordPrefs::create_objects() { - int x, y, x2; + int x, y, x1, x2; char string[BCTEXTLEN]; BC_Resources *resources = BC_WindowBase::get_resources(); BC_Title *title; + BC_Title *title0, *title1, *title2, *title3; + BC_TextBox *textbox; x = mwindow->theme->preferencesoptions_x; y = mwindow->theme->preferencesoptions_y; + int margin = mwindow->theme->widget_border; int x0 = x, y0 = y; add_subwindow(title = new BC_Title(x, y, _("File Format:"), LARGEFONT, resources->text_default)); - y += title->get_h() + 5; + y += title->get_h() + margin; recording_format = new FormatTools(mwindow, this, pwindow->thread->edl->session->recording_format); @@ -87,26 +90,24 @@ void RecordPrefs::create_objects() add_subwindow(realtime_toc); // Audio hardware - add_subwindow(new BC_Bar(5, y, get_w() - 10)); - y += 5; + add_subwindow(new BC_Bar(x, y, get_w() - x * 2)); + y += margin; add_subwindow(title = new BC_Title(x, y, _("Audio In"), LARGEFONT, resources->text_default)); - y += title->get_h() + 5; + y += title->get_h() + margin; add_subwindow(new BC_Title(x, y, _("Record Driver:"), MEDIUMFONT, resources->text_default)); audio_in_device = new ADevicePrefs(x + 110, y, pwindow, this, 0, pwindow->thread->edl->session->aconfig_in, MODERECORD); audio_in_device->initialize(1); - y += audio_in_device->get_h(1); + y += audio_in_device->get_h(1) + margin; - BC_TextBox *textbox; - BC_Title *title0, *title1, *title2, *title3; int pad = RecordWriteLength::calculate_h(this, MEDIUMFONT, 1, @@ -116,9 +117,9 @@ void RecordPrefs::create_objects() add_subwindow(title1 = new BC_Title(x, y + pad, _("Samples to write to disk:"))); add_subwindow(title2 = new BC_Title(x, y + pad * 2, _("Sample rate for recording:"))); add_subwindow(title3 = new BC_Title(x, y + pad * 3, _("Channels to record:"))); - x2 = MAX(title0->get_w(), title1->get_w()) + mwindow->theme->widget_border; - x2 = MAX(x2, title2->get_w() + mwindow->theme->widget_border); - x2 = MAX(x2, title3->get_w() + mwindow->theme->widget_border); + x2 = MAX(title0->get_w(), title1->get_w()) + margin; + x2 = MAX(x2, title2->get_w() + margin); + x2 = MAX(x2, title3->get_w() + margin); sprintf(string, "%ld", (long)pwindow->thread->edl->session->record_fragment_size); @@ -173,31 +174,36 @@ void RecordPrefs::create_objects() // Video hardware add_subwindow(new BC_Bar(5, y, get_w() - 10)); - y += 5; + y += margin; - add_subwindow(new BC_Title(x, y, _("Video In"), LARGEFONT, + add_subwindow(title1 = new BC_Title(x, y, _("Video In"), LARGEFONT, resources->text_default)); - y += 25; + y += title1->get_h() + margin; - add_subwindow(new BC_Title(x, y, _("Record Driver:"), MEDIUMFONT, + add_subwindow(title1 = new BC_Title(x, y, _("Record Driver:"), MEDIUMFONT, resources->text_default)); - video_in_device = new VDevicePrefs(x + 110, y, pwindow, this, 0, - pwindow->thread->edl->session->vconfig_in, MODERECORD); + video_in_device = new VDevicePrefs(x + title1->get_w() + margin, y, + pwindow, this, 0, pwindow->thread->edl->session->vconfig_in, MODERECORD); video_in_device->initialize(1); + y += video_in_device->get_h() + margin; - y += 55; + add_subwindow(title1 = new BC_Title(x, y, _("Frames to record to disk at a time:"))); + x1 = x + title1->get_w() + margin; sprintf(string, "%d", pwindow->thread->edl->session->video_write_length); - add_subwindow(textbox = new VideoWriteLength(pwindow, string, y)); - add_subwindow(new CaptureLengthTumbler(pwindow, textbox, textbox->get_x() + textbox->get_w(), y)); - add_subwindow(new BC_Title(x, y, _("Frames to record to disk at a time:"))); + add_subwindow(textbox = new VideoWriteLength(pwindow, string, x1, y)); + x1 += textbox->get_w() + margin; + add_subwindow(new CaptureLengthTumbler(pwindow, textbox, x1, y)); y += 27; + + add_subwindow(title1 = new BC_Title(x, y, _("Frames to buffer in device:"))); + x1 = x + title1->get_w() + margin; sprintf(string, "%d", pwindow->thread->edl->session->vconfig_in->capture_length); - add_subwindow(textbox = new VideoCaptureLength(pwindow, string, y)); - add_subwindow(new CaptureLengthTumbler(pwindow, textbox, textbox->get_x() + textbox->get_w(), y)); - add_subwindow(new BC_Title(x, y, _("Frames to buffer in device:"))); + add_subwindow(textbox = new VideoCaptureLength(pwindow, string, x1, y)); + x1 += textbox->get_w() + margin; + add_subwindow(new CaptureLengthTumbler(pwindow, textbox, x1, y)); y += 27; - int x1 = x; + x1 = x; add_subwindow(new BC_Title(x1, y, _("Positioning:"))); x1 += 100; add_subwindow(textbox = new BC_TextBox(x1, y, 200, 1, "")); @@ -212,23 +218,24 @@ void RecordPrefs::create_objects() y += 35; BC_TextBox *w_text, *h_text; - add_subwindow(new BC_Title(x, y, _("Size of captured frame:"))); - x += 170; + add_subwindow(title1 = new BC_Title(x, y, _("Size of captured frame:"))); + x += title1->get_w() + margin; add_subwindow(w_text = new RecordW(pwindow, x, y)); - x += w_text->get_w() + 2; - add_subwindow(new BC_Title(x, y, "x")); - x += 10; + x += w_text->get_w() + margin; + add_subwindow(title1 = new BC_Title(x, y, "x")); + x += title1->get_w() + margin; add_subwindow(h_text = new RecordH(pwindow, x, y)); - x += h_text->get_w(); - add_subwindow(new FrameSizePulldown(mwindow->theme, + x += h_text->get_w() + margin; + FrameSizePulldown *tumbler; + add_subwindow(tumbler = new FrameSizePulldown(mwindow->theme, w_text, h_text, x, y)); + y += tumbler->get_h() + margin; - y += 30; - x = 5; - add_subwindow(new BC_Title(x, y, _("Frame rate for recording:"))); - x += 180; + x = mwindow->theme->preferencesoptions_x; + add_subwindow(title1 = new BC_Title(x, y, _("Frame rate for recording:"))); + x += title1->get_w() + margin; add_subwindow(textbox = new RecordFrameRate(pwindow, x, y)); - x += 75; + x += textbox->get_w() + margin; add_subwindow(new FrameRatePulldown(mwindow, textbox, x, y)); } @@ -377,7 +384,7 @@ int RecordH::handle_event() } RecordFrameRate::RecordFrameRate(PreferencesWindow *pwindow, int x, int y) - : BC_TextBox(x, y, 70, 1, pwindow->thread->edl->session->vconfig_in->in_framerate) + : BC_TextBox(x, y, 140, 1, pwindow->thread->edl->session->vconfig_in->in_framerate) { this->pwindow = pwindow; } @@ -420,8 +427,8 @@ int RecordGain::handle_event() -VideoWriteLength::VideoWriteLength(PreferencesWindow *pwindow, char *text, int y) - : BC_TextBox(260, y, 100, 1, text) +VideoWriteLength::VideoWriteLength(PreferencesWindow *pwindow, char *text, int x, int y) + : BC_TextBox(x, y, 100, 1, text) { this->pwindow = pwindow; } @@ -433,8 +440,8 @@ int VideoWriteLength::handle_event() } -VideoCaptureLength::VideoCaptureLength(PreferencesWindow *pwindow, char *text, int y) - : BC_TextBox(260, y, 100, 1, text) +VideoCaptureLength::VideoCaptureLength(PreferencesWindow *pwindow, char *text, int x, int y) + : BC_TextBox(x, y, 100, 1, text) { this->pwindow = pwindow; } diff --git a/cinelerra-5.1/cinelerra/recordprefs.h b/cinelerra-5.1/cinelerra/recordprefs.h index e8dbd437..81f6fe88 100644 --- a/cinelerra-5.1/cinelerra/recordprefs.h +++ b/cinelerra-5.1/cinelerra/recordprefs.h @@ -138,7 +138,7 @@ public: class VideoWriteLength : public BC_TextBox { public: - VideoWriteLength(PreferencesWindow *pwindow, char *text, int y); + VideoWriteLength(PreferencesWindow *pwindow, char *text, int x, int y); int handle_event(); PreferencesWindow *pwindow; }; @@ -146,7 +146,7 @@ public: class VideoCaptureLength : public BC_TextBox { public: - VideoCaptureLength(PreferencesWindow *pwindow, char *text, int y); + VideoCaptureLength(PreferencesWindow *pwindow, char *text, int x, int y); int handle_event(); PreferencesWindow *pwindow; }; diff --git a/cinelerra-5.1/cinelerra/recordscopes.C b/cinelerra-5.1/cinelerra/recordscopes.C index 7004d454..65f50b1e 100644 --- a/cinelerra-5.1/cinelerra/recordscopes.C +++ b/cinelerra-5.1/cinelerra/recordscopes.C @@ -21,7 +21,7 @@ #include "bctheme.h" -#include "cicolors.h" +#include "bccolors.h" #include "language.h" #include "mainsession.h" #include "mutex.h" diff --git a/cinelerra-5.1/cinelerra/recordvideo.C b/cinelerra-5.1/cinelerra/recordvideo.C index 2abd343a..91b5971b 100644 --- a/cinelerra-5.1/cinelerra/recordvideo.C +++ b/cinelerra-5.1/cinelerra/recordvideo.C @@ -196,6 +196,7 @@ void RecordVideo::run() VideoDevice *vdevice = record->vdevice; VFrame *capture_frame = get_buffer(); vdevice->set_field_order(record->reverse_interlace); + record->set_do_cursor(); // Capture a frame grab_result = read_buffer(capture_frame); if( done ) break; diff --git a/cinelerra-5.1/cinelerra/recordwindow.h b/cinelerra-5.1/cinelerra/recordwindow.h index 9f24048f..1452c0e0 100644 --- a/cinelerra-5.1/cinelerra/recordwindow.h +++ b/cinelerra-5.1/cinelerra/recordwindow.h @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams + * Copyright (C) 2008-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cinelerra-5.1/cinelerra/remotecontrol.C b/cinelerra-5.1/cinelerra/remotecontrol.C index b668e978..1fa93d9c 100644 --- a/cinelerra-5.1/cinelerra/remotecontrol.C +++ b/cinelerra-5.1/cinelerra/remotecontrol.C @@ -1,5 +1,5 @@ -#include "colors.h" +#include "bccolors.h" #include "mainsession.h" #include "mwindow.h" #include "mwindowgui.h" diff --git a/cinelerra-5.1/cinelerra/render.C b/cinelerra-5.1/cinelerra/render.C index 085384ae..702ffbd4 100644 --- a/cinelerra-5.1/cinelerra/render.C +++ b/cinelerra-5.1/cinelerra/render.C @@ -970,7 +970,7 @@ if(debug) printf("Render::render %d\n", __LINE__); ArrayList *assets = render->packages->get_asset_list(); if(debug) printf("Render::render %d\n", __LINE__); if(render->load_mode == LOADMODE_PASTE) - mwindow->clear(0); + mwindow->clear(0, 1); if(debug) printf("Render::render %d\n", __LINE__); mwindow->load_assets(assets, -1, render->load_mode, 0, 0, mwindow->edl->session->labels_follow_edits, diff --git a/cinelerra-5.1/cinelerra/savefile.C b/cinelerra-5.1/cinelerra/savefile.C index 936bd4d5..8b3bc74a 100644 --- a/cinelerra-5.1/cinelerra/savefile.C +++ b/cinelerra-5.1/cinelerra/savefile.C @@ -130,7 +130,7 @@ int Save::save_before_quit() } SaveAs::SaveAs(MWindow *mwindow) - : BC_MenuItem(_("Save as..."), ""), Thread() + : BC_MenuItem(_("Save as..."), "Shift-S", 'S'), Thread() { this->mwindow = mwindow; quit_now = 0; diff --git a/cinelerra-5.1/cinelerra/scopewindow.C b/cinelerra-5.1/cinelerra/scopewindow.C index fb3c0198..56dd5171 100644 --- a/cinelerra-5.1/cinelerra/scopewindow.C +++ b/cinelerra-5.1/cinelerra/scopewindow.C @@ -19,7 +19,7 @@ */ #include "bcsignals.h" -#include "cicolors.h" +#include "bccolors.h" #include "clip.h" #include "cursors.h" #include "language.h" diff --git a/cinelerra-5.1/cinelerra/signalstatus.C b/cinelerra-5.1/cinelerra/signalstatus.C index 7963fa34..8e221618 100644 --- a/cinelerra-5.1/cinelerra/signalstatus.C +++ b/cinelerra-5.1/cinelerra/signalstatus.C @@ -1,7 +1,7 @@ #ifdef HAVE_DVB #include "bctitle.h" -#include "colors.h" +#include "bccolors.h" #include "devicedvbinput.h" #include "fonts.h" #include "signalstatus.h" diff --git a/cinelerra-5.1/cinelerra/testwindow.h b/cinelerra-5.1/cinelerra/testwindow.h index 8d06c956..929eb7ec 100644 --- a/cinelerra-5.1/cinelerra/testwindow.h +++ b/cinelerra-5.1/cinelerra/testwindow.h @@ -3,7 +3,7 @@ #include "bcwindow.h" #include "bcsignals.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "thread.h" diff --git a/cinelerra-5.1/cinelerra/theme.C b/cinelerra-5.1/cinelerra/theme.C index 20f8b36b..bddba878 100644 --- a/cinelerra-5.1/cinelerra/theme.C +++ b/cinelerra-5.1/cinelerra/theme.C @@ -22,7 +22,7 @@ #include "awindowgui.h" #include "bcsignals.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include "cwindowgui.h" #include "edl.h" #include "edlsession.h" @@ -85,6 +85,7 @@ Theme::Theme() play_h = 22; title_h = 23; clock_bg_color = BLACK; + clock_fg_color = GREEN; assetedit_color = YELLOW; const char *cp = getenv("BC_USE_COMMERCIALS"); use_commercials = !cp ? 0 : atoi(cp); @@ -264,43 +265,20 @@ void Theme::build_menus() frame_sizes.append(new BC_ListBoxItem("128x96")); frame_sizes.append(new BC_ListBoxItem("160x120")); - frame_sizes.append(new BC_ListBoxItem("176x144")); - frame_sizes.append(new BC_ListBoxItem("240x180")); - frame_sizes.append(new BC_ListBoxItem("320x200")); frame_sizes.append(new BC_ListBoxItem("320x240")); - frame_sizes.append(new BC_ListBoxItem("352x288")); frame_sizes.append(new BC_ListBoxItem("360x240")); frame_sizes.append(new BC_ListBoxItem("400x300")); - frame_sizes.append(new BC_ListBoxItem("424x318")); - frame_sizes.append(new BC_ListBoxItem("512x384")); - frame_sizes.append(new BC_ListBoxItem("640x350")); + frame_sizes.append(new BC_ListBoxItem("640x400")); frame_sizes.append(new BC_ListBoxItem("640x480")); - frame_sizes.append(new BC_ListBoxItem("704x576")); frame_sizes.append(new BC_ListBoxItem("720x480")); - frame_sizes.append(new BC_ListBoxItem("720x576")); frame_sizes.append(new BC_ListBoxItem("800x600")); - frame_sizes.append(new BC_ListBoxItem("852x480")); - frame_sizes.append(new BC_ListBoxItem("852x480")); - frame_sizes.append(new BC_ListBoxItem("960x540")); - frame_sizes.append(new BC_ListBoxItem("960x1080")); frame_sizes.append(new BC_ListBoxItem("1024x768")); frame_sizes.append(new BC_ListBoxItem("1280x720")); frame_sizes.append(new BC_ListBoxItem("1280x1024")); - frame_sizes.append(new BC_ListBoxItem("1368x768")); - frame_sizes.append(new BC_ListBoxItem("1408x1152")); - frame_sizes.append(new BC_ListBoxItem("1600x1024")); frame_sizes.append(new BC_ListBoxItem("1600x1200")); frame_sizes.append(new BC_ListBoxItem("1920x1080")); - frame_sizes.append(new BC_ListBoxItem("1920x1088")); - frame_sizes.append(new BC_ListBoxItem("1920x1200")); - frame_sizes.append(new BC_ListBoxItem("2048x1536")); - frame_sizes.append(new BC_ListBoxItem("2560x1600")); - frame_sizes.append(new BC_ListBoxItem("2560x2048")); - frame_sizes.append(new BC_ListBoxItem("3200x2048")); - frame_sizes.append(new BC_ListBoxItem("3840x2400")); - frame_sizes.append(new BC_ListBoxItem("5120x4096")); - frame_sizes.append(new BC_ListBoxItem("6400x4096")); - frame_sizes.append(new BC_ListBoxItem("7680x4800")); + frame_sizes.append(new BC_ListBoxItem("3840x2160")); + frame_sizes.append(new BC_ListBoxItem("4096x1720")); sample_rates.append(new BC_ListBoxItem("8000")); sample_rates.append(new BC_ListBoxItem("16000")); @@ -311,6 +289,7 @@ void Theme::build_menus() sample_rates.append(new BC_ListBoxItem("96000")); sample_rates.append(new BC_ListBoxItem("192000")); + frame_rates.append(new BC_ListBoxItem("0.25")); frame_rates.append(new BC_ListBoxItem("1")); frame_rates.append(new BC_ListBoxItem("5")); frame_rates.append(new BC_ListBoxItem("10")); @@ -324,6 +303,9 @@ void Theme::build_menus() frame_rates.append(new BC_ListBoxItem("50")); frame_rates.append(new BC_ListBoxItem("59.94")); frame_rates.append(new BC_ListBoxItem("60")); + frame_rates.append(new BC_ListBoxItem("100")); + frame_rates.append(new BC_ListBoxItem("120")); + frame_rates.append(new BC_ListBoxItem("1000")); char string[BCTEXTLEN]; for(int i = 1; i < 17; i++) @@ -592,9 +574,9 @@ void Theme::get_mwindow_sizes(MWindowGUI *gui, int w, int h) mbuttons_y = gui->menu_h() + 1; mbuttons_w = gui->menu_w(); mbuttons_h = get_image("mbutton_bg")->get_h(); - mclock_x = 10; - mclock_y = mbuttons_y - 1 + mbuttons_h + widget_border; - mclock_w = get_image("clock_bg")->get_w() - 40; + mclock_x = window_border - 5; + mclock_y = mbuttons_y - 1 + mbuttons_h; + mclock_w = get_image("clock_bg")->get_w() - 20; mclock_h = get_image("clock_bg")->get_h(); mtimebar_x = get_image("patchbay_bg")->get_w(); mtimebar_y = mbuttons_y - 1 + mbuttons_h; @@ -1175,40 +1157,106 @@ void Theme::get_plugindialog_sizes() void Theme::get_keyframedialog_sizes(KeyFrameWindow *gui) { - int x = widget_border; - int y = window_border + - BC_Title::calculate_h(gui, "P", LARGEFONT) + + int x = window_border; + int y = window_border + + BC_Title::calculate_h(gui, "P", LARGEFONT) + + widget_border; + + presets_list_x = x; + presets_list_y = y; +#ifdef EDIT_KEYFRAME + presets_list_w = mwindow->session->keyframedialog_w / 2 - + widget_border - + window_border; +#else + presets_list_w = mwindow->session->keyframedialog_w - + presets_list_x - + window_border; +#endif + presets_list_h = mwindow->session->keyframedialog_h - + BC_OKButton::calculate_h() - + presets_list_y - + widget_border - + widget_border - + BC_Title::calculate_h(gui, "P") - + widget_border - + BC_TextBox::calculate_h(gui, + MEDIUMFONT, + 1, + 1) - + widget_border - + (BC_GenericButton::calculate_h() + widget_border) * 3 - + window_border; + y += presets_list_h + widget_border + widget_border + BC_Title::calculate_h(gui, "P"); + presets_text_x = x; + presets_text_y = y; + presets_text_w = presets_list_w; + y += BC_TextBox::calculate_h(gui, + MEDIUMFONT, + 1, + 1) + widget_border; + + presets_delete_x = presets_text_x; + presets_delete_y = y; + y += BC_GenericButton::calculate_h() + widget_border; + + presets_save_x = presets_text_x; + presets_save_y = y; + y += BC_GenericButton::calculate_h() + widget_border; + + presets_apply_x = presets_text_x; + presets_apply_y = y; + y += BC_GenericButton::calculate_h(); + +#ifdef EDIT_KEYFRAME + x = mwindow->session->keyframedialog_w / 2 + widget_border; + y = window_border + + BC_Title::calculate_h(gui, "P", LARGEFONT) + widget_border; keyframe_list_x = x; keyframe_list_y = y; - keyframe_list_w = mwindow->session->keyframedialog_w - widget_border * 2; - keyframe_list_h = mwindow->session->keyframedialog_h - widget_border - - widget_border - keyframe_list_y - BC_Title::calculate_h(gui, "P") - - widget_border - BC_TextBox::calculate_h(gui, MEDIUMFONT, 1, 1) - - widget_border - BC_Title::calculate_h(gui, "P") - - widget_border - BC_OKButton::calculate_h() - + keyframe_list_w = mwindow->session->keyframedialog_w / 2 - + widget_border - + window_border; + keyframe_list_h = mwindow->session->keyframedialog_h - + keyframe_list_y - + widget_border - + widget_border - + BC_Title::calculate_h(gui, "P") - + widget_border - + BC_TextBox::calculate_h(gui, + MEDIUMFONT, + 1, + 1) - + widget_border - + BC_Title::calculate_h(gui, "P") - + widget_border - + BC_OKButton::calculate_h() - window_border; // keyframe_text_x = keyframe_list_x + keyframe_list_w + widget_border; // keyframe_text_y = y; // keyframe_text_w = mwindow->session->keyframedialog_w - keyframe_text_x - window_border; -// y += BC_TextBox::calculate_h(gui, -// MEDIUMFONT, -// 1, +// y += BC_TextBox::calculate_h(gui, +// MEDIUMFONT, +// 1, // 1) + widget_border; -// +// y += keyframe_list_h + BC_Title::calculate_h(gui, "P") + widget_border + widget_border; keyframe_value_x = keyframe_list_x; keyframe_value_y = y; keyframe_value_w = keyframe_list_w; - y += BC_TextBox::calculate_h(gui, - MEDIUMFONT, - 1, + y += BC_TextBox::calculate_h(gui, + MEDIUMFONT, + 1, 1) + widget_border; keyframe_all_x = keyframe_value_x; keyframe_all_y = y; + +#endif + } diff --git a/cinelerra-5.1/cinelerra/theme.h b/cinelerra-5.1/cinelerra/theme.h index 06cb17a7..009f396f 100644 --- a/cinelerra-5.1/cinelerra/theme.h +++ b/cinelerra-5.1/cinelerra/theme.h @@ -237,6 +237,12 @@ public: int plugindialog_sharedattach_x, plugindialog_sharedattach_y; int plugindialog_moduleattach_x, plugindialog_moduleattach_y; + int presets_list_x, presets_list_y, presets_list_w, presets_list_h; + int presets_text_x, presets_text_y, presets_text_w; + int presets_delete_x, presets_delete_y; + int presets_save_x, presets_save_y; + int presets_apply_x, presets_apply_y; + int keyframe_list_x, keyframe_list_y, keyframe_list_w, keyframe_list_h; int keyframe_text_x, keyframe_text_y, keyframe_text_w, keyframe_text_h; int keyframe_value_x, keyframe_value_y, keyframe_value_w, keyframe_value_h; @@ -287,6 +293,7 @@ public: int window_border; int widget_border; int clock_bg_color; + int clock_fg_color; int use_commercials; // Bitmaps diff --git a/cinelerra-5.1/cinelerra/track.C b/cinelerra-5.1/cinelerra/track.C index ae7d1049..f3852cf9 100644 --- a/cinelerra-5.1/cinelerra/track.C +++ b/cinelerra-5.1/cinelerra/track.C @@ -1150,17 +1150,9 @@ int Track::copy_assets(double start, } - - - -int Track::clear(double start, - double end, - int edit_edits, - int edit_labels, - int edit_plugins, - int edit_autos, - int convert_units, - Edits *trim_edits) +int Track::clear(double start, double end, + int edit_edits, int edit_labels, int edit_plugins, + int edit_autos, int convert_units, Edits *trim_edits) { // Edits::move_auto calls this routine after the units are converted to the track // format. diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index 740dea55..feff8a85 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -26,7 +26,7 @@ #include "bcsignals.h" #include "bctimer.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include "cplayback.h" #include "cursors.h" #include "cwindowgui.h" @@ -4431,7 +4431,7 @@ int TrackCanvas::do_tracks(int cursor_x, int cursor_y, int button_press) int64_t track_x, track_y, track_w, track_h; track_dimensions(track, track_x, track_y, track_w, track_h); - if(button_press && get_buttonpress() == 3 && + if(button_press && get_buttonpress() == RIGHT_BUTTON && cursor_y >= track_y && cursor_y < track_y + track_h) { gui->edit_menu->update(track, 0); gui->edit_menu->activate_menu(); diff --git a/cinelerra-5.1/cinelerra/tracksedit.C b/cinelerra-5.1/cinelerra/tracksedit.C index 971a005f..9fdf4f63 100644 --- a/cinelerra-5.1/cinelerra/tracksedit.C +++ b/cinelerra-5.1/cinelerra/tracksedit.C @@ -61,10 +61,10 @@ int Tracks::clear(double start, double end, int clear_plugins, int edit_autos) end, 1, // edits 1, // labels - clear_plugins, + clear_plugins, // edit_plugins edit_autos, - 1, - 0); + 1, // convert_units + 0); // trim_edits } } return 0; diff --git a/cinelerra-5.1/cinelerra/vautomation.C b/cinelerra-5.1/cinelerra/vautomation.C index 70df4e74..0197fa4d 100644 --- a/cinelerra-5.1/cinelerra/vautomation.C +++ b/cinelerra-5.1/cinelerra/vautomation.C @@ -20,7 +20,7 @@ */ #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include "edl.h" #include "edlsession.h" #include "floatauto.h" diff --git a/cinelerra-5.1/cinelerra/vdevice1394.C b/cinelerra-5.1/cinelerra/vdevice1394.C index c61387c9..8f3872e7 100644 --- a/cinelerra-5.1/cinelerra/vdevice1394.C +++ b/cinelerra-5.1/cinelerra/vdevice1394.C @@ -234,7 +234,8 @@ int VDevice1394::read_buffer(VFrame *frame) void VDevice1394::new_output_buffer(VFrame **output, - int colormodel) + int colormodel, + EDL *edl) { if(user_frame) { diff --git a/cinelerra-5.1/cinelerra/vdevice1394.h b/cinelerra-5.1/cinelerra/vdevice1394.h index 9ca35612..14927e4b 100644 --- a/cinelerra-5.1/cinelerra/vdevice1394.h +++ b/cinelerra-5.1/cinelerra/vdevice1394.h @@ -53,7 +53,7 @@ public: void initialize(); int can_copy_from(Asset *asset, int output_w, int output_h); // int stop_sharing(); - void new_output_buffer(VFrame **output, int colormodel); + void new_output_buffer(VFrame **output, int colormodel, EDL *edl); void encrypt(unsigned char *output, unsigned char *data, int data_size); private: diff --git a/cinelerra-5.1/cinelerra/vdevicebase.h b/cinelerra-5.1/cinelerra/vdevicebase.h index ba29bea4..4b388f53 100644 --- a/cinelerra-5.1/cinelerra/vdevicebase.h +++ b/cinelerra-5.1/cinelerra/vdevicebase.h @@ -45,7 +45,7 @@ public: virtual int create_channeldb(ArrayList *channeldb) { return 1; }; virtual int read_buffer(VFrame *frame) { return 1; }; virtual int write_buffer(VFrame *output, EDL *edl) { return 1; }; - virtual void new_output_buffer(VFrame **output, int colormodel) {}; + virtual void new_output_buffer(VFrame **output, int colormodel, EDL *edl) {}; virtual ArrayList* get_render_strategies() { return 0; }; virtual int get_shared_data(unsigned char *data, long size) { return 0; }; virtual int stop_sharing() { return 0; }; diff --git a/cinelerra-5.1/cinelerra/vdeviceprefs.C b/cinelerra-5.1/cinelerra/vdeviceprefs.C index beada605..d20c0587 100644 --- a/cinelerra-5.1/cinelerra/vdeviceprefs.C +++ b/cinelerra-5.1/cinelerra/vdeviceprefs.C @@ -22,6 +22,7 @@ #include "bcsignals.h" #include "channeldb.h" #include "channelpicker.h" +#include "clip.h" #include "edl.h" #include "edlsession.h" #include "formattools.h" @@ -37,6 +38,7 @@ #include "preferencesthread.h" #include "recordconfig.h" #include "recordprefs.h" +#include "theme.h" #include @@ -94,6 +96,7 @@ void VDevicePrefs::reset_objects() firewire_path = 0; fields_title = 0; device_fields = 0; + use_direct_x11 = 0; channel_picker = 0; } @@ -181,6 +184,7 @@ int VDevicePrefs::delete_objects() delete dvb_adapter_device; delete follow_video_config; delete dvb_adapter_title; + delete use_direct_x11; delete port_title; @@ -198,6 +202,13 @@ int VDevicePrefs::delete_objects() return 0; } +int VDevicePrefs::get_h() +{ + int margin = pwindow->mwindow->theme->widget_border; + return BC_Title::calculate_h(dialog, "X", MEDIUMFONT) + margin + + BC_TextBox::calculate_h(dialog, MEDIUMFONT, 1, 1); +} + void VDevicePrefs::create_dvb_objs() { int x1 = x + menu->get_w() + 30; @@ -332,7 +343,7 @@ int VDevicePrefs::create_v4l2jpeg_objs() char *output_char = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_device[0]; dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default)); dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char)); - x1 += max(device_title->get_w(),device_text->get_w()) + 5; + x1 += bmax(device_title->get_w(),device_text->get_w()) + 5; int *output_int = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_fields; fields_title = new BC_Title(x1, y, _("Fields:"), MEDIUMFONT, resources->text_default); dialog->add_subwindow(fields_title); @@ -373,7 +384,6 @@ int VDevicePrefs::create_x11_objs() { char *output_char; BC_Resources *resources = BC_WindowBase::get_resources(); - int x1 = x + menu->get_w() + 5; output_char = out_config->x11_host; const char *x11_display; switch( pwindow->thread->current_dialog ) { @@ -385,9 +395,21 @@ int VDevicePrefs::create_x11_objs() x11_display = _("Default B Display:"); break; break; } - dialog->add_subwindow(device_title = new BC_Title(x1, y, x11_display, + int x1 = menu->get_x() + menu->get_w() + 10; + int y1 = menu->get_y(); + if( driver == PLAYBACK_X11 ) y1 -= 10; + dialog->add_subwindow(device_title = new BC_Title(x1, y1+4, x11_display, MEDIUMFONT, resources->text_default)); - dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char)); + int x2 = x1 + device_title->get_w() + 10, dy = device_title->get_h(); + dialog->add_subwindow(device_text = new VDeviceTextBox(x2, y1, output_char)); + if( driver == PLAYBACK_X11 ) { + int y2 = device_text->get_h(); + if( dy < y2 ) dy = y2; + y1 += dy + 5; + use_direct_x11 = new BC_CheckBox(x1, y1, + &out_config->use_direct_x11, _("use direct x11 render if possible")); + dialog->add_subwindow(use_direct_x11); + } return 0; } diff --git a/cinelerra-5.1/cinelerra/vdeviceprefs.h b/cinelerra-5.1/cinelerra/vdeviceprefs.h index 06c1fa84..c29d9325 100644 --- a/cinelerra-5.1/cinelerra/vdeviceprefs.h +++ b/cinelerra-5.1/cinelerra/vdeviceprefs.h @@ -61,7 +61,7 @@ public: int initialize(int creation /* = 0 */); int delete_objects(); void reset_objects(); - static int max(int a,int b) { return a>b ? a : b; } + int get_h(); PreferencesWindow *pwindow; PreferencesDialog *dialog; @@ -84,6 +84,7 @@ private: BC_Title *device_title; BC_Title *port_title; BC_CheckBox *follow_video_config; + BC_CheckBox *use_direct_x11; BC_Title *channel_title; BC_Title *output_title; BC_Title *syt_title; diff --git a/cinelerra-5.1/cinelerra/vdevicex11.C b/cinelerra-5.1/cinelerra/vdevicex11.C index 31873e6a..793047ac 100644 --- a/cinelerra-5.1/cinelerra/vdevicex11.C +++ b/cinelerra-5.1/cinelerra/vdevicex11.C @@ -1,35 +1,37 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams - * + * Copyright (C) 2008-2017 Adam Williams + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #include "assets.h" -#include "auto.h" +#include "autos.h" #include "bccapture.h" +#include "bccmodels.h" #include "bcsignals.h" #include "canvas.h" -#include "bccmodels.h" #include "edl.h" #include "edlsession.h" -#include "maskautos.h" +#include "file.h" #include "maskauto.h" +#include "maskautos.h" #include "mwindow.h" +#include "mwindowgui.h" #include "playback3d.h" #include "playbackconfig.h" #include "preferences.h" @@ -75,34 +77,66 @@ int VDeviceX11::reset_parameters() capture_bitmap = 0; color_model_selected = 0; is_cleared = 0; + + for( int i = 0; i < SCREENCAP_BORDERS; i++ ) { + screencap_border[i] = 0; + } return 0; } int VDeviceX11::open_input() { //printf("VDeviceX11::open_input 1\n"); - capture_bitmap = new BC_Capture(device->in_config->w, + capture_bitmap = new BC_Capture(device->in_config->w, device->in_config->h, device->in_config->screencapture_display); //printf("VDeviceX11::open_input 2\n"); +// create overlay + device->mwindow->gui->lock_window("VDeviceX11::close_all"); + + screencap_border[0] = new BC_Popup(device->mwindow->gui, + device->input_x - SCREENCAP_PIXELS, device->input_y - SCREENCAP_PIXELS, + device->in_config->w + SCREENCAP_PIXELS * 2, SCREENCAP_PIXELS, + SCREENCAP_COLOR, 1); + screencap_border[1] = new BC_Popup(device->mwindow->gui, + device->input_x - SCREENCAP_PIXELS, device->input_y, + SCREENCAP_PIXELS, device->in_config->h, + SCREENCAP_COLOR, 1); + screencap_border[2] = new BC_Popup(device->mwindow->gui, + device->input_x - SCREENCAP_PIXELS, device->input_y + device->in_config->h, + device->in_config->w + SCREENCAP_PIXELS * 2, SCREENCAP_PIXELS, + SCREENCAP_COLOR, 1); + screencap_border[3] = new BC_Popup(device->mwindow->gui, + device->input_x + device->in_config->w, device->input_y, + SCREENCAP_PIXELS, device->in_config->h, + SCREENCAP_COLOR, 1); + + for( int i=0; iset_bg_color(SCREENCAP_COLOR); + box->clear_box(0, 0, box->get_w(), box->get_h()); + box->flash(0); + box->show_window(); + } + + device->mwindow->gui->unlock_window(); + return 0; } int VDeviceX11::open_output() { - if(output) - { + if( output ) { output->lock_canvas("VDeviceX11::open_output"); output->get_canvas()->lock_window("VDeviceX11::open_output"); - if(!device->single_frame) + if( !device->single_frame ) output->start_video(); else output->start_single(); output->get_canvas()->unlock_window(); // Enable opengl in the first routine that needs it, to reduce the complexity. - output->unlock_canvas(); } return 0; @@ -111,16 +145,14 @@ int VDeviceX11::open_output() int VDeviceX11::output_visible() { - if(!output) return 0; + if( !output ) return 0; output->lock_canvas("VDeviceX11::output_visible"); - if(output->get_canvas()->get_hidden()) - { + if( output->get_canvas()->get_hidden() ) { output->unlock_canvas(); - return 0; + return 0; } - else - { + else { output->unlock_canvas(); return 1; } @@ -129,46 +161,27 @@ int VDeviceX11::output_visible() int VDeviceX11::close_all() { - if(output) - { + if( output ) { output->lock_canvas("VDeviceX11::close_all 1"); output->get_canvas()->lock_window("VDeviceX11::close_all 1"); } - if(output && output_frame) - { + if( output && output_frame ) { output->update_refresh(device, output_frame); if( device->single_frame ) output->draw_refresh(); } + delete bitmap; bitmap = 0; + delete output_frame; output_frame = 0; + delete capture_bitmap; capture_bitmap = 0; - - - if(bitmap) - { - delete bitmap; - bitmap = 0; - } - - if(output_frame) - { - delete output_frame; - output_frame = 0; - } - - if(capture_bitmap) delete capture_bitmap; - - if(output) - { - + if( output ) { // Update the status bug - if(!device->single_frame) - { + if( !device->single_frame ) { output->stop_video(); } - else - { + else { output->stop_single(); } @@ -176,78 +189,100 @@ int VDeviceX11::close_all() output->unlock_canvas(); } - + if( device->mwindow ) { + device->mwindow->gui->lock_window("VDeviceX11::close_all"); + for( int i=0; imwindow->gui->unlock_window(); + } + reset_parameters(); + return 0; } int VDeviceX11::read_buffer(VFrame *frame) { - capture_bitmap->capture_frame(frame, device->input_x, device->input_y); +//printf("VDeviceX11::read_buffer %d colormodel=%d\n", __LINE__, frame->get_color_model()); + device->mwindow->gui->lock_window("VDeviceX11::close_all"); + + screencap_border[0]->reposition_window(device->input_x - SCREENCAP_PIXELS, + device->input_y - SCREENCAP_PIXELS); + screencap_border[1]->reposition_window(device->input_x - SCREENCAP_PIXELS, + device->input_y); + screencap_border[2]->reposition_window(device->input_x - SCREENCAP_PIXELS, + device->input_y + device->in_config->h); + screencap_border[3]->reposition_window(device->input_x + device->in_config->w, + device->input_y); + device->mwindow->gui->flush(); + device->mwindow->gui->unlock_window(); + + + capture_bitmap->capture_frame(frame, + device->input_x, device->input_y, device->do_cursor); return 0; } int VDeviceX11::get_best_colormodel(Asset *asset) { - return BC_RGB888; + return File::get_best_colormodel(asset, SCREENCAPTURE); +// return BC_RGB888; } -int VDeviceX11::get_best_colormodel(int colormodel) +int VDeviceX11::get_display_colormodel(int file_colormodel) { int result = -1; - if(device->out_config->driver == PLAYBACK_X11_GL) - { - if(colormodel == BC_RGB888 || - colormodel == BC_RGBA8888 || - colormodel == BC_YUV888 || - colormodel == BC_YUVA8888 || - colormodel == BC_RGB_FLOAT || - colormodel == BC_RGBA_FLOAT) - { - return colormodel; + if( device->out_config->driver == PLAYBACK_X11_GL ) { + if( file_colormodel == BC_RGB888 || + file_colormodel == BC_RGBA8888 || + file_colormodel == BC_YUV888 || + file_colormodel == BC_YUVA8888 || + file_colormodel == BC_RGB_FLOAT || + file_colormodel == BC_RGBA_FLOAT ) { + return file_colormodel; } + return BC_RGB888; } - if(!device->single_frame) - { - switch(colormodel) - { - case BC_YUV420P: - case BC_YUV422P: - case BC_YUV422: - result = colormodel; - break; + if( !device->single_frame ) { + switch( file_colormodel ) { + case BC_YUV420P: + case BC_YUV422P: + case BC_YUV422: + result = file_colormodel; + break; } } // 2 more colormodels are supported by OpenGL - if(device->out_config->driver == PLAYBACK_X11_GL) - { - if(colormodel == BC_RGB_FLOAT || - colormodel == BC_RGBA_FLOAT) - result = colormodel; + if( device->out_config->driver == PLAYBACK_X11_GL ) { + if( file_colormodel == BC_RGB_FLOAT || + file_colormodel == BC_RGBA_FLOAT ) + result = file_colormodel; } - if(result < 0) - { - switch(colormodel) - { - case BC_RGB888: - case BC_RGBA8888: - case BC_YUV888: - case BC_YUVA8888: - result = colormodel; - break; - - default: - output->lock_canvas("VDeviceX11::get_best_colormodel"); - result = output->get_canvas()->get_color_model(); - output->unlock_canvas(); - break; + if( result < 0 ) { + switch( file_colormodel ) { + case BC_RGB888: + case BC_RGBA8888: + case BC_YUV888: + case BC_YUVA8888: + case BC_RGB_FLOAT: + case BC_RGBA_FLOAT: + result = file_colormodel; + break; + + default: + output->lock_canvas("VDeviceX11::get_display_colormodel"); + result = output->get_canvas()->get_color_model(); + output->unlock_canvas(); + break; } } @@ -255,110 +290,177 @@ int VDeviceX11::get_best_colormodel(int colormodel) } -void VDeviceX11::new_output_buffer(VFrame **result, int colormodel) +void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *edl) { -//printf("VDeviceX11::new_output_buffer 1\n"); +// printf("VDeviceX11::new_output_buffer %d hardware_scaling=%d\n", +// __LINE__, bitmap ? bitmap->hardware_scaling() : 0); output->lock_canvas("VDeviceX11::new_output_buffer"); output->get_canvas()->lock_window("VDeviceX11::new_output_buffer 1"); // Get the best colormodel the display can handle. - int best_colormodel = get_best_colormodel(colormodel); + int display_colormodel = get_display_colormodel(file_colormodel); +//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n", +// __LINE__, file_colormodel, display_colormodel); // Only create OpenGL Pbuffer and texture. if( device->out_config->driver == PLAYBACK_X11_GL ) { // Create bitmap for initial load into texture. // Not necessary to do through Playback3D.....yet if( !output_frame ) { - output_frame = new VFrame(0, -1, - device->out_w, device->out_h, colormodel, -1); -//BUFFER2(output_frame->get_rows()[0], "VDeviceX11::new_output_buffer 1"); + output_frame = new VFrame(device->out_w, device->out_h, file_colormodel); } window_id = output->get_canvas()->get_id(); output_frame->set_opengl_state(VFrame::RAM); } else { + output->get_transfers(edl, + output_x1, output_y1, output_x2, output_y2, + canvas_x1, canvas_y1, canvas_x2, canvas_y2, +// Canvas may be a different size than the temporary bitmap for pure software + -1, -1); + canvas_w = canvas_x2 - canvas_x1; + canvas_h = canvas_y2 - canvas_y1; +// can the direct frame be used? + int direct_supported = + device->out_config->use_direct_x11 && + !output->xscroll && !output->yscroll && + output_x1 == 0 && output_x2 == device->out_w && + output_y1 == 0 && output_y2 == device->out_h; + +// file wants direct frame but we need a temp + if( !direct_supported && file_colormodel == BC_BGR8888 ) + file_colormodel = BC_RGB888; + // Conform existing bitmap to new colormodel and output size if( bitmap ) { +// printf("VDeviceX11::new_output_buffer %d bitmap=%dx%d canvas=%dx%d canvas=%dx%d\n", +// __LINE__, bitmap->get_w(), bitmap->get_h(), canvas_w, canvas_h,); + int size_change = ( + bitmap->get_w() != canvas_w || + bitmap->get_h() != canvas_h ); + // Restart if output size changed or output colormodel changed. // May have to recreate if transferring between windowed and fullscreen. - if( !color_model_selected || ( !bitmap->hardware_scaling() && - (bitmap->get_w() != output->get_canvas()->get_w() || - bitmap->get_h() != output->get_canvas()->get_h()) ) || - colormodel != output_frame->get_color_model() ) { - int size_change = - bitmap->get_w() != output->get_canvas()->get_w() || - bitmap->get_h() != output->get_canvas()->get_h(); -//printf("VDeviceX11::new_output_buffer %d\n", __LINE__); + if( !color_model_selected || + file_colormodel != output_frame->get_color_model() || + (!bitmap->hardware_scaling() && size_change) ) { +//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d prev " +// "file_colormodel=%d bitmap=%p output_frame=%p\n", __LINE__, +// file_colormodel, output_frame->get_color_model(), bitmap, output_frame); delete bitmap; bitmap = 0; delete output_frame; output_frame = 0; - -// Blank only if size changed +// Clear borders if size changed if( size_change ) { +//printf("VDeviceX11::new_output_buffer %d w=%d h=%d " +// "canvas_x1=%d canvas_y1=%d canvas_x2=%d canvas_y2=%d\n", +// __LINE__, // (int)output->w, (int)output->h, +// (int)canvas_x1, (int)canvas_y1, (int)canvas_x2, (int)canvas_y2); output->get_canvas()->set_color(BLACK); - output->get_canvas()->draw_box(0, 0, output->w, output->h); - output->get_canvas()->flash(); + + if( canvas_y1 > 0 ) { + output->get_canvas()->draw_box(0, 0, output->w, canvas_y1); + output->get_canvas()->flash(0, 0, output->w, canvas_y1); + } + + if( canvas_y2 < output->h ) { + output->get_canvas()->draw_box(0, canvas_y2, output->w, output->h - canvas_y2); + output->get_canvas()->flash(0, canvas_y2, output->w, output->h - canvas_y2); + } + + if( canvas_x1 > 0 ) { + output->get_canvas()->draw_box(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); + output->get_canvas()->flash(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); + } + + if( canvas_x2 < output->w ) { + output->get_canvas()->draw_box(canvas_x2, canvas_y1, + output->w - canvas_x2, canvas_y2 - canvas_y1); + output->get_canvas()->flash(canvas_x2, canvas_y1, + output->w - canvas_x2, canvas_y2 - canvas_y1); + } } } } // Create new bitmap if( !bitmap ) { -// Try hardware accelerated + int use_direct = 0; bitmap_type = BITMAP_TEMP; - switch( best_colormodel ) { +//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n", +// __LINE__, file_colormodel, display_colormodel); + +// Try hardware accelerated + switch( display_colormodel ) { +// blit from the codec directly to the window, using the standard X11 color model. +// Must scale in the codec. No cropping + case BC_BGR8888: + if( direct_supported ) { + bitmap_type = BITMAP_PRIMARY; + use_direct = 1; + } + break; + case BC_YUV420P: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(best_colormodel, 0) && + output->get_canvas()->accel_available(display_colormodel, 0) && !output->use_scrollbars ) bitmap_type = BITMAP_PRIMARY; break; case BC_YUV422P: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(best_colormodel, 0) && + output->get_canvas()->accel_available(display_colormodel, 0) && !output->use_scrollbars ) bitmap_type = BITMAP_PRIMARY; else if( device->out_config->driver == PLAYBACK_X11_XV && output->get_canvas()->accel_available(BC_YUV422, 0) ) { - bitmap = new BC_Bitmap(output->get_canvas(), + bitmap = new BC_Bitmap(output->get_canvas(), device->out_w, device->out_h, BC_YUV422, 1); } break; case BC_YUV422: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(best_colormodel, 0) && - !output->use_scrollbars ) + output->get_canvas()->accel_available(display_colormodel, 0) && + !output->use_scrollbars ) { bitmap_type = BITMAP_PRIMARY; + } else if( device->out_config->driver == PLAYBACK_X11_XV && output->get_canvas()->accel_available(BC_YUV422P, 0) ) { - bitmap = new BC_Bitmap(output->get_canvas(), + bitmap = new BC_Bitmap(output->get_canvas(), device->out_w, device->out_h, BC_YUV422P, 1); } break; } if( bitmap_type == BITMAP_PRIMARY ) { + int bitmap_w = use_direct ? canvas_w : device->out_w; + int bitmap_h = use_direct ? canvas_h : device->out_h; bitmap = new BC_Bitmap(output->get_canvas(), - device->out_w, device->out_h, best_colormodel, 1); + bitmap_w, bitmap_h, display_colormodel, -1); output_frame = new VFrame(bitmap, - device->out_w, device->out_h, best_colormodel, -1); + bitmap_w, bitmap_h, display_colormodel, -1); } - else { -// Try default colormodel - best_colormodel = output->get_canvas()->get_color_model(); - bitmap = new BC_Bitmap(output->get_canvas(), - output->get_canvas()->get_w(), output->get_canvas()->get_h(), - best_colormodel, 1); -// Intermediate frame - output_frame = new VFrame(0, -1, - device->out_w, device->out_h, colormodel, -1); +// Make an intermediate frame + if( !bitmap ) { + display_colormodel = output->get_canvas()->get_color_model(); +// printf("VDeviceX11::new_output_buffer %d creating temp display_colormodel=%d " +// "file_colormodel=%d %dx%d %dx%d %dx%d\n", __LINE__, +// display_colormodel, file_colormodel, device->out_w, device->out_h, +// output->get_canvas()->get_w(), output->get_canvas()->get_h(), canvas_w, canvas_h); + bitmap = new BC_Bitmap(output->get_canvas(), + canvas_w, canvas_h, display_colormodel, 1); + bitmap_type = BITMAP_TEMP; } + if( bitmap_type == BITMAP_TEMP ) { +// Intermediate frame +//printf("VDeviceX11::new_output_buffer %d creating output_frame\n", __LINE__); + output_frame = new VFrame(device->out_w, device->out_h, file_colormodel); + } color_model_selected = 1; } else if( bitmap_type == BITMAP_PRIMARY ) { -// Update the ring buffer output_frame->set_memory(bitmap); } } @@ -374,14 +476,14 @@ void VDeviceX11::new_output_buffer(VFrame **result, int colormodel) int VDeviceX11::start_playback() { // Record window is initialized when its monitor starts. - if(!device->single_frame) + if( !device->single_frame ) output->start_video(); return 0; } int VDeviceX11::stop_playback() { - if(!device->single_frame) + if( !device->single_frame ) output->stop_video(); // Record window goes back to monitoring // get the last frame played and store it in the video_out @@ -390,59 +492,52 @@ int VDeviceX11::stop_playback() int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) { -// The reason for not drawing single frame is that it is _always_ drawn -// when drawing draw_refresh in cwindowgui and vwindowgui - if( device->single_frame ) - return 0; - output->lock_canvas("VDeviceX11::write_buffer"); output->get_canvas()->lock_window("VDeviceX11::write_buffer 1"); - -// Canvas may be a different size than the temporary bitmap for pure software - int xfr_w, xfr_h; - if(bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) { - xfr_w = bitmap->get_w(); - xfr_h = bitmap->get_h(); - } - else - xfr_w = xfr_h = -1; - -//printf("VDeviceX11::write_buffer %d %d\n", __LINE__, output->get_canvas()->get_video_on()); - output->get_transfers(edl, output_x1, output_y1, output_x2, output_y2, - canvas_x1, canvas_y1, canvas_x2, canvas_y2, xfr_w, xfr_h); - -// Convert colormodel -#if 0 +// if( device->out_config->driver == PLAYBACK_X11_GL && +// output_frame->get_color_model() != BC_RGB888 ) { // this is handled by overlay call in virtualvnode, using flatten alpha // invoked when is_nested = -1 is passed to vdevicex11->overlay(...) - if(device->out_config->driver == PLAYBACK_X11_GL && - output_frame->get_color_model() != BC_RGB888) { - int cmodel = BC_RGB888; - output->get_canvas()->unlock_window(); - output->unlock_canvas(); - output->mwindow->playback_3d->convert_cmodel(output, output_frame, cmodel); - output_frame->reallocate(0,-1,0,0,0,output_frame->get_w(),output_frame->get_h(),cmodel,-1); - output->lock_canvas("VDeviceX11::write_buffer 3"); - output->get_canvas()->lock_window("VDeviceX11::write_buffer 3"); - } - else -#endif +// } + +// printf("VDeviceX11::write_buffer %d %d bitmap_type=%d\n", +// __LINE__, +// output->get_canvas()->get_video_on(), +// bitmap_type); + +// int use_bitmap_extents = 0; +// canvas_w = -1; canvas_h = -1; +// // Canvas may be a different size than the temporary bitmap for pure software +// if( bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling() ) { +// canvas_w = bitmap->get_w(); +// canvas_h = bitmap->get_h(); +// } +// +// output->get_transfers(edl, +// output_x1, output_y1, output_x2, output_y2, +// canvas_x1, canvas_y1, canvas_x2, canvas_y2, +// canvas_w, canvas_h); + +// Convert colormodel if( bitmap_type == BITMAP_TEMP ) { // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n", -// output->w, output->h, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h ); +// output->w, output->h, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h); // fflush(stdout); -//printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels); + +// printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels); +// printf("VDeviceX11::write_buffer %d input color_model=%d output color_model=%d\n", +// __LINE__, output_channels->get_color_model(), bitmap->get_color_model()); if( bitmap->hardware_scaling() ) { - BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), - 0, 0, 0, output_channels->get_y(), output_channels->get_u(), output_channels->get_v(), + BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0, + output_channels->get_y(), output_channels->get_u(), output_channels->get_v(), 0, 0, output_channels->get_w(), output_channels->get_h(), 0, 0, bitmap->get_w(), bitmap->get_h(), output_channels->get_color_model(), bitmap->get_color_model(), 0, output_channels->get_w(), bitmap->get_w()); } else { - BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), - 0, 0, 0, output_channels->get_y(), output_channels->get_u(), output_channels->get_v(), + BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0, + output_channels->get_y(), output_channels->get_u(), output_channels->get_v(), (int)output_x1, (int)output_y1, (int)(output_x2 - output_x1), (int)(output_y2 - output_y1), 0, 0, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), output_channels->get_color_model(), bitmap->get_color_model(), @@ -451,44 +546,69 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) } //printf("VDeviceX11::write_buffer 4 %p\n", bitmap); -//for(i = 0; i < 1000; i += 4) bitmap->get_data()[i] = 128; -//printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type, -// bitmap->get_color_model(), output->get_color_model()); -//fflush(stdout); -//printf("VDeviceX11::write_buffer 2 %d %d, %f %f %f %f -> %f %f %f %f\n", -// output->w, output->h, output_x1, output_y1, output_x2, output_y2, +//for( i = 0; i < 1000; i += 4 ) bitmap->get_data()[i] = 128; +//printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type, +// bitmap->get_color_model(), +// output->get_color_model());fflush(stdout); + +// printf("VDeviceX11::write_buffer %d %dx%d %f %f %f %f -> %f %f %f %f\n", +// __LINE__, // output->w, output->h, +// output_x1, output_y1, output_x2, output_y2, // canvas_x1, canvas_y1, canvas_x2, canvas_y2); // Cause X server to display it if( device->out_config->driver == PLAYBACK_X11_GL ) { // Output is drawn in close_all if no video. if( output->get_canvas()->get_video_on() ) { + canvas_w = -1; canvas_h = -1; +// Canvas may be a different size than the temporary bitmap for pure software + if( bitmap_type == BITMAP_TEMP && + !bitmap->hardware_scaling() ) { + canvas_w = bitmap->get_w(); + canvas_h = bitmap->get_h(); + } + + output->get_transfers(edl, + output_x1, output_y1, output_x2, output_y2, + canvas_x1, canvas_y1, canvas_x2, canvas_y2, + canvas_w, canvas_h); + +//printf("VDeviceX11::write_buffer %d\n", __LINE__); // Draw output frame directly. Not used for compositing. output->get_canvas()->unlock_window(); output->unlock_canvas(); - output->mwindow->playback_3d->write_buffer(output, - output_frame, output_x1, output_y1, output_x2, output_y2, - canvas_x1, canvas_y1, canvas_x2, canvas_y2, is_cleared); + output->mwindow->playback_3d->write_buffer(output, output_frame, + output_x1, output_y1, output_x2, output_y2, + canvas_x1, canvas_y1, canvas_x2, canvas_y2, + is_cleared); is_cleared = 0; output->lock_canvas("VDeviceX11::write_buffer 2"); output->get_canvas()->lock_window("VDeviceX11::write_buffer 2"); } } - else if( bitmap->hardware_scaling() ) { + else + if( bitmap->hardware_scaling() ) { output->get_canvas()->draw_bitmap(bitmap, !device->single_frame, (int)canvas_x1, (int)canvas_y1, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), (int)output_x1, (int)output_y1, - (int)(output_x2 - output_x1), (int)(output_y2 - output_y1), 0); + (int)(output_x2 - output_x1), (int)(output_y2 - output_y1), + 0); } else { +//printf("VDeviceX11::write_buffer %d x=%d y=%d w=%d h=%d\n", +// __LINE__, (int)canvas_x1, (int)canvas_y1, +// output->get_canvas()->get_w(), output->get_canvas()->get_h()); + output->get_canvas()->draw_bitmap(bitmap, !device->single_frame, (int)canvas_x1, (int)canvas_y1, - (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), 0, 0, - (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), 0); + (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), + 0, 0, + (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), + 0); +//printf("VDeviceX11::write_buffer %d bitmap=%p\n", __LINE__, bitmap); } - output->get_canvas()->unlock_window(); output->unlock_canvas(); return 0; @@ -513,17 +633,17 @@ void VDeviceX11::clear_input(VFrame *frame) void VDeviceX11::convert_cmodel(VFrame *output, int dst_cmodel) { this->output->mwindow->playback_3d->convert_cmodel(this->output, - output, + output, dst_cmodel); } void VDeviceX11::do_camera(VFrame *output, VFrame *input, - float in_x1, float in_y1, float in_x2, float in_y2, + float in_x1, float in_y1, float in_x2, float in_y2, float out_x1, float out_y1, float out_x2, float out_y2) { - this->output->mwindow->playback_3d->do_camera( - this->output, output, input, - in_x1, in_y1, in_x2, in_y2, + this->output->mwindow->playback_3d->do_camera(this->output, + output, input, + in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2); } @@ -541,52 +661,45 @@ bool VDeviceX11::can_mask(int64_t start_position_project, MaskAutos *keyframe_se return keyframe->disable_opengl_masking ? 0 : 1; } -void VDeviceX11::do_mask(VFrame *output_temp, - int64_t start_position_project, MaskAutos *keyframe_set, - MaskAuto *keyframe, MaskAuto *default_auto) +void VDeviceX11::do_mask(VFrame *output_temp, int64_t start_position_project, + MaskAutos *keyframe_set, MaskAuto *keyframe, MaskAuto *default_auto) { - this->output->mwindow->playback_3d->do_mask(output, - output_temp, start_position_project, - keyframe_set, keyframe, default_auto); + this->output->mwindow->playback_3d->do_mask(output, output_temp, + start_position_project, keyframe_set, keyframe, default_auto); } -void VDeviceX11::overlay(VFrame *output_frame, VFrame *input, +void VDeviceX11::overlay(VFrame *output_frame, VFrame *input, // This is the transfer from track to output frame - float in_x1, float in_y1, float in_x2, float in_y2, - float out_x1, float out_y1, float out_x2, float out_y2, - float alpha /*0-1*/, int mode, EDL *edl, int is_nested) + float in_x1, float in_y1, float in_x2, float in_y2, + float out_x1, float out_y1, float out_x2, float out_y2, + float alpha, // 0 - 1 + int mode, EDL *edl, int is_nested) { int interpolation_type = edl->session->interpolation_type; // printf("VDeviceX11::overlay 1:\n" // "in_x1=%f in_y1=%f in_x2=%f in_y2=%f\n" // "out_x1=%f out_y1=%f out_x2=%f out_y2=%f\n", -// in_x1, in_y1, in_x2, in_y2, -// out_x1, out_y1, out_x2, out_y2); +// in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2); // Convert node coords to canvas coords in here // If single frame playback or nested EDL, use full sized PBuffer as output. - if(device->single_frame || is_nested > 0) - { + if( device->single_frame || is_nested > 0 ) { output->mwindow->playback_3d->overlay(output, input, - in_x1, in_y1, in_x2, in_y2, - out_x1, out_y1, out_x2, out_y2, - alpha, mode, interpolation_type, - output_frame, is_nested); -// printf("VDeviceX11::overlay 1 %p %d %d %d\n", -// output_frame, -// output_frame->get_w(), -// output_frame->get_h(), + in_x1, in_y1, in_x2, in_y2, + out_x1, out_y1, out_x2, out_y2, alpha, // 0 - 1 + mode, interpolation_type, output_frame, is_nested); +// printf("VDeviceX11::overlay 1 %p %d %d %d\n", +// output_frame, output_frame->get_w(), output_frame->get_h(), // output_frame->get_opengl_state()); } - else - { + else { output->lock_canvas("VDeviceX11::overlay"); output->get_canvas()->lock_window("VDeviceX11::overlay"); // This is the transfer from output frame to canvas - output->get_transfers(edl, - output_x1, output_y1, output_x2, output_y2, + output->get_transfers(edl, + output_x1, output_y1, output_x2, output_y2, canvas_x1, canvas_y1, canvas_x2, canvas_y2, -1, -1); @@ -608,40 +721,35 @@ void VDeviceX11::overlay(VFrame *output_frame, VFrame *input, float track_y2 = (float)(output_y2 - out_y2) / track_yscale + in_y2; // Clamp canvas coords to track boundary - if(track_x1 < 0) - { + if( track_x1 < 0 ) { float difference = -track_x1; track_x1 += difference; canvas_x1 += difference * track_xscale * canvas_xscale; } - if(track_y1 < 0) - { + if( track_y1 < 0 ) { float difference = -track_y1; track_y1 += difference; canvas_y1 += difference * track_yscale * canvas_yscale; } - if(track_x2 > input->get_w()) - { + if( track_x2 > input->get_w() ) { float difference = track_x2 - input->get_w(); track_x2 -= difference; canvas_x2 -= difference * track_xscale * canvas_xscale; } - if(track_y2 > input->get_h()) - { + if( track_y2 > input->get_h() ) { float difference = track_y2 - input->get_h(); track_y2 -= difference; canvas_y2 -= difference * track_yscale * canvas_yscale; } // Overlay directly from track buffer to canvas, skipping output buffer - if(track_x2 > track_x1 && track_y2 > track_y1 && - canvas_x2 > canvas_x1 && canvas_y2 > canvas_y1) - { + if( track_x2 > track_x1 && track_y2 > track_y1 && + canvas_x2 > canvas_x1 && canvas_y2 > canvas_y1 ) { output->mwindow->playback_3d->overlay(output, input, - track_x1, track_y1, track_x2, track_y2, - canvas_x1, canvas_y1, canvas_x2, canvas_y2, - alpha, mode, interpolation_type, 0, is_nested); + track_x1, track_y1, track_x2, track_y2, + canvas_x1, canvas_y1, canvas_x2, canvas_y2, alpha, // 0 - 1 + mode, interpolation_type, 0, is_nested); } } } diff --git a/cinelerra-5.1/cinelerra/vdevicex11.h b/cinelerra-5.1/cinelerra/vdevicex11.h index 7f001a70..afc21edb 100644 --- a/cinelerra-5.1/cinelerra/vdevicex11.h +++ b/cinelerra-5.1/cinelerra/vdevicex11.h @@ -47,7 +47,7 @@ public: int read_buffer(VFrame *frame); int reset_parameters(); // User always gets the colormodel requested - void new_output_buffer(VFrame **output, int colormodel); + void new_output_buffer(VFrame **output, int colormodel, EDL *edl); int open_output(); int start_playback(); @@ -130,7 +130,13 @@ private: // is passed to this to create the VFrame to which the output is rendered. // For OpenGL, it creates the array of row pointers used to upload the video // frame to the texture, the texture, and the PBuffer. - int get_best_colormodel(int colormodel); + int get_display_colormodel(int file_colormodel); + +// windows which overlay the screencap area +#define SCREENCAP_BORDERS 4 +#define SCREENCAP_PIXELS 5 +#define SCREENCAP_COLOR GREEN + BC_Popup *screencap_border[SCREENCAP_BORDERS]; // Bitmap to be written to device BC_Bitmap *bitmap; @@ -150,12 +156,14 @@ private: int texture_h; int color_model; int color_model_selected; -// Transfer coordinates from the output frame to the canvas -// for last frame rendered. +// Transfer coordinates from the output frame to the canvas. +// Calculated in new_output_buffer & retained for write_buffer // These stick the last frame to the display. // Must be floats to support OpenGL float output_x1, output_y1, output_x2, output_y2; float canvas_x1, canvas_y1, canvas_x2, canvas_y2; +// rounded integer dimensions + int canvas_w, canvas_h; // Screen capture BC_Capture *capture_bitmap; // Set when OpenGL rendering has cleared the frame buffer before write_buffer diff --git a/cinelerra-5.1/cinelerra/videodevice.C b/cinelerra-5.1/cinelerra/videodevice.C index fbad636f..e8de98ca 100644 --- a/cinelerra-5.1/cinelerra/videodevice.C +++ b/cinelerra-5.1/cinelerra/videodevice.C @@ -190,6 +190,8 @@ int VideoDevice::initialize() single_frame = 0; channel_changed = 0; picture_changed = 0; + odd_field_first = 0; + do_cursor = 0; return 0; } @@ -492,6 +494,21 @@ int VideoDevice::set_field_order(int odd_field_first) return 0; } +void VideoDevice::set_do_cursor(int do_cursor, int do_big_cursor) +{ + int cursor_scale = 0; + if(do_cursor) + { + cursor_scale = 1; + if(do_big_cursor) + { + cursor_scale = 2; + } + } + + this->do_cursor = cursor_scale; +} + int VideoDevice::set_channel(Channel *channel) { int result = 0; @@ -697,10 +714,10 @@ void VideoDevice::goose_input() if(input_base) input_base->goose_input(); } -void VideoDevice::new_output_buffer(VFrame **output, int colormodel) +void VideoDevice::new_output_buffer(VFrame **output, int colormodel, EDL *edl) { if(!output_base) return; - output_base->new_output_buffer(output, colormodel); + output_base->new_output_buffer(output, colormodel, edl); } diff --git a/cinelerra-5.1/cinelerra/videodevice.h b/cinelerra-5.1/cinelerra/videodevice.h index f9334aff..61f56657 100644 --- a/cinelerra-5.1/cinelerra/videodevice.h +++ b/cinelerra-5.1/cinelerra/videodevice.h @@ -144,6 +144,7 @@ public: void set_quality(int quality); // Change field order int set_field_order(int odd_field_first); + void set_do_cursor(int do_cursor, int do_big_cursor); // Set frames to clear after translation change. int set_latency_counter(int value); // Values from -100 to 100 @@ -177,7 +178,7 @@ public: int interrupt_playback(); // Get output buffer for playback using colormodel. // colormodel argument should be as close to best_colormodel as possible - void new_output_buffer(VFrame **output, int colormodel); + void new_output_buffer(VFrame **output, int colormodel, EDL *edl); int wait_for_startup(); int wait_for_completion(); int output_visible(); // Whether the output is visible or not. @@ -263,6 +264,7 @@ public: // All the input sources on the device ArrayList input_sources; int odd_field_first; + int do_cursor; // Quality for the JPEG compressor int quality; // Single frame mode for playback diff --git a/cinelerra-5.1/cinelerra/vmodule.C b/cinelerra-5.1/cinelerra/vmodule.C index 02e047e6..0c8e1b7f 100644 --- a/cinelerra-5.1/cinelerra/vmodule.C +++ b/cinelerra-5.1/cinelerra/vmodule.C @@ -230,11 +230,8 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit, { File *file = 0; - if(debug) printf("VModule::import_frame %d cache=%p\n", - __LINE__, - get_cache()); - if(current_edit->asset) - { +//printf("VModule::import_frame %d cache=%p\n", __LINE__, get_cache()); + if( current_edit->asset ) { get_cache()->age(); file = get_cache()->check_out(current_edit->asset, get_edl()); @@ -307,18 +304,19 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit, int use_cache = renderengine && renderengine->command->single_frame(); - int use_asynchronous = !use_cache && renderengine && +// int use_asynchronous = !use_cache && +// renderengine && // Try to make rendering go faster. // But converts some formats to YUV420, which may degrade input format. -// renderengine->command->realtime && - renderengine->get_edl()->session->video_asynchronous; +//// renderengine->command->realtime && +// renderengine->get_edl()->session->video_asynchronous; if(file) { if(debug) printf("VModule::import_frame %d\n", __LINE__); - if(use_asynchronous) - file->start_video_decode_thread(); - else +// if(use_asynchronous) +// file->start_video_decode_thread(); +// else file->stop_video_thread(); int64_t normalized_position = Units::to_int64(position * @@ -445,7 +443,7 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit, !EQUIV(in_w, asset_w) || !EQUIV(in_h, asset_h)) { - if(debug) printf("VModule::import_frame %d file -> temp -> output\n", __LINE__); +//printf("VModule::import_frame %d file -> temp -> output\n", __LINE__); @@ -725,7 +723,13 @@ output->get_opengl_state(), get_edl()->session->interpolation_type); } result = 1; + output->copy_stacks((*input)); + + +//printf("VModule::import_frame %d\n", __LINE__); +//(*input)->dump_params(); +//output->dump_params(); } else // file -> output @@ -880,6 +884,11 @@ current_cmodel); } result = 1; } + +// printf("VModule::import_frame %d cache=%p\n", +// __LINE__, +// get_cache()); + } else // Source is silence diff --git a/cinelerra-5.1/cinelerra/vrender.C b/cinelerra-5.1/cinelerra/vrender.C index c59c3fec..f46a4096 100644 --- a/cinelerra-5.1/cinelerra/vrender.C +++ b/cinelerra-5.1/cinelerra/vrender.C @@ -133,10 +133,10 @@ int VRender::process_buffer(int64_t input_position, int use_brender = 0; int result = 0; int use_cache = renderengine->command->single_frame(); - int use_asynchronous = - renderengine->command->realtime && - renderengine->get_edl()->session->video_every_frame && - renderengine->get_edl()->session->video_asynchronous; +// int use_asynchronous = +// renderengine->command->realtime && +// renderengine->get_edl()->session->video_every_frame && +// renderengine->get_edl()->session->video_asynchronous; const int debug = 0; // Determine the rendering strategy for this frame. @@ -151,7 +151,9 @@ int VRender::process_buffer(int64_t input_position, // Get output buffer from device if(renderengine->command->realtime && !renderengine->is_nested) { - renderengine->video->new_output_buffer(&video_out, colormodel); + renderengine->video->new_output_buffer(&video_out, + colormodel, + renderengine->get_edl()); } if(debug) printf("VRender::process_buffer %d video_out=%p\n", __LINE__, video_out); @@ -177,9 +179,9 @@ int VRender::process_buffer(int64_t input_position, corrected_position--; // Cache single frames only - if(use_asynchronous) - file->start_video_decode_thread(); - else +// if(use_asynchronous) +// file->start_video_decode_thread(); +// else file->stop_video_thread(); if(use_cache) file->set_cache_frames(1); int64_t normalized_position = (int64_t)(corrected_position * @@ -206,7 +208,8 @@ int VRender::process_buffer(int64_t input_position, renderengine->get_vcache(), 1, use_cache, - use_asynchronous); + 0); +// use_asynchronous); if(debug) printf("VRender::process_buffer %d\n", __LINE__); } @@ -267,8 +270,7 @@ int VRender::get_colormodel(VEdit *playable_edit, current_position, renderengine->command->get_direction()); } -// ffmpeg files are side effected by color_model, affects colorspace,color_range - if( asset && asset->format != FILE_FFMPEG ) + if( asset ) { file = renderengine->get_vcache()->check_out(asset, renderengine->get_edl()); @@ -276,8 +278,12 @@ int VRender::get_colormodel(VEdit *playable_edit, if(file) { colormodel = file->get_best_colormodel(driver); +//printf("VRender::get_colormodel %d driver=%d colormodel=%d\n", __LINE__, driver, colormodel); renderengine->get_vcache()->check_in(asset); } +// ffmpeg files are side effected by color_model, affects colorspace,color_range +// if( asset->format == FILE_FFMPEG && !BC_CModels::is_yuv(colormodel) ) +// colormodel = BC_BGR8888; } } diff --git a/cinelerra-5.1/configure.ac b/cinelerra-5.1/configure.ac index 9d54bc7d..3ec19dfd 100644 --- a/cinelerra-5.1/configure.ac +++ b/cinelerra-5.1/configure.ac @@ -397,6 +397,7 @@ CHECK_LIB([XINERAMA], [Xinerama], [XineramaQueryExtension]) CHECK_HEADERS([XINERAMA], [Xinerama headers], [X11/extensions/Xinerama.h]) CHECK_LIB([XV], [Xv], [XvQueryExtension]) CHECK_HEADERS([XV], [Xlib Xv extention], [X11/Xlib.h X11/extensions/Xvlib.h]) +CHECK_LIB([XFIXES], [Xfixes], [XFixesQueryVersion]) CHECK_LIB([BZ2], [bz2], [BZ2_bzDecompress]) CHECK_LIB([FONTCONFIG], [fontconfig], [FcInit]) CHECK_LIB([FREETYPE], [freetype], [FT_Init_FreeType]) diff --git a/cinelerra-5.1/ffmpeg/decode.opts b/cinelerra-5.1/ffmpeg/decode.opts index 98dbcaed..fc4e1a56 100644 --- a/cinelerra-5.1/ffmpeg/decode.opts +++ b/cinelerra-5.1/ffmpeg/decode.opts @@ -2,4 +2,3 @@ loglevel=fatal formatprobesize=5000000 scan_all_pmts=1 -threads=auto diff --git a/cinelerra-5.1/guicast/Makefile b/cinelerra-5.1/guicast/Makefile index efc7f15c..2fa43288 100644 --- a/cinelerra-5.1/guicast/Makefile +++ b/cinelerra-5.1/guicast/Makefile @@ -16,6 +16,7 @@ OBJS = \ $(OBJDIR)/bcbitmap.o \ $(OBJDIR)/bcbutton.o \ $(OBJDIR)/bccapture.o \ + $(OBJDIR)/bccolors.o \ $(OBJDIR)/bccmodels.o \ $(OBJDIR)/bccounter.o \ $(OBJDIR)/bcclipboard.o \ diff --git a/cinelerra-5.1/guicast/bcbitmap.h b/cinelerra-5.1/guicast/bcbitmap.h index 7d1e37a2..221248b9 100644 --- a/cinelerra-5.1/guicast/bcbitmap.h +++ b/cinelerra-5.1/guicast/bcbitmap.h @@ -32,7 +32,7 @@ #include "bcwindowbase.inc" #include "bcbitmap.inc" #include "bccmodels.h" -#include "colors.h" +#include "bccolors.h" #include "condition.h" #include "linklist.h" #include "mutex.h" diff --git a/cinelerra-5.1/guicast/bcbutton.C b/cinelerra-5.1/guicast/bcbutton.C index 6a8b863b..6d0c4349 100644 --- a/cinelerra-5.1/guicast/bcbutton.C +++ b/cinelerra-5.1/guicast/bcbutton.C @@ -23,7 +23,7 @@ #include "bcpixmap.h" #include "bcresources.h" #include "bcsignals.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "keys.h" #include "language.h" diff --git a/cinelerra-5.1/guicast/bccapture.C b/cinelerra-5.1/guicast/bccapture.C index 993cfe14..e955a527 100644 --- a/cinelerra-5.1/guicast/bccapture.C +++ b/cinelerra-5.1/guicast/bccapture.C @@ -23,15 +23,14 @@ #include "bcresources.h" #include "bcwindowbase.h" #include "bccmodels.h" +#include "bccolors.h" +#include "clip.h" #include "language.h" #include "vframe.h" #include #include #include - - - - +#include // Byte orders: // 24 bpp packed: bgr @@ -59,11 +58,10 @@ BC_Capture::~BC_Capture() int BC_Capture::init_window(const char *display_path) { int bits_per_pixel; - if(display_path && display_path[0] == 0) display_path = NULL; - if((display = XOpenDisplay(display_path)) == NULL) - { + if( display_path && display_path[0] == 0 ) display_path = NULL; + if( (display = XOpenDisplay(display_path)) == NULL ) { printf(_("cannot connect to X server.\n")); - if(getenv("DISPLAY") == NULL) + if( getenv("DISPLAY") == NULL ) printf(_("'DISPLAY' environment variable not set.\n")); exit(-1); return 1; @@ -93,8 +91,7 @@ int BC_Capture::init_window(const char *display_path) // test shared memory // This doesn't ensure the X Server is on the local host - if(use_shm && !XShmQueryExtension(display)) - { + if( use_shm && !XShmQueryExtension(display) ) { use_shm = 0; } return 0; @@ -104,14 +101,12 @@ int BC_Capture::init_window(const char *display_path) int BC_Capture::allocate_data() { // try shared memory - if(!display) return 1; - if(use_shm) - { + if( !display ) return 1; + if( use_shm ) { ximage = XShmCreateImage(display, vis, default_depth, ZPixmap, (char*)NULL, &shm_info, w, h); shm_info.shmid = shmget(IPC_PRIVATE, h * ximage->bytes_per_line, IPC_CREAT | 0600); - if(shm_info.shmid == -1) - { + if( shm_info.shmid == -1 ) { perror("BC_Capture::allocate_data shmget"); abort(); } @@ -124,16 +119,14 @@ int BC_Capture::allocate_data() BC_Resources::error = 0; XShmAttach(display, &shm_info); XSync(display, False); - if(BC_Resources::error) - { + if( BC_Resources::error ) { XDestroyImage(ximage); shmdt(shm_info.shmaddr); use_shm = 0; } } - if(!use_shm) - { + if( !use_shm ) { // need to use bytes_per_line for some X servers data = 0; ximage = XCreateImage(display, vis, default_depth, ZPixmap, 0, (char*)data, w, h, 8, 0); @@ -144,8 +137,7 @@ int BC_Capture::allocate_data() } row_data = new unsigned char*[h]; - for(int i = 0; i < h; i++) - { + for( int i = 0; i < h; i++ ) { row_data[i] = &data[i * ximage->bytes_per_line]; } // This differs from the depth parameter of the top_level. @@ -155,17 +147,14 @@ int BC_Capture::allocate_data() int BC_Capture::delete_data() { - if(!display) return 1; - if(data) - { - if(use_shm) - { + if( !display ) return 1; + if( data ) { + if( use_shm ) { XShmDetach(display, &shm_info); XDestroyImage(ximage); shmdt(shm_info.shmaddr); } - else - { + else { XDestroyImage(ximage); } @@ -181,31 +170,22 @@ int BC_Capture::get_w() { return w; } int BC_Capture::get_h() { return h; } // Capture a frame from the screen -#define CAPTURE_FRAME_HEAD \ - for(int i = 0; i < h; i++) \ - { \ - unsigned char *input_row = row_data[i]; \ - unsigned char *output_row = (unsigned char*)frame->get_rows()[i]; \ - for(int j = 0; j < w; j++) \ - { - -#define CAPTURE_FRAME_TAIL \ - } \ - } +#define RGB_TO_YUV(y, u, v, r, g, b) { \ + YUV::yuv.rgb_to_yuv_8(r, g, b, y, u, v); \ + bclamp(y, 0,0xff); bclamp(u, 0,0xff); bclamp(v, 0,0xff); } - - -int BC_Capture::capture_frame(VFrame *frame, int &x1, int &y1) +int BC_Capture::capture_frame(VFrame *frame, int &x1, int &y1, + int do_cursor) // the scale of the cursor if nonzero { - if(!display) return 1; - if(x1 < 0) x1 = 0; - if(y1 < 0) y1 = 0; - if(x1 > get_top_w() - w) x1 = get_top_w() - w; - if(y1 > get_top_h() - h) y1 = get_top_h() - h; + if( !display ) return 1; + if( x1 < 0 ) x1 = 0; + if( y1 < 0 ) y1 = 0; + if( x1 > get_top_w() - w ) x1 = get_top_w() - w; + if( y1 > get_top_h() - h ) y1 = get_top_h() - h; // Read the raw data - if(use_shm) + if( use_shm ) XShmGetImage(display, rootwin, ximage, x1, y1, 0xffffffff); else XGetSubImage(display, rootwin, x1, y1, w, h, 0xffffffff, ZPixmap, ximage, 0, 0); @@ -216,6 +196,72 @@ int BC_Capture::capture_frame(VFrame *frame, int &x1, int &y1) frame->get_w(), frame->get_h(), bitmap_color_model, frame->get_color_model(), 0, frame->get_w(), w); + + if( do_cursor ) { + XFixesCursorImage *cursor; + cursor = XFixesGetCursorImage(display); + if( cursor ) { +//printf("BC_Capture::capture_frame %d cursor=%p colormodel=%d\n", +// __LINE__, cursor, frame->get_color_model()); + int scale = do_cursor; + int cursor_x = cursor->x - x1 - cursor->xhot * scale; + int cursor_y = cursor->y - y1 - cursor->yhot * scale; + int w = frame->get_w(); + int h = frame->get_h(); + for( int i = 0; i < cursor->height; i++ ) { + for( int yscale = 0; yscale < scale; yscale++ ) { + if( cursor_y + i * scale + yscale >= 0 && + cursor_y + i * scale + yscale < h ) { + unsigned char *src = (unsigned char*)(cursor->pixels + + i * cursor->width); + int dst_y = cursor_y + i * scale + yscale; + int dst_x = cursor_x; + for( int j = 0; j < cursor->width; j++ ) { + for( int xscale = 0; xscale < scale ; xscale++ ) { + if( cursor_x + j * scale + xscale >= 0 && + cursor_x + j * scale + xscale < w ) { + int a = src[3]; + int invert_a = 0xff - a; + int r = src[2]; + int g = src[1]; + int b = src[0]; + switch( frame->get_color_model() ) { + case BC_RGB888: { + unsigned char *dst = frame->get_rows()[dst_y] + + dst_x * 3; + dst[0] = (r * a + dst[0] * invert_a) / 0xff; + dst[1] = (g * a + dst[1] * invert_a) / 0xff; + dst[2] = (b * a + dst[2] * invert_a) / 0xff; + break; } + + case BC_YUV420P: { + unsigned char *dst_y_ = frame->get_y() + + dst_y * w + dst_x; + unsigned char *dst_u = frame->get_u() + + (dst_y / 2) * (w / 2) + (dst_x / 2); + unsigned char *dst_v = frame->get_v() + + (dst_y / 2) * (w / 2) + (dst_x / 2); + int y, u, v; + RGB_TO_YUV(y, u, v, r, g, b); + + *dst_y_ = (y * a + *dst_y_ * invert_a) / 0xff; + *dst_u = (u * a + *dst_u * invert_a) / 0xff; + *dst_v = (v * a + *dst_v * invert_a) / 0xff; + break; } + } + } + dst_x++; + } + src += sizeof(long); + } + } + } + } + +// This frees cursor->pixels + XFree(cursor); + } + } return 0; } diff --git a/cinelerra-5.1/guicast/bccapture.h b/cinelerra-5.1/guicast/bccapture.h index e0f098b9..787fb4a6 100644 --- a/cinelerra-5.1/guicast/bccapture.h +++ b/cinelerra-5.1/guicast/bccapture.h @@ -39,7 +39,8 @@ public: int init_window(const char *display_path); // x1 and y1 are automatically adjusted if out of bounds - int capture_frame(VFrame *frame, int &x1, int &y1); + int capture_frame(VFrame *frame, int &x1, int &y1, + int do_cursor=0); // the scale of the cursor if nonzero int get_w(); int get_h(); diff --git a/cinelerra-5.1/guicast/bccmodels.h b/cinelerra-5.1/guicast/bccmodels.h index 57b595f4..63b7d8c3 100644 --- a/cinelerra-5.1/guicast/bccmodels.h +++ b/cinelerra-5.1/guicast/bccmodels.h @@ -128,7 +128,6 @@ public: int in_x, int in_y, int in_w, int in_h, int in_rowspan, int bg_color); - static void init_yuv(); static int bc_to_x(int color_model); static void bcxfer_stop_slicers(); }; diff --git a/cinelerra-5.1/cinelerra/cicolors.C b/cinelerra-5.1/guicast/bccolors.C similarity index 99% rename from cinelerra-5.1/cinelerra/cicolors.C rename to cinelerra-5.1/guicast/bccolors.C index 2dba6f87..48dcb02a 100644 --- a/cinelerra-5.1/cinelerra/cicolors.C +++ b/cinelerra-5.1/guicast/bccolors.C @@ -19,7 +19,7 @@ * */ -#include "cicolors.h" +#include "bccolors.h" #include diff --git a/cinelerra-5.1/cinelerra/cicolors.h b/cinelerra-5.1/guicast/bccolors.h similarity index 81% rename from cinelerra-5.1/cinelerra/cicolors.h rename to cinelerra-5.1/guicast/bccolors.h index 1ab7ab45..c91aba9f 100644 --- a/cinelerra-5.1/cinelerra/cicolors.h +++ b/cinelerra-5.1/guicast/bccolors.h @@ -19,8 +19,8 @@ * */ -#ifndef CICOLORS_H -#define CICOLORS_H +#ifndef __BCCOLORS_H__ +#define __BCCOLORS_H__ // Duplicate filename in guicast @@ -193,18 +193,6 @@ private: }; - - - - - - - - - - - - class HSV { public: @@ -224,4 +212,51 @@ public: }; +// standard colors +#define BLACK 0x000000 +#define WHITE 0xFFFFFF + +#define LTBLUE 0x9090FF +#define BLUE 0x0000FF +#define DKBLUE 0x000090 + +#define LTPINK 0xFFC0C0 +#define PINK 0xFF8080 +#define RED 0xFF0000 + +#define LTGREEN 0xC0FFC0 +#define GREEN 0x00FF00 +#define DKGREEN 0x009000 + +#define YELLOW 0xFFFF00 +#define LTYELLOW 0xFFFFA0 +#define MEYELLOW 0xFFFF00 +#define MDYELLOW 0xFFFFD2 +#define DKYELLOW 0xFFFFB4 + +#define LTCYAN 0x00CBCB +#define MECYAN 0x009696 +#define MDCYAN 0x007E7E +#define DKCYAN 0x004949 + +#define LTPURPLE 0xFFC0FF +#define MEPURPLE 0xFF00FF +#define MDPURPLE 0xC000C0 +#define DKPURPLE 0xA000A0 + +#define LTGREY 0xE0E0E0 +#define MEGREY 0xAFAFAF +#define DMGREY 0x999999 +#define MDGREY 0x7D7D7D +#define DKGREY 0x4B4B4B + +#define BLOND 0xb4b487 +#define SLBLUE 0x6040c0 + +#define MNGREY 0xe6e6e6 +#define FGGREY 0xe3e3e3 +#define MNBLUE 0x003cff +#define ORANGE 0xffdd76 +#define FTGREY 0xbcbcbc + #endif diff --git a/cinelerra-5.1/cinelerra/cicolors.inc b/cinelerra-5.1/guicast/bccolors.inc similarity index 100% rename from cinelerra-5.1/cinelerra/cicolors.inc rename to cinelerra-5.1/guicast/bccolors.inc diff --git a/cinelerra-5.1/guicast/bcfilebox.C b/cinelerra-5.1/guicast/bcfilebox.C index 021a87fc..212956b8 100644 --- a/cinelerra-5.1/guicast/bcfilebox.C +++ b/cinelerra-5.1/guicast/bcfilebox.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 1997-2011 Adam Williams + * Copyright (C) 1997-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cinelerra-5.1/guicast/bclistbox.C b/cinelerra-5.1/guicast/bclistbox.C index 394daac6..ac15f666 100644 --- a/cinelerra-5.1/guicast/bclistbox.C +++ b/cinelerra-5.1/guicast/bclistbox.C @@ -4505,43 +4505,39 @@ void BC_ListBox::draw_title(int number) image_number = 2; } - int column_offset = get_column_offset(number) - xposition + LISTBOX_BORDER; - int column_width = get_column_width(number, 1); gui->draw_3segmenth(get_column_offset(number) - xposition + LISTBOX_BORDER, LISTBOX_BORDER, get_column_width(number, 1) + get_resources()->listbox_title_overlap, column_bg[image_number]); -// Column title sort order - if(number == sort_column) - { - BC_Pixmap *src; - if(sort_order == SORT_ASCENDING) - src = column_sort_dn; - else - src = column_sort_up; + int title_x = -xposition + get_column_offset(number) + + LISTBOX_MARGIN + LISTBOX_BORDER; + title_x += get_resources()->listbox_title_margin; - int x = column_offset + - column_width - - LISTBOX_BORDER; - if(x > items_w) x = items_w; - x -= 5 + src->get_w(); + gui->set_color(get_resources()->listbox_title_color); + gui->draw_text(title_x, + LISTBOX_MARGIN + LISTBOX_BORDER + get_text_ascent(MEDIUMFONT), + column_titles[number]); + +// Column sort order + if(number == sort_column) { + BC_Pixmap *src = sort_order == SORT_ASCENDING ? + column_sort_dn : column_sort_up; + +// int column_offset = get_column_offset(number) - xposition + LISTBOX_BORDER; +// int column_width = get_column_width(number, 1); +// int toggle_x = column_offset + column_width - LISTBOX_BORDER; +// if( toggle_x > items_w ) toggle_x = items_w; +// toggle_x -= 5 + src->get_w(); + + int x = title_x + + get_text_width(MEDIUMFONT, column_titles[number]) + + LISTBOX_MARGIN; + gui->draw_pixmap(src, x, title_h / 2 - src->get_h() / 2 + LISTBOX_BORDER); } - - - int x = -xposition + - get_column_offset(number) + - LISTBOX_MARGIN + - LISTBOX_BORDER; - x += get_resources()->listbox_title_margin; - - gui->set_color(get_resources()->listbox_title_color); - gui->draw_text(x, - LISTBOX_MARGIN + LISTBOX_BORDER + get_text_ascent(MEDIUMFONT), - _(column_titles[number])); } int BC_ListBox::draw_titles(int flash) diff --git a/cinelerra-5.1/guicast/bclistbox.h b/cinelerra-5.1/guicast/bclistbox.h index e0654105..8d425080 100644 --- a/cinelerra-5.1/guicast/bclistbox.h +++ b/cinelerra-5.1/guicast/bclistbox.h @@ -27,7 +27,7 @@ #include "bcscrollbar.h" #include "bcsubwindow.h" #include "bctoggle.h" -#include "colors.h" +#include "bccolors.h" #define BCPOPUPLISTBOX_W 25 #define BCPOPUPLISTBOX_H 25 diff --git a/cinelerra-5.1/guicast/bclistboxitem.h b/cinelerra-5.1/guicast/bclistboxitem.h index 4ec0e475..bb9bc126 100644 --- a/cinelerra-5.1/guicast/bclistboxitem.h +++ b/cinelerra-5.1/guicast/bclistboxitem.h @@ -24,7 +24,7 @@ #include "arraylist.h" #include "bcpixmap.inc" -#include "colors.h" +#include "bccolors.h" #include "vframe.h" diff --git a/cinelerra-5.1/guicast/bcmenubar.C b/cinelerra-5.1/guicast/bcmenubar.C index 135a7d44..908567ec 100644 --- a/cinelerra-5.1/guicast/bcmenubar.C +++ b/cinelerra-5.1/guicast/bcmenubar.C @@ -27,7 +27,7 @@ #include "bcpopupmenu.h" #include "bcresources.h" #include "bcsignals.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "keys.h" #include diff --git a/cinelerra-5.1/guicast/bcmenuitem.C b/cinelerra-5.1/guicast/bcmenuitem.C index c516622a..f51a46d6 100644 --- a/cinelerra-5.1/guicast/bcmenuitem.C +++ b/cinelerra-5.1/guicast/bcmenuitem.C @@ -28,7 +28,7 @@ #include "bcresources.h" #include "bcsignals.h" #include "bcwindowbase.h" -#include "colors.h" +#include "bccolors.h" #include diff --git a/cinelerra-5.1/guicast/bcmenuitem.h b/cinelerra-5.1/guicast/bcmenuitem.h index 3728c0b6..5b40a05c 100644 --- a/cinelerra-5.1/guicast/bcmenuitem.h +++ b/cinelerra-5.1/guicast/bcmenuitem.h @@ -50,7 +50,7 @@ public: void set_hotkey_text(const char *text); int set_shift(int value = 1); int set_alt(int value = 1); - void set_ctrl(int value); + void set_ctrl(int value = 1); int deactivate_submenus(BC_MenuPopup *exclude); int activate_submenu(); diff --git a/cinelerra-5.1/guicast/bcmeter.C b/cinelerra-5.1/guicast/bcmeter.C index 22a420a9..6ece16f2 100644 --- a/cinelerra-5.1/guicast/bcmeter.C +++ b/cinelerra-5.1/guicast/bcmeter.C @@ -24,7 +24,7 @@ #include "bcpixmap.h" #include "bcresources.h" #include "bcwindow.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "vframe.h" #include diff --git a/cinelerra-5.1/guicast/bcpan.C b/cinelerra-5.1/guicast/bcpan.C index e35925f4..d8bce872 100644 --- a/cinelerra-5.1/guicast/bcpan.C +++ b/cinelerra-5.1/guicast/bcpan.C @@ -24,7 +24,7 @@ #include "bcpopup.h" #include "bcresources.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "rotateframe.h" #include "units.h" diff --git a/cinelerra-5.1/guicast/bcpopupmenu.C b/cinelerra-5.1/guicast/bcpopupmenu.C index 8421a6bf..4d3144b5 100644 --- a/cinelerra-5.1/guicast/bcpopupmenu.C +++ b/cinelerra-5.1/guicast/bcpopupmenu.C @@ -26,7 +26,7 @@ #include "bcpopupmenu.h" #include "bcresources.h" #include "bcsignals.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include #include "vframe.h" diff --git a/cinelerra-5.1/guicast/bcpot.C b/cinelerra-5.1/guicast/bcpot.C index e934fc53..60807911 100644 --- a/cinelerra-5.1/guicast/bcpot.C +++ b/cinelerra-5.1/guicast/bcpot.C @@ -21,7 +21,7 @@ #include "bcpot.h" #include "bcresources.h" -#include "colors.h" +#include "bccolors.h" #include "keys.h" #include "units.h" #include "vframe.h" diff --git a/cinelerra-5.1/guicast/bcprogress.C b/cinelerra-5.1/guicast/bcprogress.C index 7cca92b9..100ef766 100644 --- a/cinelerra-5.1/guicast/bcprogress.C +++ b/cinelerra-5.1/guicast/bcprogress.C @@ -25,7 +25,7 @@ #define PROGRESS_UP 0 #define PROGRESS_HI 1 -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "bcprogress.h" #include "bcpixmap.h" diff --git a/cinelerra-5.1/guicast/bcresources.C b/cinelerra-5.1/guicast/bcresources.C index 4ae705ad..e932af59 100644 --- a/cinelerra-5.1/guicast/bcresources.C +++ b/cinelerra-5.1/guicast/bcresources.C @@ -27,7 +27,7 @@ #include "bcsignals.h" #include "bcsynchronous.h" #include "bcwindowbase.h" -#include "colors.h" +#include "bccolors.h" #include "bccmodels.h" #include "cstrdup.h" #include "fonts.h" @@ -72,10 +72,14 @@ static const char *def_big_font = "-*-bitstream charter-bold-r-normal-*-*-0-%d-%d-p-0-iso8859-1"; // 160 static const char *def_big_font2 = "-*-nimbus sans l-bold-r-normal-*-*-0-%d-%d-p-0-iso8859-1"; // 160 +static const char *def_clock_font = "-*-helvetica-bold-r-normal-*-%d-*"; // 16 +static const char *def_clock_font2 = "-*-helvetica-bold-r-normal-*-%d-*"; // 18 static const char *def_small_fontset = "-*-helvetica-medium-r-normal-*-%d-*";// 10 static const char *def_medium_fontset = "-*-helvetica-bold-r-normal-*-%d-*"; // 14 static const char *def_large_fontset = "-*-helvetica-bold-r-normal-*-%d-*"; // 18 static const char *def_big_fontset = "-*-helvetica-bold-r-normal-*-%d-*"; // 24 +static const char *def_clock_fontset = "-*-helvetica-bold-r-normal-*-%d-*"; // 16 + static const char *def_small_font_xft = "Sans:pixelsize=%.4f"; // 10.6667 static const char *def_small_b_font_xft = "Sans:bold:pixelsize=%.4f"; // 10.6667 static const char *def_medium_font_xft = "Sans:pixelsize=%.4f"; // 13.3333 @@ -84,6 +88,7 @@ static const char *def_large_font_xft = "Sans:pixelsize=%.4f"; // 21.3 static const char *def_large_b_font_xft = "Sans:bold:pixelsize=%.4f"; // 21.3333 static const char *def_big_font_xft = "Sans:pixelsize=37.3333"; // 37.3333 static const char *def_big_b_font_xft = "Sans:bold:pixelsize=37.33333"; // 37.3333 +static const char *def_clock_font_xft = "Sans:pixelsize=16"; // 16 #define default_font_xft2 "-microsoft-verdana-*-*-*-*-*-*-*-*-*-*-*-*" @@ -95,10 +100,13 @@ const char* BC_Resources::large_font = 0; const char* BC_Resources::large_font2 = 0; const char* BC_Resources::big_font = 0; const char* BC_Resources::big_font2 = 0; +const char* BC_Resources::clock_font = 0; +const char* BC_Resources::clock_font2 = 0; const char* BC_Resources::small_fontset = 0; const char* BC_Resources::medium_fontset = 0; const char* BC_Resources::large_fontset = 0; const char* BC_Resources::big_fontset = 0; +const char* BC_Resources::clock_fontset = 0; const char* BC_Resources::small_font_xft = 0; const char* BC_Resources::small_font_xft2 = 0; const char* BC_Resources::small_b_font_xft = 0; @@ -111,6 +119,8 @@ const char* BC_Resources::large_b_font_xft = 0; const char* BC_Resources::big_font_xft = 0; const char* BC_Resources::big_font_xft2 = 0; const char* BC_Resources::big_b_font_xft = 0; +const char* BC_Resources::clock_font_xft = 0; +const char* BC_Resources::clock_font_xft2 = 0; #define def_font(v, s...) do { sprintf(string,def_##v,s); v = cstrdup(string); } while(0) #define set_font(v, s) do { sprintf(string, "%s", s); v = cstrdup(string); } while(0) @@ -125,11 +135,14 @@ void BC_Resources::init_font_defs(double scale) def_font(large_font, iround(scale*18)); def_font(large_font2, iround(scale*20)); def_font(big_font, iround(scale*160), iround(scale*160)); - def_font(big_font2, iround(scale*160), iround(scale*160)); + def_font(big_font2, iround(scale*16), iround(scale*16)); + def_font(clock_font, iround(scale*16), iround(scale*16)); + def_font(clock_font2, iround(scale*16), iround(scale*16)); def_font(small_fontset, iround(scale*10)); def_font(medium_fontset, iround(scale*14)); def_font(large_fontset, iround(scale*18)); def_font(big_fontset, iround(scale*24)); + def_font(clock_fontset, iround(scale*16)); def_font(small_font_xft, (scale*10.6667)); def_font(small_b_font_xft, (scale*10.6667)); def_font(medium_font_xft, (scale*13.3333)); @@ -138,11 +151,13 @@ void BC_Resources::init_font_defs(double scale) def_font(large_b_font_xft, (scale*21.3333)); def_font(big_font_xft, (scale*37.3333)); def_font(big_b_font_xft, (scale*37.3333)); + def_font(clock_font_xft, (scale*16)); set_font(small_font_xft2, default_font_xft2); set_font(medium_font_xft2, default_font_xft2); set_font(large_font_xft2, default_font_xft2); set_font(big_font_xft2, default_font_xft2); + set_font(clock_font_xft2, default_font_xft2); } void BC_Resources::finit_font_defs() { @@ -154,10 +169,13 @@ void BC_Resources::finit_font_defs() delete [] large_font2; delete [] big_font; delete [] big_font2; + delete [] clock_font; + delete [] clock_font2; delete [] small_fontset; delete [] medium_fontset; delete [] large_fontset; delete [] big_fontset; + delete [] clock_fontset; delete [] small_font_xft; delete [] small_b_font_xft; delete [] medium_font_xft; @@ -166,11 +184,13 @@ void BC_Resources::finit_font_defs() delete [] large_b_font_xft; delete [] big_font_xft; delete [] big_b_font_xft; + delete [] clock_font_xft; delete [] small_font_xft2; delete [] medium_font_xft2; delete [] large_font_xft2; delete [] big_font_xft2; + delete [] clock_font_xft2; } diff --git a/cinelerra-5.1/guicast/bcresources.h b/cinelerra-5.1/guicast/bcresources.h index 8ff04649..d5c9a069 100644 --- a/cinelerra-5.1/guicast/bcresources.h +++ b/cinelerra-5.1/guicast/bcresources.h @@ -306,31 +306,31 @@ public: double font_scale, icon_scale; // fonts - static const char *small_font; - static const char *medium_font; - static const char *large_font; - static const char *big_font; -// Backup of fonts in case the first choices don't exist - static const char *small_font2; - static const char *medium_font2; - static const char *large_font2; - static const char *big_font2; + static const char *small_font, *small_font2; + static const char *medium_font, *medium_font2; + static const char *large_font, *large_font2; + static const char *big_font, *big_font2; + static const char *clock_font, *clock_font2; static const char *small_fontset; static const char *medium_fontset; static const char *large_fontset; static const char *big_fontset; + static const char *clock_fontset; static const char *small_font_xft, *small_b_font_xft; static const char *medium_font_xft, *medium_b_font_xft; static const char *large_font_xft, *large_b_font_xft; static const char *big_font_xft, *big_b_font_xft; + static const char *clock_font_xft, *clock_b_font_xft; // Backup of fonts in case the first choices don't exist static const char *small_font_xft2; static const char *medium_font_xft2; static const char *large_font_xft2; static const char *big_font_xft2; + static const char *clock_font_xft2; + void init_font_defs(double scale); void finit_font_defs(); diff --git a/cinelerra-5.1/guicast/bcscrollbar.C b/cinelerra-5.1/guicast/bcscrollbar.C index bc2e4f99..389cacf8 100644 --- a/cinelerra-5.1/guicast/bcscrollbar.C +++ b/cinelerra-5.1/guicast/bcscrollbar.C @@ -23,7 +23,7 @@ #include "bcresources.h" #include "bcscrollbar.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include "vframe.h" #include diff --git a/cinelerra-5.1/guicast/bcslider.C b/cinelerra-5.1/guicast/bcslider.C index 79283d29..7a60a1f4 100644 --- a/cinelerra-5.1/guicast/bcslider.C +++ b/cinelerra-5.1/guicast/bcslider.C @@ -22,7 +22,7 @@ #include "bcpixmap.h" #include "bcresources.h" #include "bcslider.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "keys.h" #include "units.h" diff --git a/cinelerra-5.1/guicast/bctextbox.C b/cinelerra-5.1/guicast/bctextbox.C index 5d1257eb..bdbe6040 100644 --- a/cinelerra-5.1/guicast/bctextbox.C +++ b/cinelerra-5.1/guicast/bctextbox.C @@ -24,11 +24,12 @@ #include "bcsignals.h" #include "bctextbox.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include #include "cursors.h" #include "filesystem.h" #include "keys.h" +#include "language.h" #include #include "bctimer.h" #include "vframe.h" @@ -133,6 +134,7 @@ BC_TextBox::~BC_TextBox() delete suggestions_popup; suggestions->remove_all_objects(); delete suggestions; + delete menu; delete [] wtext; if( size > 0 ) delete [] text; @@ -175,6 +177,7 @@ int BC_TextBox::reset_parameters(int rows, int has_border, int font, int size) separators = 0; xscroll = 0; yscroll = 0; + menu = 0; dirty = 1; selection_active = 0; return 0; @@ -247,6 +250,7 @@ int BC_TextBox::text_update(const wchar_t *wcp, int wsz, char *tcp, int tsz) int BC_TextBox::initialize() { + if (!skip_cursor) skip_cursor = new Timer; skip_cursor->update(); @@ -288,6 +292,10 @@ int BC_TextBox::initialize() draw(0); set_cursor(IBEAM_CURSOR, 0, 0); show_window(0); + + add_subwindow(menu = new BC_TextMenu(this)); + menu->create_objects(); + return 0; } @@ -779,12 +787,10 @@ int BC_TextBox::button_press_event() const int debug = 0; if(!enabled) return 0; - if(get_buttonpress() != WHEEL_UP && - get_buttonpress() != WHEEL_DOWN && - get_buttonpress() != LEFT_BUTTON && - get_buttonpress() != MIDDLE_BUTTON) return 0; - - +// if(get_buttonpress() != WHEEL_UP && +// get_buttonpress() != WHEEL_DOWN && +// get_buttonpress() != LEFT_BUTTON && +// get_buttonpress() != MIDDLE_BUTTON) return 0; if(debug) printf("BC_TextBox::button_press_event %d\n", __LINE__); @@ -822,6 +828,11 @@ int BC_TextBox::button_press_event() update_scroll = 1; } else + if(get_buttonpress() == RIGHT_BUTTON) + { + menu->activate_menu(); + } + else { cursor_letter = get_cursor_letter(top_level->cursor_x, top_level->cursor_y); @@ -1608,29 +1619,15 @@ int BC_TextBox::keypress_event() if( ctrl_down() ) { switch( get_keypress() ) { case 'c': case 'C': { - if(highlight_letter1 != highlight_letter2) { - copy_selection(SECONDARY_SELECTION); - result = 1; - } + result = copy(0); break; } case 'v': case 'V': { - paste_selection(SECONDARY_SELECTION); - find_ibeam(1); - if(keypress_draw) draw(1); + result = paste(0); dispatch_event = 1; - result = 1; break; } case 'x': case 'X': { - if(highlight_letter1 != highlight_letter2) { - copy_selection(SECONDARY_SELECTION); - delete_selection(highlight_letter1, highlight_letter2, wtext_len); - highlight_letter2 = ibeam_letter = highlight_letter1; - } - - find_ibeam(1); - if(keypress_draw) draw(1); + result = cut(0); dispatch_event = 1; - result = 1; break; } case 'u': case 'U': { if( shift_down() ) { @@ -1661,6 +1658,53 @@ int BC_TextBox::keypress_event() } +int BC_TextBox::cut(int do_update) +{ + if( highlight_letter1 != highlight_letter2 ) { + int wtext_len = wtext_update(); + copy_selection(SECONDARY_SELECTION); + delete_selection(highlight_letter1, highlight_letter2, wtext_len); + highlight_letter2 = ibeam_letter = highlight_letter1; + } + + find_ibeam(1); + if( keypress_draw ) + draw(1); + + if( do_update ) { + skip_cursor->update(); + handle_event(); + } + return 1; +} + +int BC_TextBox::copy(int do_update) +{ + int result = 0; + if( highlight_letter1 != highlight_letter2 ) { + copy_selection(SECONDARY_SELECTION); + result = 1; + if( do_update ) { + skip_cursor->update(); + } + } + return result; +} + +int BC_TextBox::paste(int do_update) +{ + paste_selection(SECONDARY_SELECTION); + find_ibeam(1); + if( keypress_draw ) + draw(1); + if( do_update ) { + skip_cursor->update(); + handle_event(); + } + return 1; +} + + int BC_TextBox::uses_text() { return 1; @@ -2843,6 +2887,66 @@ void BC_TumbleTextBox::set_boundaries(float min, float max) tumbler->set_boundaries(min, max); } + + +BC_TextMenu::BC_TextMenu(BC_TextBox *textbox) + : BC_PopupMenu(0, 0, 0, "", 0) +{ + this->textbox = textbox; +} + +BC_TextMenu::~BC_TextMenu() +{ +} + +void BC_TextMenu::create_objects() +{ + add_item(new BC_TextMenuCut(this)); + add_item(new BC_TextMenuCopy(this)); + add_item(new BC_TextMenuPaste(this)); +} + + +BC_TextMenuCut::BC_TextMenuCut(BC_TextMenu *menu) + : BC_MenuItem(_("Cut")) +{ + this->menu = menu; +} + +int BC_TextMenuCut::handle_event() +{ + menu->textbox->cut(1); + + return 0; +} + + +BC_TextMenuCopy::BC_TextMenuCopy(BC_TextMenu *menu) + : BC_MenuItem(_("Copy")) +{ + this->menu = menu; +} + +int BC_TextMenuCopy::handle_event() +{ + menu->textbox->copy(1); + return 0; +} + + +BC_TextMenuPaste::BC_TextMenuPaste(BC_TextMenu *menu) + : BC_MenuItem(_("Paste")) +{ + this->menu = menu; +} + +int BC_TextMenuPaste::handle_event() +{ + menu->textbox->paste(1); + return 0; +} + + void BC_TumbleTextBox::set_tooltip(const char *text) { textbox->set_tooltip(text); diff --git a/cinelerra-5.1/guicast/bctextbox.h b/cinelerra-5.1/guicast/bctextbox.h index 89d77432..e461767e 100644 --- a/cinelerra-5.1/guicast/bctextbox.h +++ b/cinelerra-5.1/guicast/bctextbox.h @@ -23,6 +23,8 @@ #define BCTEXTBOX_H #include "bclistbox.h" +#include "bcmenuitem.h" +#include "bcpopupmenu.h" #include "bcsubwindow.h" #include "bctumble.h" #include "fonts.h" @@ -39,7 +41,7 @@ class BC_TextBoxSuggestions; class BC_ScrollTextBoxXScroll; class BC_ScrollTextBoxYScroll; class BC_ScrollTextBoxText; - +class BC_TextMenu; class BC_TextBox : public BC_SubWindow { @@ -118,6 +120,10 @@ public: int reposition_window(int x, int y, int w = -1, int rows = -1); int uses_text(); + int cut(int do_update); + int copy(int do_update); + int paste(int do_update); + static int calculate_h(BC_WindowBase *gui, int font, int has_border, int rows); static int calculate_row_h(int rows, BC_WindowBase *parent_window, int has_border = 1, int font = MEDIUMFONT); static int pixels_to_rows(BC_WindowBase *window, int font, int pixels); @@ -157,6 +163,7 @@ public: BC_ScrollTextBoxYScroll *yscroll; private: int reset_parameters(int rows, int has_border, int font, int size); + BC_TextMenu *menu; void draw(int flush); void draw_border(); void draw_cursor(); @@ -463,4 +470,40 @@ public: }; +class BC_TextMenu : public BC_PopupMenu +{ +public: + BC_TextMenu(BC_TextBox *textbox); + ~BC_TextMenu(); + + void create_objects(); + + BC_TextBox *textbox; +}; + +class BC_TextMenuCut : public BC_MenuItem +{ +public: + BC_TextMenuCut(BC_TextMenu *menu); + int handle_event(); + BC_TextMenu *menu; +}; + +class BC_TextMenuCopy : public BC_MenuItem +{ +public: + BC_TextMenuCopy(BC_TextMenu *menu); + int handle_event(); + BC_TextMenu *menu; +}; + +class BC_TextMenuPaste : public BC_MenuItem +{ +public: + BC_TextMenuPaste(BC_TextMenu *menu); + int handle_event(); + BC_TextMenu *menu; +}; + + #endif diff --git a/cinelerra-5.1/guicast/bctitle.h b/cinelerra-5.1/guicast/bctitle.h index 3a54c728..adb59f24 100644 --- a/cinelerra-5.1/guicast/bctitle.h +++ b/cinelerra-5.1/guicast/bctitle.h @@ -23,7 +23,7 @@ #define BCTITLE_H #include "bcsubwindow.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" class BC_Title : public BC_SubWindow diff --git a/cinelerra-5.1/guicast/bctoggle.C b/cinelerra-5.1/guicast/bctoggle.C index 11554673..67af31ec 100644 --- a/cinelerra-5.1/guicast/bctoggle.C +++ b/cinelerra-5.1/guicast/bctoggle.C @@ -24,35 +24,26 @@ #include "bcsignals.h" #include "bctoggle.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include "cursors.h" #include "fonts.h" #include "vframe.h" #include -BC_Toggle::BC_Toggle(int x, int y, - VFrame **data, - int value, - const char *caption, - int bottom_justify, - int font, - int color) +BC_Toggle::BC_Toggle(int x, int y, VFrame **data, int value, + const char *caption, int bottom_justify, int font, int color) : BC_SubWindow(x, y, 0, 0, -1) { this->data = data; - for(int i = 0; i < TOGGLE_IMAGES; i++) - images[i] = 0; + for( int i=0; ivalue = value; strcpy(this->caption, caption); this->bottom_justify = bottom_justify; this->font = font; - if(color >= 0) - this->color = color; - else - this->color = get_resources()->default_text_color; + this->color = color >= 0 ? color : get_resources()->default_text_color; select_drag = 0; enabled = 1; underline = -1; @@ -62,7 +53,7 @@ BC_Toggle::BC_Toggle(int x, int y, BC_Toggle::~BC_Toggle() { - for(int i = 0; i < TOGGLE_IMAGES; i++) if(images[i]) delete images[i]; + for( int i=0; iget_text_width(font, caption); *text_h = gui->get_text_height(font); - if(resources->toggle_highlight_bg) - { + if( resources->toggle_highlight_bg ) { *text_w += resources->toggle_text_margin * 2; *text_h = MAX(*text_h, resources->toggle_highlight_bg->get_h()); } - if(*text_h > *h) - { + if( *text_h > *h ) { *toggle_y = (*text_h - *h) >> 1; *h = *text_h; } else *text_y = (*h - *text_h) >> 1; - if(bottom_justify) - { + if( bottom_justify ) { *text_y = *h - *text_h; *text_line = *h - gui->get_text_descent(font); } @@ -164,14 +133,12 @@ int BC_Toggle::set_images(VFrame **data) { delete bg_image; bg_image = 0; - for(int i = 0; i < TOGGLE_IMAGES; i++) - { - if(images[i]) delete images[i]; + for( int i=0; itoggle_highlight_bg) - { + if( resources->toggle_highlight_bg ) { bg_image = new BC_Pixmap(top_level, resources->toggle_highlight_bg, PIXMAP_ALPHA); @@ -194,16 +161,13 @@ int BC_Toggle::draw_face(int flash, int flush) { BC_Resources *resources = get_resources(); draw_top_background(parent_window, 0, 0, get_w(), get_h()); - if(has_caption()) - { - if(enabled && + if( has_caption() ) { + if( enabled && (status == BC_Toggle::TOGGLE_UPHI || status == BC_Toggle::TOGGLE_DOWN || - status == BC_Toggle::TOGGLE_CHECKEDHI)) - { + status == BC_Toggle::TOGGLE_CHECKEDHI) ) { // Draw highlight image - if(bg_image) - { + if( bg_image ) { int x = text_x; int y = text_line - get_text_ascent(font) / 2 - bg_image->get_h() / 2; @@ -226,7 +190,7 @@ int BC_Toggle::draw_face(int flash, int flush) } set_opaque(); - if(enabled) + if( enabled ) set_color(color); else set_color(get_resources()->disabled_text_color); @@ -236,8 +200,7 @@ int BC_Toggle::draw_face(int flash, int flush) caption); // Draw underline - if(underline >= 0) - { + if( underline >= 0 ) { int x = text_x + resources->toggle_text_margin; int y = text_line + 1; int x1 = get_text_width(current_font, caption, underline) + x; @@ -248,21 +211,21 @@ int BC_Toggle::draw_face(int flash, int flush) } draw_pixmap(images[status]); - if(flash) this->flash(0); - if(flush) this->flush(); + if( flash ) this->flash(0); + if( flush ) this->flush(); return 0; } void BC_Toggle::enable() { enabled = 1; - if(parent_window) draw_face(1, 1); + if( parent_window ) draw_face(1, 1); } void BC_Toggle::disable() { enabled = 0; - if(parent_window) draw_face(1, 1); + if( parent_window ) draw_face(1, 1); } void BC_Toggle::set_status(int value) @@ -273,10 +236,9 @@ void BC_Toggle::set_status(int value) int BC_Toggle::repeat_event(int64_t duration) { - if(tooltip_text && tooltip_text[0] != 0 && + if( tooltip_text && tooltip_text[0] != 0 && duration == top_level->get_resources()->tooltip_delay && - (status == BC_Toggle::TOGGLE_UPHI || status == BC_Toggle::TOGGLE_CHECKEDHI)) - { + (status == BC_Toggle::TOGGLE_UPHI || status == BC_Toggle::TOGGLE_CHECKEDHI) ) { show_tooltip(); return 1; } @@ -285,9 +247,8 @@ int BC_Toggle::repeat_event(int64_t duration) int BC_Toggle::cursor_enter_event() { - if(top_level->event_win == win && enabled) - { - if(top_level->button_down) + if( top_level->event_win == win && enabled ) { + if( top_level->button_down ) status = BC_Toggle::TOGGLE_DOWN; else status = value ? BC_Toggle::TOGGLE_CHECKEDHI : BC_Toggle::TOGGLE_UPHI; @@ -299,14 +260,12 @@ int BC_Toggle::cursor_enter_event() int BC_Toggle::cursor_leave_event() { hide_tooltip(); - if(!value && status == BC_Toggle::TOGGLE_UPHI) - { + if( !value && status == BC_Toggle::TOGGLE_UPHI ) { status = BC_Toggle::TOGGLE_UP; draw_face(1, 1); } else - if(status == BC_Toggle::TOGGLE_CHECKEDHI) - { + if( status == BC_Toggle::TOGGLE_CHECKEDHI ) { status = BC_Toggle::TOGGLE_CHECKED; draw_face(1, 1); } @@ -316,15 +275,13 @@ int BC_Toggle::cursor_leave_event() int BC_Toggle::button_press_event() { hide_tooltip(); - if(top_level->event_win == win && get_buttonpress() == 1 && enabled) - { + if( top_level->event_win == win && get_buttonpress() == 1 && enabled ) { status = BC_Toggle::TOGGLE_DOWN; // Change value now for select drag mode. // Radial always goes to 1 - if(select_drag) - { - if(!is_radial) + if( select_drag ) { + if( !is_radial ) value = !value; else value = 1; @@ -344,12 +301,10 @@ int BC_Toggle::button_release_event() int result = 0; hide_tooltip(); - if(top_level->event_win == win) - { + if( top_level->event_win == win ) { // Keep value regardless of status if drag mode. - if(select_drag) - { - if(value) + if( select_drag ) { + if( value ) status = BC_Toggle::TOGGLE_CHECKEDHI; else status = BC_Toggle::TOGGLE_UPHI; @@ -357,16 +312,13 @@ int BC_Toggle::button_release_event() } else // Change value only if button down for default mode. - if(status == BC_Toggle::TOGGLE_DOWN) - { + if( status == BC_Toggle::TOGGLE_DOWN ) { // Radial always goes to 1. - if(!value || is_radial) - { + if( !value || is_radial ) { status = BC_Toggle::TOGGLE_CHECKEDHI; value = 1; } - else - { + else { status = BC_Toggle::TOGGLE_UPHI; value = 0; } @@ -380,21 +332,18 @@ int BC_Toggle::button_release_event() int BC_Toggle::cursor_motion_event() { - if(top_level->button_down && + if( top_level->button_down && top_level->event_win == win && - !cursor_inside()) - { - if(status == BC_Toggle::TOGGLE_DOWN) - { - if(value) + !cursor_inside() ) { + if( status == BC_Toggle::TOGGLE_DOWN ) { + if( value ) status = BC_Toggle::TOGGLE_CHECKED; else status = BC_Toggle::TOGGLE_UP; draw_face(1, 1); } else - if(status == BC_Toggle::TOGGLE_UPHI) - { + if( status == BC_Toggle::TOGGLE_UPHI ) { status = BC_Toggle::TOGGLE_CHECKEDHI; draw_face(1, 1); } @@ -409,32 +358,29 @@ int BC_Toggle::get_value() int BC_Toggle::set_value(int value, int draw) { - if(value != this->value) - { + if( value != this->value ) { this->value = value; - if(value) - { - switch(status) - { - case BC_Toggle::TOGGLE_UP: - status = BC_Toggle::TOGGLE_CHECKED; - break; - case BC_Toggle::TOGGLE_UPHI: - status = BC_Toggle::TOGGLE_CHECKEDHI; - break; + if( value ) { + switch( status ) { + case BC_Toggle::TOGGLE_UP: + status = BC_Toggle::TOGGLE_CHECKED; + break; + case BC_Toggle::TOGGLE_UPHI: + status = BC_Toggle::TOGGLE_CHECKEDHI; + break; } } - else - switch(status) - { + else { + switch( status ) { case BC_Toggle::TOGGLE_CHECKED: status = BC_Toggle::TOGGLE_UP; break; case BC_Toggle::TOGGLE_CHECKEDHI: status = BC_Toggle::TOGGLE_UPHI; break; + } } - if(draw) draw_face(1, 1); + if( draw ) draw_face(1, 1); } return 0; } @@ -456,56 +402,29 @@ int BC_Toggle::has_caption() return (caption != 0 && caption[0] != 0); } -BC_Radial::BC_Radial(int x, - int y, - int value, - const char *caption, - int font, - int color) - : BC_Toggle(x, - y, +BC_Radial::BC_Radial(int x, int y, int value, + const char *caption, int font, int color) + : BC_Toggle(x, y, BC_WindowBase::get_resources()->radial_images, - value, - caption, - 0, - font, - color) + value, caption, 0, font, color) { is_radial = 1; } -BC_CheckBox::BC_CheckBox(int x, - int y, - int value, - const char *caption, - int font, - int color) - : BC_Toggle(x, - y, +BC_CheckBox::BC_CheckBox(int x, int y, int value, + const char *caption, int font, int color) + : BC_Toggle(x, y, BC_WindowBase::get_resources()->checkbox_images, - value, - caption, - 0, - font, - color) + value, caption, 0, font, color) { this->value = 0; } -BC_CheckBox::BC_CheckBox(int x, - int y, - int *value, - const char *caption, - int font, - int color) - : BC_Toggle(x, - y, +BC_CheckBox::BC_CheckBox(int x, int y, int *value, + const char *caption, int font, int color) + : BC_Toggle(x, y, BC_WindowBase::get_resources()->checkbox_images, - *value, - caption, - 1, - font, - color) + *value, caption, 1, font, color) { this->value = value; } @@ -529,20 +448,17 @@ int BC_CheckBox::handle_event() return 1; } +int BC_CheckBox::calculate_h(BC_WindowBase *gui, int font) +{ + int w, h; + calculate_extents(gui, &w, &h, "X", font); + return h; +} -BC_Label::BC_Label(int x, - int y, - int value, - int font, - int color) - : BC_Toggle(x, - y, - BC_WindowBase::get_resources()->label_images, - value, - "", - 0, - font, - color) +BC_Label::BC_Label(int x, int y, int value, int font, int color) + : BC_Toggle(x, y, + BC_WindowBase::get_resources()->label_images, value, + "", 0, font, color) { } diff --git a/cinelerra-5.1/guicast/bctoggle.h b/cinelerra-5.1/guicast/bctoggle.h index 2fc32150..60979130 100644 --- a/cinelerra-5.1/guicast/bctoggle.h +++ b/cinelerra-5.1/guicast/bctoggle.h @@ -24,7 +24,7 @@ #include "bcbitmap.inc" #include "bcsubwindow.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "vframe.inc" @@ -143,6 +143,7 @@ public: int font = MEDIUMFONT, int color = -1); virtual int handle_event(); + static int calculate_h(BC_WindowBase *gui, int font=MEDIUMFONT); static void calculate_extents(BC_WindowBase *gui, int *w, int *h, const char *caption="", int font=MEDIUMFONT); diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index ec750768..6599369e 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -36,7 +36,7 @@ #include "bcwindowbase.h" #include "bcwindowevents.h" #include "bccmodels.h" -#include "colors.h" +#include "bccolors.h" #include "condition.h" #include "cursors.h" #include "bchash.h" @@ -223,7 +223,12 @@ BC_WindowBase::~BC_WindowBase() } else #endif + { +// _XftDisplayInfo needs a lock. + get_resources()->create_window_lock->lock("BC_WindowBase::~BC_WindowBase"); XCloseDisplay(display); + get_resources()->create_window_lock->unlock(); + } // clipboard uses a different display connection clipboard->stop_clipboard(); delete clipboard; @@ -326,16 +331,24 @@ int BC_WindowBase::initialize() #ifdef HAVE_LIBXXF86VM vm_switched = 0; #endif - smallfont_xft = 0; - bold_largefont_xft = 0; - bold_mediumfont_xft = 0; - bold_smallfont_xft = 0; input_method = 0; input_context = 0; + smallfont = 0; + mediumfont = 0; + largefont = 0; + bigfont = 0; + clockfont = 0; + + smallfont_xft = 0; mediumfont_xft = 0; largefont_xft = 0; bigfont_xft = 0; + clockfont_xft = 0; + + bold_smallfont_xft = 0; + bold_mediumfont_xft = 0; + bold_largefont_xft = 0; #ifdef SINGLE_THREAD completion_lock = new Condition(0, "BC_WindowBase::completion_lock"); #else @@ -2298,6 +2311,10 @@ int BC_WindowBase::init_fonts() if( !(bigfont = XLoadQueryFont(display, _(resources.big_font2))) ) bigfont = XLoadQueryFont(display, "fixed"); + if((clockfont = XLoadQueryFont(display, _(resources.clock_font))) == NULL) + if((clockfont = XLoadQueryFont(display, _(resources.clock_font2))) == NULL) + clockfont = XLoadQueryFont(display, "fixed"); + init_xft(); if(get_resources()->use_fontset) { @@ -2316,8 +2333,11 @@ int BC_WindowBase::init_fonts() largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); bigfontset = XCreateFontSet(display, resources.big_fontset, &m, &n, &d); if( !bigfontset ) - largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); - if(bigfontset && largefontset && mediumfontset && smallfontset) { + bigfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); + clockfontset = XCreateFontSet(display, resources.clock_fontset, &m, &n, &d); + if( !clockfontset ) + clockfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); + if(clockfontset && bigfontset && largefontset && mediumfontset && smallfontset) { curr_fontset = mediumfontset; get_resources()->use_fontset = 1; } @@ -2362,6 +2382,12 @@ void BC_WindowBase::init_xft() if(!(bigfont_xft = XftFontOpenXlfd(display, screen, resources.big_font_xft2))) bigfont_xft = XftFontOpenXlfd(display, screen, "fixed"); + if(!(clockfont_xft = + (resources.clock_font_xft[0] == '-' ? + XftFontOpenXlfd(display, screen, resources.clock_font_xft) : + XftFontOpenName(display, screen, resources.clock_font_xft))) ) + clockfont_xft = XftFontOpenXlfd(display, screen, "fixed"); + if(!(bold_smallfont_xft = (resources.small_b_font_xft[0] == '-' ? @@ -2379,21 +2405,24 @@ void BC_WindowBase::init_xft() XftFontOpenName(display, screen, resources.large_b_font_xft))) ) bold_largefont_xft = XftFontOpenXlfd(display, screen, "fixed"); -// Extension failed to locate fonts if( !smallfont_xft || !mediumfont_xft || !largefont_xft || !bigfont_xft || - !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ) { + !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft || + !clockfont_xft ) { printf("BC_WindowBase::init_fonts: no xft fonts found:" - " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n", + " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n", resources.small_font_xft, smallfont_xft, resources.medium_font_xft, mediumfont_xft, resources.large_font_xft, largefont_xft, resources.big_font_xft, bigfont_xft, + resources.clock_font_xft, clockfont_xft, resources.small_b_font_xft, bold_smallfont_xft, resources.medium_b_font_xft, bold_mediumfont_xft, resources.large_b_font_xft, bold_largefont_xft); get_resources()->use_xft = 0; exit(1); } +// _XftDisplayInfo needs a lock. + XftDefaultHasRender(display); #endif // HAVE_XFT } @@ -2744,6 +2773,7 @@ XFontStruct* BC_WindowBase::get_font_struct(int font) case MEDIUMFONT: return top_level->mediumfont; break; case LARGEFONT: return top_level->largefont; break; case BIGFONT: return top_level->bigfont; break; + case CLOCKFONT: return top_level->clockfont; break; } return 0; } @@ -2759,6 +2789,7 @@ XFontSet BC_WindowBase::get_fontset(int font) case MEDIUMFONT: fs = top_level->mediumfontset; break; case LARGEFONT: fs = top_level->largefontset; break; case BIGFONT: fs = top_level->bigfontset; break; + case CLOCKFONT: fs = top_level->clockfontset; break; } } @@ -2773,6 +2804,7 @@ XftFont* BC_WindowBase::get_xft_struct(int font) case MEDIUMFONT: return (XftFont*)top_level->mediumfont_xft; case LARGEFONT: return (XftFont*)top_level->largefont_xft; case BIGFONT: return (XftFont*)top_level->bigfont_xft; + case CLOCKFONT: return (XftFont*)top_level->clockfont_xft; case MEDIUMFONT_3D: return (XftFont*)top_level->bold_mediumfont_xft; case SMALLFONT_3D: return (XftFont*)top_level->bold_smallfont_xft; case LARGEFONT_3D: return (XftFont*)top_level->bold_largefont_xft; @@ -2783,13 +2815,6 @@ XftFont* BC_WindowBase::get_xft_struct(int font) #endif - - - - - - - int BC_WindowBase::get_current_font() { return top_level->current_font; @@ -2825,6 +2850,7 @@ void BC_WindowBase::set_fontset(int font) case MEDIUMFONT: fs = top_level->mediumfontset; break; case LARGEFONT: fs = top_level->largefontset; break; case BIGFONT: fs = top_level->bigfontset; break; + case CLOCKFONT: fs = top_level->clockfontset; break; } } diff --git a/cinelerra-5.1/guicast/bcwindowbase.h b/cinelerra-5.1/guicast/bcwindowbase.h index 263fa657..2c25dc1f 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.h +++ b/cinelerra-5.1/guicast/bcwindowbase.h @@ -743,19 +743,17 @@ private: // Font sets - XFontSet smallfontset, mediumfontset, largefontset, bigfontset, curr_fontset; - + XFontSet smallfontset, mediumfontset, largefontset, bigfontset, clockfontset; + XFontSet curr_fontset; // Fonts int current_font; - XFontStruct *smallfont, *mediumfont, *largefont, *bigfont; - + XFontStruct *smallfont, *mediumfont, *largefont, *bigfont, *clockfont; // Must be void so users don't need to include the wrong libpng version. - void *smallfont_xft, *mediumfont_xft, *largefont_xft, *bigfont_xft; - + void *smallfont_xft, *mediumfont_xft, *largefont_xft, *bigfont_xft, *clockfont_xft; + void *bold_smallfont_xft, *bold_mediumfont_xft, *bold_largefont_xft; int line_width; int line_dashes; - void *bold_largefont_xft, *bold_mediumfont_xft, *bold_smallfont_xft; int64_t current_color; // Coordinate of drag start int drag_x, drag_y; diff --git a/cinelerra-5.1/guicast/bcwindowdraw.C b/cinelerra-5.1/guicast/bcwindowdraw.C index cd28636f..6a8412de 100644 --- a/cinelerra-5.1/guicast/bcwindowdraw.C +++ b/cinelerra-5.1/guicast/bcwindowdraw.C @@ -28,7 +28,7 @@ #include "bctimer.h" #include "bcwindowbase.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include "cursors.h" #include "fonts.h" #include "vframe.h" @@ -947,7 +947,7 @@ void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap, // Hide cursor if video enabled update_video_cursor(); -//printf("BC_WindowBase::draw_bitmap 1\n"); +//printf("BC_WindowBase::draw_bitmap %d dest_y=%d\n", __LINE__, dest_y); if(dest_w <= 0 || dest_h <= 0) { // Use hardware scaling to canvas dimensions if proper color model. diff --git a/cinelerra-5.1/guicast/fonts.h b/cinelerra-5.1/guicast/fonts.h index f9ea98c2..b5662aeb 100644 --- a/cinelerra-5.1/guicast/fonts.h +++ b/cinelerra-5.1/guicast/fonts.h @@ -25,8 +25,9 @@ #define SMALLFONT 1 #define MEDIUMFONT 2 #define LARGEFONT 3 -#define MEDIUM_7SEGMENT 4 -#define BIGFONT 5 +#define BIGFONT 4 +#define CLOCKFONT 5 +#define MEDIUM_7SEGMENT 6 // no longer used // Specialized fonts not available in every widget #define BOLDFACE 0x8000 diff --git a/cinelerra-5.1/guicast/guicast.h b/cinelerra-5.1/guicast/guicast.h index fe3dffde..62a37d93 100644 --- a/cinelerra-5.1/guicast/guicast.h +++ b/cinelerra-5.1/guicast/guicast.h @@ -55,7 +55,7 @@ #include "bctoggle.h" #include "bctumble.h" #include "bcwindow.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "bctimer.h" #include "errorbox.h" diff --git a/cinelerra-5.1/guicast/test4.C b/cinelerra-5.1/guicast/test4.C index a878a19d..23535cd1 100644 --- a/cinelerra-5.1/guicast/test4.C +++ b/cinelerra-5.1/guicast/test4.C @@ -13,7 +13,7 @@ #include "bcwindow.h" #include "bcsignals.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" #include "thread.h" #include "vframe.h" diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index fdd24ce0..2573e56b 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -1050,6 +1050,18 @@ void VFrame::flip_horiz() int VFrame::copy_from(VFrame *frame) { + if(this->w != frame->get_w() || + this->h != frame->get_h()) + { + printf("VFrame::copy_from %d sizes differ src %dx%d != dst %dx%d\n", + __LINE__, + frame->get_w(), + frame->get_h(), + get_w(), + get_h()); + return 1; + } + int w = MIN(this->w, frame->get_w()); int h = MIN(this->h, frame->get_h()); timestamp = frame->timestamp; @@ -1660,6 +1672,7 @@ void VFrame::smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3) } } + void VFrame::draw_rect(int x1, int y1, int x2, int y2) { draw_line(x1, y1, x2, y1); @@ -1668,6 +1681,52 @@ void VFrame::draw_rect(int x1, int y1, int x2, int y2) draw_line(x1, y2 - 1, x1, y1 + 1); } + +void VFrame::draw_oval(int x1, int y1, int x2, int y2) +{ + int w = x2 - x1; + int h = y2 - y1; + int center_x = (x2 + x1) / 2; + int center_y = (y2 + y1) / 2; + int x_table[h / 2]; + +//printf("VFrame::draw_oval %d %d %d %d %d\n", __LINE__, x1, y1, x2, y2); + + for(int i = 0; i < h / 2; i++) { +// A^2 = -(B^2) + C^2 + x_table[i] = (int)(sqrt(-SQR(h / 2 - i) + SQR(h / 2)) * w / h); +//printf("VFrame::draw_oval %d i=%d x=%d\n", __LINE__, i, x_table[i]); + } + + for(int i = 0; i < h / 2 - 1; i++) { + int x3 = x_table[i]; + int x4 = x_table[i + 1]; + + if(x4 > x3 + 1) { + for(int j = x3; j < x4; j++) { + draw_pixel(center_x + j, y1 + i); + draw_pixel(center_x - j, y1 + i); + draw_pixel(center_x + j, y2 - i - 1); + draw_pixel(center_x - j, y2 - i - 1); + } + } + else { + draw_pixel(center_x + x3, y1 + i); + draw_pixel(center_x - x3, y1 + i); + draw_pixel(center_x + x3, y2 - i - 1); + draw_pixel(center_x - x3, y2 - i - 1); + } + } + + draw_pixel(center_x, y1); + draw_pixel(center_x, y2 - 1); + draw_pixel(x1, center_y); + draw_pixel(x2 - 1, center_y); + draw_pixel(x1, center_y - 1); + draw_pixel(x2 - 1, center_y - 1); +} + + void VFrame::draw_arrow(int x1, int y1, int x2, int y2, int sz) { double angle = atan((float)(y2 - y1) / (float)(x2 - x1)); diff --git a/cinelerra-5.1/guicast/vframe.h b/cinelerra-5.1/guicast/vframe.h index 44695ba7..951e0364 100644 --- a/cinelerra-5.1/guicast/vframe.h +++ b/cinelerra-5.1/guicast/vframe.h @@ -354,6 +354,7 @@ public: void draw_arrow(int x1, int y1, int x2, int y2, int sz=10); void draw_x(int x1, int y1, int sz=2); void draw_t(int x1, int y1, int sz=2); + void draw_oval(int x1, int y1, int x2, int y2); // 3D scene graphs // Not integrated with shmem because that only affects codecs diff --git a/cinelerra-5.1/guicast/vicon.C b/cinelerra-5.1/guicast/vicon.C index 9f8d93cc..e9a71b15 100644 --- a/cinelerra-5.1/guicast/vicon.C +++ b/cinelerra-5.1/guicast/vicon.C @@ -2,7 +2,7 @@ #include "bctimer.h" #include "bcwindow.h" -#include "colors.h" +#include "bccolors.h" #include "keys.h" #include "mutex.h" #include "condition.h" diff --git a/cinelerra-5.1/plugin_defs b/cinelerra-5.1/plugin_defs index 9a663219..39a72d7d 100644 --- a/cinelerra-5.1/plugin_defs +++ b/cinelerra-5.1/plugin_defs @@ -23,7 +23,7 @@ colors := brightness bluebanana C41 color3way colorbalance huesaturation \ gamma gradient histogram histogram_bezier threshold plugin_dirs += exotic -exotic := aging burn dot holo oil edge +exotic := aging burn dot holo oil edge spherecam plugin_dirs += audio_tools audio_tools := audioscope cdripper compressor dcoffset delayaudio \ diff --git a/cinelerra-5.1/plugins/C41/c41.C b/cinelerra-5.1/plugins/C41/c41.C index 52ae7b0e..6006e07b 100644 --- a/cinelerra-5.1/plugins/C41/c41.C +++ b/cinelerra-5.1/plugins/C41/c41.C @@ -18,7 +18,7 @@ * */ #include "c41.h" -#include "cicolors.h" +#include "bccolors.h" #include "clip.h" #include "edlsession.h" #include "filexml.h" diff --git a/cinelerra-5.1/plugins/Makefile b/cinelerra-5.1/plugins/Makefile index 745f8808..bf9b8367 100644 --- a/cinelerra-5.1/plugins/Makefile +++ b/cinelerra-5.1/plugins/Makefile @@ -120,6 +120,7 @@ DIRS = $(OPENCV_OBJS) \ shiftinterlace \ slide \ spectrogram \ + spherecam \ svg \ swapchannels \ swapframes \ diff --git a/cinelerra-5.1/plugins/audioscope/audioscope.C b/cinelerra-5.1/plugins/audioscope/audioscope.C index 484b6cc9..129748d5 100644 --- a/cinelerra-5.1/plugins/audioscope/audioscope.C +++ b/cinelerra-5.1/plugins/audioscope/audioscope.C @@ -27,7 +27,7 @@ #include "bchash.h" #include "filexml.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "samples.h" #include "theme.h" #include "transportque.inc" diff --git a/cinelerra-5.1/plugins/audioscope/audioscope.h b/cinelerra-5.1/plugins/audioscope/audioscope.h index 366418f3..364d7038 100644 --- a/cinelerra-5.1/plugins/audioscope/audioscope.h +++ b/cinelerra-5.1/plugins/audioscope/audioscope.h @@ -29,7 +29,7 @@ #include "bchash.inc" #include "bctimer.inc" -#include "colors.h" +#include "bccolors.h" #include "guicast.h" #include "mutex.h" #include "pluginaclient.h" diff --git a/cinelerra-5.1/plugins/bluebanana/bluebanana.C b/cinelerra-5.1/plugins/bluebanana/bluebanana.C index 2f3399d5..5e7b4103 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebanana.C +++ b/cinelerra-5.1/plugins/bluebanana/bluebanana.C @@ -35,7 +35,7 @@ #include "language.h" #include "loadbalance.h" #include "playback3d.h" -#include "cicolors.h" +#include "bccolors.h" #include "vframe.h" #include "workarounds.h" diff --git a/cinelerra-5.1/plugins/bluebanana/bluebanana.h b/cinelerra-5.1/plugins/bluebanana/bluebanana.h index f96cba93..556b6232 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebanana.h +++ b/cinelerra-5.1/plugins/bluebanana/bluebanana.h @@ -29,7 +29,7 @@ class BluebananaThread; #include "bluebananaconfig.h" #include "bluebananawindow.h" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #define SELECT_LOOKUP_SIZE 1024 diff --git a/cinelerra-5.1/plugins/bluebanana/bluebananaslider.h b/cinelerra-5.1/plugins/bluebanana/bluebananaslider.h index 9e8f9fef..35a8c2b7 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebananaslider.h +++ b/cinelerra-5.1/plugins/bluebanana/bluebananaslider.h @@ -21,7 +21,7 @@ #ifndef BLUEBANANASLIDER_H #define BLUEBANANASLIDER_H -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "bluebanana.h" #include "bluebananawindow.h" diff --git a/cinelerra-5.1/plugins/bluebanana/bluebananawindow.h b/cinelerra-5.1/plugins/bluebanana/bluebananawindow.h index 6f951a76..b37c5a37 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebananawindow.h +++ b/cinelerra-5.1/plugins/bluebanana/bluebananawindow.h @@ -21,7 +21,7 @@ #ifndef BLUEBANANAWINDOW_H #define BLUEBANANAWINDOW_H -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "pluginserver.h" #include "mwindow.h" diff --git a/cinelerra-5.1/plugins/brightness/brightness.h b/cinelerra-5.1/plugins/brightness/brightness.h index a8e255ac..a4eb7de0 100644 --- a/cinelerra-5.1/plugins/brightness/brightness.h +++ b/cinelerra-5.1/plugins/brightness/brightness.h @@ -27,7 +27,7 @@ class BrightnessMain; #include "brightnesswindow.h" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" class BrightnessConfig diff --git a/cinelerra-5.1/plugins/burn/burn.C b/cinelerra-5.1/plugins/burn/burn.C index 6878423a..98261b20 100644 --- a/cinelerra-5.1/plugins/burn/burn.C +++ b/cinelerra-5.1/plugins/burn/burn.C @@ -24,7 +24,7 @@ #include "effecttv.h" #include "filexml.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "burn.h" #include "burnwindow.h" diff --git a/cinelerra-5.1/plugins/burn/burn.h b/cinelerra-5.1/plugins/burn/burn.h index 402b40dc..22fbfc88 100644 --- a/cinelerra-5.1/plugins/burn/burn.h +++ b/cinelerra-5.1/plugins/burn/burn.h @@ -28,7 +28,7 @@ class BurnMain; #include "effecttv.inc" #include "loadbalance.h" #include "mutex.h" -#include "cicolors.inc" +#include "bccolors.inc" #include "pluginvclient.h" #include "burnwindow.h" #include diff --git a/cinelerra-5.1/plugins/chromakey/chromakey.C b/cinelerra-5.1/plugins/chromakey/chromakey.C index 9d1926fc..90934f3e 100644 --- a/cinelerra-5.1/plugins/chromakey/chromakey.C +++ b/cinelerra-5.1/plugins/chromakey/chromakey.C @@ -30,7 +30,7 @@ #include "language.h" #include "loadbalance.h" #include "playback3d.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C index 39ff594e..5558606b 100644 --- a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C +++ b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C @@ -30,7 +30,7 @@ #include "language.h" #include "loadbalance.h" #include "playback3d.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/color3way/color3way.h b/cinelerra-5.1/plugins/color3way/color3way.h index f11f6f70..d771acc0 100644 --- a/cinelerra-5.1/plugins/color3way/color3way.h +++ b/cinelerra-5.1/plugins/color3way/color3way.h @@ -34,7 +34,7 @@ class Color3WayEngine; #include "color3waywindow.h" #include "condition.h" -#include "cicolors.h" +#include "bccolors.h" #include "guicast.h" #include "loadbalance.h" #include "pluginvclient.h" diff --git a/cinelerra-5.1/plugins/colorbalance/colorbalance.h b/cinelerra-5.1/plugins/colorbalance/colorbalance.h index c8a924ed..69b5923a 100644 --- a/cinelerra-5.1/plugins/colorbalance/colorbalance.h +++ b/cinelerra-5.1/plugins/colorbalance/colorbalance.h @@ -26,7 +26,7 @@ class ColorBalanceMain; #include "colorbalancewindow.h" #include "condition.h" -#include "cicolors.h" +#include "bccolors.h" #include "guicast.h" #include "pluginvclient.h" #include "thread.h" diff --git a/cinelerra-5.1/plugins/crikey/crikey.C b/cinelerra-5.1/plugins/crikey/crikey.C index 6b942d5d..b3e7592b 100644 --- a/cinelerra-5.1/plugins/crikey/crikey.C +++ b/cinelerra-5.1/plugins/crikey/crikey.C @@ -25,7 +25,7 @@ #include "arraylist.h" #include "bccmodels.h" -#include "cicolors.h" +#include "bccolors.h" #include "clip.h" #include "edlsession.h" #include "filexml.h" diff --git a/cinelerra-5.1/plugins/diffkey/diffkey.C b/cinelerra-5.1/plugins/diffkey/diffkey.C index 9ad9850b..118b7f38 100644 --- a/cinelerra-5.1/plugins/diffkey/diffkey.C +++ b/cinelerra-5.1/plugins/diffkey/diffkey.C @@ -29,7 +29,7 @@ #include "guicast.h" #include "language.h" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" diff --git a/cinelerra-5.1/plugins/echo/echo.C b/cinelerra-5.1/plugins/echo/echo.C index 58f8cf00..d8b426d0 100644 --- a/cinelerra-5.1/plugins/echo/echo.C +++ b/cinelerra-5.1/plugins/echo/echo.C @@ -25,7 +25,7 @@ #include "bchash.h" #include "filexml.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "samples.h" #include "echo.h" #include "theme.h" diff --git a/cinelerra-5.1/plugins/echocancel/echocancel.C b/cinelerra-5.1/plugins/echocancel/echocancel.C index 80787f40..b0cf73dd 100644 --- a/cinelerra-5.1/plugins/echocancel/echocancel.C +++ b/cinelerra-5.1/plugins/echocancel/echocancel.C @@ -25,7 +25,7 @@ #include "bchash.h" #include "filexml.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "samples.h" #include "echocancel.h" #include "theme.h" diff --git a/cinelerra-5.1/plugins/findobj/findobj.C b/cinelerra-5.1/plugins/findobj/findobj.C index 6348eb47..737167e5 100644 --- a/cinelerra-5.1/plugins/findobj/findobj.C +++ b/cinelerra-5.1/plugins/findobj/findobj.C @@ -19,7 +19,7 @@ */ #include "affine.h" -#include "cicolors.h" +#include "bccolors.h" #include "clip.h" #include "filexml.h" #include "language.h" diff --git a/cinelerra-5.1/plugins/gamma/gamma.C b/cinelerra-5.1/plugins/gamma/gamma.C index f0fd559d..28d04fc5 100644 --- a/cinelerra-5.1/plugins/gamma/gamma.C +++ b/cinelerra-5.1/plugins/gamma/gamma.C @@ -25,7 +25,7 @@ #include "gamma.h" #include "bchash.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "../interpolate/aggregated.h" #include "playback3d.h" #include "workarounds.h" diff --git a/cinelerra-5.1/plugins/gamma/gamma.h b/cinelerra-5.1/plugins/gamma/gamma.h index fe5881fc..21cef587 100644 --- a/cinelerra-5.1/plugins/gamma/gamma.h +++ b/cinelerra-5.1/plugins/gamma/gamma.h @@ -27,7 +27,7 @@ class GammaMain; #include "gammawindow.h" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "guicast.h" #include "pluginvclient.h" #include "thread.h" diff --git a/cinelerra-5.1/plugins/gradient/gradient.h b/cinelerra-5.1/plugins/gradient/gradient.h index 736e975a..4d68f945 100644 --- a/cinelerra-5.1/plugins/gradient/gradient.h +++ b/cinelerra-5.1/plugins/gradient/gradient.h @@ -37,7 +37,7 @@ class GradientServer; #include "guicast.h" #include "loadbalance.h" #include "overlayframe.inc" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "thread.h" #include "vframe.inc" diff --git a/cinelerra-5.1/plugins/histogram/histogram.C b/cinelerra-5.1/plugins/histogram/histogram.C index 4acc0c7b..fd2cdc86 100644 --- a/cinelerra-5.1/plugins/histogram/histogram.C +++ b/cinelerra-5.1/plugins/histogram/histogram.C @@ -36,7 +36,7 @@ #include "language.h" #include "loadbalance.h" #include "playback3d.h" -#include "cicolors.h" +#include "bccolors.h" #include "vframe.h" #include "workarounds.h" diff --git a/cinelerra-5.1/plugins/histogram/histogram.h b/cinelerra-5.1/plugins/histogram/histogram.h index 6d5d8e28..317c1beb 100644 --- a/cinelerra-5.1/plugins/histogram/histogram.h +++ b/cinelerra-5.1/plugins/histogram/histogram.h @@ -27,7 +27,7 @@ #include "histogramconfig.h" #include "histogramwindow.inc" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" diff --git a/cinelerra-5.1/plugins/histogram_bezier/bistogram.C b/cinelerra-5.1/plugins/histogram_bezier/bistogram.C index 53ebceeb..23688b18 100644 --- a/cinelerra-5.1/plugins/histogram_bezier/bistogram.C +++ b/cinelerra-5.1/plugins/histogram_bezier/bistogram.C @@ -35,7 +35,7 @@ #include "keyframe.h" #include "language.h" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/histogram_bezier/bistogram.h b/cinelerra-5.1/plugins/histogram_bezier/bistogram.h index 935e1282..97f31520 100644 --- a/cinelerra-5.1/plugins/histogram_bezier/bistogram.h +++ b/cinelerra-5.1/plugins/histogram_bezier/bistogram.h @@ -27,7 +27,7 @@ #include "bistogramconfig.h" #include "bistogramwindow.inc" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" diff --git a/cinelerra-5.1/plugins/holo/holo.C b/cinelerra-5.1/plugins/holo/holo.C index fb034b4d..61a8c0d2 100644 --- a/cinelerra-5.1/plugins/holo/holo.C +++ b/cinelerra-5.1/plugins/holo/holo.C @@ -26,7 +26,7 @@ #include "holo.h" #include "holowindow.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include #include diff --git a/cinelerra-5.1/plugins/holo/holo.h b/cinelerra-5.1/plugins/holo/holo.h index 668d2b5e..37dbb0b1 100644 --- a/cinelerra-5.1/plugins/holo/holo.h +++ b/cinelerra-5.1/plugins/holo/holo.h @@ -30,7 +30,7 @@ class HoloEngine; #include "holowindow.h" #include "loadbalance.h" #include "mutex.h" -#include "cicolors.inc" +#include "bccolors.inc" #include "pluginvclient.h" #include diff --git a/cinelerra-5.1/plugins/huesaturation/huesaturation.C b/cinelerra-5.1/plugins/huesaturation/huesaturation.C index 58dca39c..f7f04f24 100644 --- a/cinelerra-5.1/plugins/huesaturation/huesaturation.C +++ b/cinelerra-5.1/plugins/huesaturation/huesaturation.C @@ -26,7 +26,7 @@ #include "guicast.h" #include "language.h" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "playback3d.h" #include "pluginvclient.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/interpolate/interpolate.C b/cinelerra-5.1/plugins/interpolate/interpolate.C index 4c130eca..64fa589b 100644 --- a/cinelerra-5.1/plugins/interpolate/interpolate.C +++ b/cinelerra-5.1/plugins/interpolate/interpolate.C @@ -167,7 +167,7 @@ InterpolatePixelsMain::~InterpolatePixelsMain() delete engine; } -const char* InterpolatePixelsMain::plugin_title() { return _("Interpolate Pixels"); } +const char* InterpolatePixelsMain::plugin_title() { return _("Interpolate Bayer"); } int InterpolatePixelsMain::is_realtime() { return 1; } @@ -400,6 +400,13 @@ void InterpolatePixelsUnit::process_package(LoadPackage *package) float color_matrix[9]; memcpy(color_matrix, server->color_matrix, sizeof(color_matrix)); +// printf("InterpolatePixelsUnit::process_package %d color_matrix=", __LINE__); +// for(int i = 0; i < 9; i++) +// { +// printf("%f ", color_matrix[i]); +// } +// printf("\n"); + y1 = MAX(y1, 1); y2 = MIN(y2, h - 1); @@ -451,9 +458,14 @@ void InterpolatePixelsUnit::process_package(LoadPackage *package) b = current_row[BLUE]; } - out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2]; - out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5]; - out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8]; +// out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2]; +// out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5]; +// out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8]; + + out_row[0] = r; + out_row[1] = g; + out_row[2] = b; + prev_row += components; current_row += components; next_row += components; @@ -486,9 +498,14 @@ void InterpolatePixelsUnit::process_package(LoadPackage *package) b = (prev_row[BLUE] + next_row[BLUE]) / 2; } - out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2]; - out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5]; - out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8]; +// out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2]; +// out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5]; +// out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8]; + + out_row[0] = r; + out_row[1] = g; + out_row[2] = b; + prev_row += components; current_row += components; next_row += components; @@ -514,6 +531,10 @@ void InterpolatePixelsEngine::init_packages() char string[BCTEXTLEN]; string[0] = 0; plugin->get_output()->get_params()->get("DCRAW_MATRIX", string); + +// printf("InterpolatePixelsEngine::init_packages %d\n", __LINE__); +// plugin->get_output()->dump_params(); + sscanf(string, "%f %f %f %f %f %f %f %f %f", &color_matrix[0], diff --git a/cinelerra-5.1/plugins/interpolatevideo/Makefile b/cinelerra-5.1/plugins/interpolatevideo/Makefile index 3b50feb2..1993a6a0 100644 --- a/cinelerra-5.1/plugins/interpolatevideo/Makefile +++ b/cinelerra-5.1/plugins/interpolatevideo/Makefile @@ -3,10 +3,9 @@ include ../../plugin_defs OBJS = $(OBJDIR)/interpolatevideo.o \ $(OBJDIR)/interpolatewindow.o \ $(OBJDIR)/opticflow.o \ + $(OBJDIR)/motioncache-hv.o \ $(OBJDIR)/motionscan-hv.o -CFLAGS += -DMotionScan=MotionHVScan - PLUGIN = interpolatevideo include ../../plugin_config @@ -15,4 +14,5 @@ include ../../plugin_config $(OBJDIR)/interpolatevideo.o: interpolatevideo.C $(OBJDIR)/interpolatewindow.o: interpolatewindow.C $(OBJDIR)/opticflow.o: opticflow.C +$(OBJDIR)/motionscan-hv.o: motioncache-hv.C motioncache-hv.h $(OBJDIR)/motionscan-hv.o: motionscan-hv.C motionscan-hv.h diff --git a/cinelerra-5.1/plugins/interpolatevideo/interpolatevideo.C b/cinelerra-5.1/plugins/interpolatevideo/interpolatevideo.C index 9e553ac3..6eab87b3 100644 --- a/cinelerra-5.1/plugins/interpolatevideo/interpolatevideo.C +++ b/cinelerra-5.1/plugins/interpolatevideo/interpolatevideo.C @@ -326,6 +326,11 @@ void InterpolateVideo::create_macroblocks() // Get macroblock size x_macroblocks = frames[0]->get_w() / config.macroblock_size; y_macroblocks = frames[0]->get_h() / config.macroblock_size; +// printf("InterpolateVideo::create_macroblocks %d %d %d %d\n", +// __LINE__, +// config.macroblock_size, +// x_macroblocks, +// y_macroblocks); if(config.macroblock_size * x_macroblocks < frames[0]->get_w()) { diff --git a/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.C b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.C new file mode 120000 index 00000000..5e5d9aa1 --- /dev/null +++ b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.C @@ -0,0 +1 @@ +../motion-hv/motioncache-hv.C \ No newline at end of file diff --git a/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.h b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.h new file mode 120000 index 00000000..d6ebb120 --- /dev/null +++ b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.h @@ -0,0 +1 @@ +../motion-hv/motioncache-hv.h \ No newline at end of file diff --git a/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.inc b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.inc new file mode 120000 index 00000000..d59d1391 --- /dev/null +++ b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.inc @@ -0,0 +1 @@ +../motion-hv/motioncache-hv.inc \ No newline at end of file diff --git a/cinelerra-5.1/plugins/interpolatevideo/opticflow.C b/cinelerra-5.1/plugins/interpolatevideo/opticflow.C index bf8a6762..83414c07 100644 --- a/cinelerra-5.1/plugins/interpolatevideo/opticflow.C +++ b/cinelerra-5.1/plugins/interpolatevideo/opticflow.C @@ -24,6 +24,7 @@ #include "clip.h" #include "interpolatevideo.h" +#include "motioncache-hv.h" #include "motionscan-hv.h" #include "opticflow.h" @@ -92,9 +93,11 @@ void OpticFlowUnit::process_package(LoadPackage *package) struct timeval start_time; gettimeofday(&start_time, 0); - if(!motion) motion = new MotionScan(1, 1); + if(!motion) motion = new MotionHVScan(1, 1); motion->set_test_match(0); + motion->set_cache(server->downsample_cache); + // printf("OpticFlowUnit::process_package %d %d %d\n", // __LINE__, // pkg->macroblock0, @@ -103,6 +106,7 @@ void OpticFlowUnit::process_package(LoadPackage *package) for(int i = pkg->macroblock0; i < pkg->macroblock1; i++) { OpticFlowMacroblock *mb = plugin->macroblocks.get(i); +//printf("OpticFlowUnit::process_package %d i=%d x=%d y=%d\n", __LINE__, i, mb->x, mb->y); motion->scan_frame(plugin->frames[0], // Frame after motion plugin->frames[1], @@ -112,10 +116,10 @@ void OpticFlowUnit::process_package(LoadPackage *package) plugin->config.macroblock_size, mb->x, mb->y, - MotionScan::TRACK_PREVIOUS, - MotionScan::CALCULATE, + MotionHVScan::TRACK_PREVIOUS, + MotionHVScan::CALCULATE, // Get it to do the subpixel step - MotionScan::STABILIZE, + MotionHVScan::STABILIZE, 0, 0, 0, @@ -127,6 +131,7 @@ void OpticFlowUnit::process_package(LoadPackage *package) 0, 0, 0); +//printf("OpticFlowUnit::process_package 2\n", __LINE__); mb->dx = motion->dx_result; @@ -157,21 +162,39 @@ OpticFlow::OpticFlow(InterpolateVideo *plugin, total_packages) { this->plugin = plugin; + downsample_cache = 0; } OpticFlow::~OpticFlow() { + if(downsample_cache) + { +//printf("OpticFlow::~OpticFlow %d %p\n", __LINE__, downsample_cache); + delete downsample_cache; + } } void OpticFlow::init_packages() { -//printf("OpticFlow::init_packages %d %d\n", __LINE__, get_total_packages()); + if(!downsample_cache) + { + downsample_cache = new MotionHVCache(); + } + + downsample_cache->clear(); + for(int i = 0; i < get_total_packages(); i++) { OpticFlowPackage *pkg = (OpticFlowPackage*)get_package(i); pkg->macroblock0 = plugin->total_macroblocks * i / get_total_packages(); pkg->macroblock1 = plugin->total_macroblocks * (i + 1) / get_total_packages(); +// printf("OpticFlow::init_packages %d %d %d %d %d\n", +// __LINE__, +// plugin->total_macroblocks, +// get_total_packages(), +// pkg->macroblock0, +// pkg->macroblock1); } } diff --git a/cinelerra-5.1/plugins/interpolatevideo/opticflow.h b/cinelerra-5.1/plugins/interpolatevideo/opticflow.h index 6e611fc5..5a0dbefb 100644 --- a/cinelerra-5.1/plugins/interpolatevideo/opticflow.h +++ b/cinelerra-5.1/plugins/interpolatevideo/opticflow.h @@ -24,6 +24,7 @@ #include "interpolatevideo.inc" #include "loadbalance.h" +#include "motioncache-hv.inc" #include "motionscan-hv.inc" #include "opticflow.inc" @@ -57,7 +58,7 @@ public: OpticFlowUnit(OpticFlow *server); ~OpticFlowUnit(); void process_package(LoadPackage *package); - MotionScan *motion; + MotionHVScan *motion; OpticFlow *server; }; @@ -73,6 +74,7 @@ public: LoadClient* new_client(); LoadPackage* new_package(); InterpolateVideo *plugin; + MotionHVCache *downsample_cache; }; diff --git a/cinelerra-5.1/plugins/invertvideo/invert.C b/cinelerra-5.1/plugins/invertvideo/invert.C index 309776b3..078f48f8 100644 --- a/cinelerra-5.1/plugins/invertvideo/invert.C +++ b/cinelerra-5.1/plugins/invertvideo/invert.C @@ -25,7 +25,7 @@ #include "filexml.h" #include "guicast.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/libeffecttv/effecttv.C b/cinelerra-5.1/plugins/libeffecttv/effecttv.C index 5da0a4b1..60f2c8a9 100644 --- a/cinelerra-5.1/plugins/libeffecttv/effecttv.C +++ b/cinelerra-5.1/plugins/libeffecttv/effecttv.C @@ -21,7 +21,7 @@ #include "bccmodels.h" #include "effecttv.h" -#include "cicolors.h" +#include "bccolors.h" #include "vframe.h" #include diff --git a/cinelerra-5.1/plugins/libeffecttv/effecttv.h b/cinelerra-5.1/plugins/libeffecttv/effecttv.h index af8368f3..473a4240 100644 --- a/cinelerra-5.1/plugins/libeffecttv/effecttv.h +++ b/cinelerra-5.1/plugins/libeffecttv/effecttv.h @@ -22,7 +22,7 @@ #ifndef EFFECTTV_H #define EFFECTTV_H -#include "cicolors.h" +#include "bccolors.h" #include "vframe.inc" #include diff --git a/cinelerra-5.1/plugins/motion-hv/Makefile b/cinelerra-5.1/plugins/motion-hv/Makefile index 695fd5ee..b8c2ffbc 100644 --- a/cinelerra-5.1/plugins/motion-hv/Makefile +++ b/cinelerra-5.1/plugins/motion-hv/Makefile @@ -2,6 +2,7 @@ include ../../plugin_defs OBJS := \ $(OBJDIR)/motion-hv.o \ + $(OBJDIR)/motioncache-hv.o \ $(OBJDIR)/motionscan-hv.o \ $(OBJDIR)/motionwindow-hv.o @@ -10,5 +11,6 @@ PLUGIN = motion-hv include ../../plugin_config $(OBJDIR)/motion-hv.o: motion-hv.C +$(OBJDIR)/motioncache-hv.o: motioncache-hv.C $(OBJDIR)/motionscan-hv.o: motionscan-hv.C $(OBJDIR)/motionwindow-hv.o: motionwindow-hv.C diff --git a/cinelerra-5.1/plugins/motion-hv/motion-hv.C b/cinelerra-5.1/plugins/motion-hv/motion-hv.C index ea339d92..b61c654a 100644 --- a/cinelerra-5.1/plugins/motion-hv/motion-hv.C +++ b/cinelerra-5.1/plugins/motion-hv/motion-hv.C @@ -120,7 +120,8 @@ int MotionHVConfig::equivalent(MotionHVConfig &that) track_frame == that.track_frame && bottom_is_master == that.bottom_is_master && horizontal_only == that.horizontal_only && - vertical_only == that.vertical_only; + vertical_only == that.vertical_only && + tracking_type == that.tracking_type; } void MotionHVConfig::copy_from(MotionHVConfig &that) diff --git a/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C new file mode 100644 index 00000000..98722ded --- /dev/null +++ b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C @@ -0,0 +1,233 @@ +/* + * CINELERRA + * Copyright (C) 2016 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + + +// store previously scaled images here for operations +// with multiple motion scans on the same frame. + + +#include "bcsignals.h" +#include "clip.h" +#include "motioncache-hv.h" +#include "mutex.h" +#include +#include "vframe.h" + + +MotionHVCacheItem::MotionHVCacheItem() +{ +} + +MotionHVCacheItem::~MotionHVCacheItem() +{ +//printf("MotionHVCacheItem::~MotionHVCacheItem %d image=%p\n", __LINE__, image); + if(image) + { + delete image; + } +} + + + +MotionHVCache::MotionHVCache() +{ + lock = new Mutex("MotionHVCache::lock"); +} + +MotionHVCache::~MotionHVCache() +{ +//printf("MotionHVCache::~MotionHVCache %d this=%p\n", __LINE__, this); + + delete lock; + clear(); +} + +void MotionHVCache::clear() +{ + images.remove_all_objects(); +} + + + +#define DOWNSAMPLE(type, temp_type, components, max) \ +{ \ + temp_type r; \ + temp_type g; \ + temp_type b; \ + temp_type a; \ + type **in_rows = (type**)src->get_rows(); \ + type **out_rows = (type**)dst->get_rows(); \ + \ + for(int i = 0; i < h; i += downsample) \ + { \ + int y1 = MAX(i, 0); \ + int y2 = MIN(i + downsample, h); \ + \ + \ + for(int j = 0; \ + j < w; \ + j += downsample) \ + { \ + int x1 = MAX(j, 0); \ + int x2 = MIN(j + downsample, w); \ + \ + temp_type scale = (x2 - x1) * (y2 - y1); \ + if(x2 > x1 && y2 > y1) \ + { \ + \ +/* Read in values */ \ + r = 0; \ + g = 0; \ + b = 0; \ + if(components == 4) a = 0; \ + \ + for(int k = y1; k < y2; k++) \ + { \ + type *row = in_rows[k] + x1 * components; \ + for(int l = x1; l < x2; l++) \ + { \ + r += *row++; \ + g += *row++; \ + b += *row++; \ + if(components == 4) a += *row++; \ + } \ + } \ + \ +/* Write average */ \ + r /= scale; \ + g /= scale; \ + b /= scale; \ + if(components == 4) a /= scale; \ + \ + type *row = out_rows[y1 / downsample] + \ + x1 / downsample * components; \ + *row++ = r; \ + *row++ = g; \ + *row++ = b; \ + if(components == 4) *row++ = a; \ + } \ + } \ +/*printf("DOWNSAMPLE 3 %d\n", i);*/ \ + } \ +} + + + + +void MotionHVCache::downsample_frame(VFrame *dst, + VFrame *src, + int downsample) +{ + int h = src->get_h(); + int w = src->get_w(); + +//PRINT_TRACE +//printf("downsample=%d w=%d h=%d dst=%d %d\n", downsample, w, h, dst->get_w(), dst->get_h()); + switch(src->get_color_model()) + { + case BC_RGB888: + DOWNSAMPLE(uint8_t, int64_t, 3, 0xff) + break; + case BC_RGB_FLOAT: + DOWNSAMPLE(float, float, 3, 1.0) + break; + case BC_RGBA8888: + DOWNSAMPLE(uint8_t, int64_t, 4, 0xff) + break; + case BC_RGBA_FLOAT: + DOWNSAMPLE(float, float, 4, 1.0) + break; + case BC_YUV888: + DOWNSAMPLE(uint8_t, int64_t, 3, 0xff) + break; + case BC_YUVA8888: + DOWNSAMPLE(uint8_t, int64_t, 4, 0xff) + break; + } +//PRINT_TRACE +} + +VFrame* MotionHVCache::get_image(int ratio, + int is_previous, + int downsampled_w, + int downsampled_h, + VFrame *src) +{ + lock->lock("MotionHVCache::get_image 1"); + + for(int i = 0; i < images.size(); i++) + { + if(images.get(i)->ratio == ratio && + images.get(i)->is_previous == is_previous) + { + VFrame *result = images.get(i)->image; + lock->unlock(); + return result; + } + } + + +//PRINT_TRACE + VFrame *result = new VFrame(); + result->set_use_shm(0); + result->reallocate(0, + -1, + 0, + 0, + 0, + downsampled_w + 1, + downsampled_h + 1, + src->get_color_model(), + -1); + downsample_frame(result, + src, + ratio); + + + MotionHVCacheItem *item = new MotionHVCacheItem(); + item->image = result; + item->is_previous = is_previous; + item->ratio = ratio; + images.append(item); + + lock->unlock(); + + return result; +} + + + + + + + + + + + + + + + + + + + diff --git a/cinelerra-5.1/plugins/motion-hv/motioncache-hv.h b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.h new file mode 100644 index 00000000..f8813ce6 --- /dev/null +++ b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.h @@ -0,0 +1,72 @@ +/* + * CINELERRA + * Copyright (C) 2016 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef MOTIONCACHE_HV_H +#define MOTIONCACHE_HV_H + +// store previously scaled intermediates here for operations +// with multiple motion scans on the same frame. + +#include "arraylist.h" +#include "mutex.inc" +#include "vframe.inc" + +class MotionHVCacheItem +{ +public: + MotionHVCacheItem(); + ~MotionHVCacheItem(); + + VFrame *image; + int ratio; + int is_previous; +}; + + +class MotionHVCache +{ +public: + MotionHVCache(); + ~MotionHVCache(); + + VFrame *get_image(int ratio, + int is_previous, + int downsampled_w, + int downsampled_h, + VFrame *src); + + void clear(); + + void downsample_frame(VFrame *dst, + VFrame *src, + int downsample); + + ArrayList images; + Mutex *lock; +}; + + + + + +#endif + + diff --git a/cinelerra-5.1/plugins/motion-hv/motioncache-hv.inc b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.inc new file mode 100644 index 00000000..4ff46364 --- /dev/null +++ b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.inc @@ -0,0 +1,8 @@ +#ifndef MOTIONCACHE_HV_INC +#define MOTIONCACHE_HV_INC + +class MotionHVCache; + +#endif + + diff --git a/cinelerra-5.1/plugins/motion-hv/motionscan-hv.C b/cinelerra-5.1/plugins/motion-hv/motionscan-hv.C index db8617ea..6c4d6e07 100644 --- a/cinelerra-5.1/plugins/motion-hv/motionscan-hv.C +++ b/cinelerra-5.1/plugins/motion-hv/motionscan-hv.C @@ -22,6 +22,7 @@ #include "affine.h" #include "bcsignals.h" #include "clip.h" +#include "motioncache-hv.h" #include "motionscan-hv.h" #include "mutex.h" #include "vframe.h" @@ -208,23 +209,24 @@ total_clients, total_packages ) { test_match = 1; - downsampled_previous = 0; - downsampled_current = 0; rotated_current = 0; rotater = 0; + downsample_cache = 0; + shared_downsample = 0; } MotionHVScan::~MotionHVScan() { - delete downsampled_previous; - delete downsampled_current; - if(rotated_current) - { - for(int i = 0; i < total_rotated; i++) - { + if(downsample_cache && !shared_downsample) { + delete downsample_cache; + downsample_cache = 0; + shared_downsample = 0; + } + + if(rotated_current) { + for(int i = 0; i < total_rotated; i++) { delete rotated_current[i]; } - delete [] rotated_current; } delete rotater; @@ -366,107 +368,13 @@ void MotionHVScan::set_test_match(int value) this->test_match = value; } - - - -#define DOWNSAMPLE(type, temp_type, components, max) \ -{ \ - temp_type r; \ - temp_type g; \ - temp_type b; \ - temp_type a; \ - type **in_rows = (type**)src->get_rows(); \ - type **out_rows = (type**)dst->get_rows(); \ - \ - for(int i = 0; i < h; i += downsample) \ - { \ - int y1 = MAX(i, 0); \ - int y2 = MIN(i + downsample, h); \ - \ - \ - for(int j = 0; \ - j < w; \ - j += downsample) \ - { \ - int x1 = MAX(j, 0); \ - int x2 = MIN(j + downsample, w); \ - \ - temp_type scale = (x2 - x1) * (y2 - y1); \ - if(x2 > x1 && y2 > y1) \ - { \ - \ -/* Read in values */ \ - r = 0; \ - g = 0; \ - b = 0; \ - if(components == 4) a = 0; \ - \ - for(int k = y1; k < y2; k++) \ - { \ - type *row = in_rows[k] + x1 * components; \ - for(int l = x1; l < x2; l++) \ - { \ - r += *row++; \ - g += *row++; \ - b += *row++; \ - if(components == 4) a += *row++; \ - } \ - } \ - \ -/* Write average */ \ - r /= scale; \ - g /= scale; \ - b /= scale; \ - if(components == 4) a /= scale; \ - \ - type *row = out_rows[y1 / downsample] + \ - x1 / downsample * components; \ - *row++ = r; \ - *row++ = g; \ - *row++ = b; \ - if(components == 4) *row++ = a; \ - } \ - } \ -/*printf("DOWNSAMPLE 3 %d\n", i);*/ \ - } \ -} - - - - -void MotionHVScan::downsample_frame(VFrame *dst, - VFrame *src, - int downsample) +void MotionHVScan::set_cache(MotionHVCache *cache) { - int h = src->get_h(); - int w = src->get_w(); - -//PRINT_TRACE -//printf("downsample=%d w=%d h=%d dst=%d %d\n", downsample, w, h, dst->get_w(), dst->get_h()); - switch(src->get_color_model()) - { - case BC_RGB888: - DOWNSAMPLE(uint8_t, int64_t, 3, 0xff) - break; - case BC_RGB_FLOAT: - DOWNSAMPLE(float, float, 3, 1.0) - break; - case BC_RGBA8888: - DOWNSAMPLE(uint8_t, int64_t, 4, 0xff) - break; - case BC_RGBA_FLOAT: - DOWNSAMPLE(float, float, 4, 1.0) - break; - case BC_YUV888: - DOWNSAMPLE(uint8_t, int64_t, 3, 0xff) - break; - case BC_YUVA8888: - DOWNSAMPLE(uint8_t, int64_t, 4, 0xff) - break; - } -//PRINT_TRACE + this->downsample_cache = cache; + shared_downsample = 1; } + double MotionHVScan::step_to_angle(int step, double center) { if(step < angle_steps / 2) @@ -557,51 +465,29 @@ void MotionHVScan::pixel_search(int &x_result, int &y_result, double &r_result) if(current_downsample > 1) { - if(!downsampled_previous || - downsampled_previous->get_w() != downsampled_prev_w || - downsampled_previous->get_h() != downsampled_prev_h) + if(!downsample_cache) { - delete downsampled_previous; - downsampled_previous = new VFrame(); - downsampled_previous->set_use_shm(0); - downsampled_previous->reallocate(0, - -1, - 0, - 0, - 0, - downsampled_prev_w + 1, - downsampled_prev_h + 1, - previous_frame_arg->get_color_model(), - -1); + downsample_cache = new MotionHVCache(); + shared_downsample = 0; } - if(!downsampled_current || - downsampled_current->get_w() != downsampled_current_w || - downsampled_current->get_h() != downsampled_current_h) + + if(!shared_downsample) { - delete downsampled_current; - downsampled_current = new VFrame(); - downsampled_current->set_use_shm(0); - downsampled_current->reallocate(0, - -1, - 0, - 0, - 0, - downsampled_current_w + 1, - downsampled_current_h + 1, - current_frame_arg->get_color_model(), - -1); + downsample_cache->clear(); } + previous_frame = downsample_cache->get_image(current_downsample, + 1, + downsampled_prev_w, + downsampled_prev_h, + previous_frame_arg); + current_frame = downsample_cache->get_image(current_downsample, + 0, + downsampled_current_w, + downsampled_current_h, + current_frame_arg); - downsample_frame(downsampled_previous, - previous_frame_arg, - current_downsample); - downsample_frame(downsampled_current, - current_frame_arg, - current_downsample); - previous_frame = downsampled_previous; - current_frame = downsampled_current; } else diff --git a/cinelerra-5.1/plugins/motion-hv/motionscan-hv.h b/cinelerra-5.1/plugins/motion-hv/motionscan-hv.h index 7511e642..b9241c59 100644 --- a/cinelerra-5.1/plugins/motion-hv/motionscan-hv.h +++ b/cinelerra-5.1/plugins/motion-hv/motionscan-hv.h @@ -25,6 +25,7 @@ #include "affine.inc" #include "loadbalance.h" +#include "motioncache-hv.inc" #include "vframe.inc" #include @@ -89,6 +90,7 @@ public: LoadPackage* new_package(); // Test for identical frames before scanning void set_test_match(int value); + void set_cache(MotionHVCache *cache); // Invoke the motion engine for a search // Frame before motion @@ -196,7 +198,8 @@ private: int color_model); - + MotionHVCache *downsample_cache; + int shared_downsample; AffineEngine *rotater; // Pointer to downsampled frame before motion VFrame *previous_frame; @@ -205,9 +208,6 @@ private: // Frames passed from user VFrame *previous_frame_arg; VFrame *current_frame_arg; -// Downsampled frames - VFrame *downsampled_previous; - VFrame *downsampled_current; // rotated versions of current_frame VFrame **rotated_current; // allocation of rotated_current array, a copy of angle_steps diff --git a/cinelerra-5.1/plugins/motion2point/Makefile b/cinelerra-5.1/plugins/motion2point/Makefile index 5a00398c..038095d1 100644 --- a/cinelerra-5.1/plugins/motion2point/Makefile +++ b/cinelerra-5.1/plugins/motion2point/Makefile @@ -2,6 +2,7 @@ include ../../plugin_defs OBJS := \ $(OBJDIR)/downsampleengine.o \ + $(OBJDIR)/motioncache-hv.o \ $(OBJDIR)/motionscan-hv.o \ $(OBJDIR)/motion.o \ $(OBJDIR)/motionwindow.o @@ -14,5 +15,6 @@ include ../../plugin_config $(OBJDIR)/downsampleengine.o: downsampleengine.C $(OBJDIR)/motion.o: motion.C +$(OBJDIR)/motionscan-hv.o: motioncache-hv.C $(OBJDIR)/motionscan-hv.o: motionscan-hv.C $(OBJDIR)/motionwindow.o: motionwindow.C diff --git a/cinelerra-5.1/plugins/motion2point/motioncache-hv.C b/cinelerra-5.1/plugins/motion2point/motioncache-hv.C new file mode 120000 index 00000000..5e5d9aa1 --- /dev/null +++ b/cinelerra-5.1/plugins/motion2point/motioncache-hv.C @@ -0,0 +1 @@ +../motion-hv/motioncache-hv.C \ No newline at end of file diff --git a/cinelerra-5.1/plugins/motion2point/motioncache-hv.h b/cinelerra-5.1/plugins/motion2point/motioncache-hv.h new file mode 120000 index 00000000..d6ebb120 --- /dev/null +++ b/cinelerra-5.1/plugins/motion2point/motioncache-hv.h @@ -0,0 +1 @@ +../motion-hv/motioncache-hv.h \ No newline at end of file diff --git a/cinelerra-5.1/plugins/motion2point/motioncache-hv.inc b/cinelerra-5.1/plugins/motion2point/motioncache-hv.inc new file mode 120000 index 00000000..d59d1391 --- /dev/null +++ b/cinelerra-5.1/plugins/motion2point/motioncache-hv.inc @@ -0,0 +1 @@ +../motion-hv/motioncache-hv.inc \ No newline at end of file diff --git a/cinelerra-5.1/plugins/reverb/reverb.C b/cinelerra-5.1/plugins/reverb/reverb.C index 92417a6c..eb60c71d 100644 --- a/cinelerra-5.1/plugins/reverb/reverb.C +++ b/cinelerra-5.1/plugins/reverb/reverb.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams + * Copyright (C) 2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -350,87 +350,91 @@ void Reverb::update_gui() { if(thread) { - thread->window->lock_window(); - ((ReverbWindow*)thread->window)->level_init->update(config.level_init); - ((ReverbWindow*)thread->window)->delay_init->update(config.delay_init); - ((ReverbWindow*)thread->window)->ref_level1->update(config.ref_level1); - ((ReverbWindow*)thread->window)->ref_level2->update(config.ref_level2); - ((ReverbWindow*)thread->window)->ref_total->update(config.ref_total); - ((ReverbWindow*)thread->window)->ref_length->update(config.ref_length); - ((ReverbWindow*)thread->window)->lowpass1->update(config.lowpass1); - ((ReverbWindow*)thread->window)->lowpass2->update(config.lowpass2); - thread->window->unlock_window(); - } -} - - - - -int Reverb::load_from_file(char *path) -{ - int result = 0; - int length; - char string[1024]; - - FILE *in = fopen(path, "rb"); - if( in ) - { - fseek(in, 0, SEEK_END); - length = ftell(in); - fseek(in, 0, SEEK_SET); - (void)fread(string, length, 1, in); - fclose(in); -// read_data(string); - } - else - { - perror("fopen:"); -// failed - ErrorBox errorbox(""); - char string[1024]; - sprintf(string, _("Couldn't open %s."), path); - errorbox.create_objects(string); - errorbox.run_window(); - result = 1; + if(load_configuration()) + { +//printf("Reverb::update_gui %d %d\n", __LINE__, config.ref_length); + thread->window->lock_window("Reverb::update_gui"); + ((ReverbWindow*)thread->window)->level_init->update(config.level_init); + ((ReverbWindow*)thread->window)->delay_init->update(config.delay_init); + ((ReverbWindow*)thread->window)->ref_level1->update(config.ref_level1); + ((ReverbWindow*)thread->window)->ref_level2->update(config.ref_level2); + ((ReverbWindow*)thread->window)->ref_total->update(config.ref_total); + ((ReverbWindow*)thread->window)->ref_length->update(config.ref_length); + ((ReverbWindow*)thread->window)->lowpass1->update(config.lowpass1); + ((ReverbWindow*)thread->window)->lowpass2->update(config.lowpass2); + thread->window->unlock_window(); + } } - - return result; } -int Reverb::save_to_file(char *path) -{ - int result = 0; - char string[1024]; - { -// ConfirmSave confirm; -// result = confirm.test_file("", path); - } - if(!result) - { - FILE *out = fopen(path, "wb"); - if( out ) - { -// save_data(string); - fwrite(string, strlen(string), 1, out); - fclose(out); - } - else - { - result = 1; -// failed - ErrorBox errorbox(""); - char string[1024]; - sprintf(string, _("Couldn't save %s."), path); - errorbox.create_objects(string); - errorbox.run_window(); - result = 1; - } - } - return result; -} +// int Reverb::load_from_file(char *path) +// { +// FILE *in; +// int result = 0; +// int length; +// char string[1024]; +// +// if(in = fopen(path, "rb")) +// { +// fseek(in, 0, SEEK_END); +// length = ftell(in); +// fseek(in, 0, SEEK_SET); +// int temp = fread(string, length, 1, in); +// fclose(in); +// // read_data(string); +// } +// else +// { +// perror("fopen:"); +// // failed +// ErrorBox errorbox(""); +// char string[1024]; +// sprintf(string, _("Couldn't open %s."), path); +// errorbox.create_objects(string); +// errorbox.run_window(); +// result = 1; +// } +// +// return result; +// } +// +// int Reverb::save_to_file(char *path) +// { +// FILE *out; +// int result = 0; +// char string[1024]; +// +// { +// // ConfirmSave confirm; +// // result = confirm.test_file("", path); +// } +// +// if(!result) +// { +// if(out = fopen(path, "wb")) +// { +// // save_data(string); +// fwrite(string, strlen(string), 1, out); +// fclose(out); +// } +// else +// { +// result = 1; +// // failed +// ErrorBox errorbox(""); +// char string[1024]; +// sprintf(string, _("Couldn't save %s."), path); +// errorbox.create_objects(string); +// errorbox.run_window(); +// result = 1; +// } +// } +// +// return result; +// } ReverbEngine::ReverbEngine(Reverb *plugin) : Thread(1, 0, 0) diff --git a/cinelerra-5.1/plugins/reverb/reverb.h b/cinelerra-5.1/plugins/reverb/reverb.h index ca04f739..629c74ce 100644 --- a/cinelerra-5.1/plugins/reverb/reverb.h +++ b/cinelerra-5.1/plugins/reverb/reverb.h @@ -65,8 +65,8 @@ public: ~Reverb(); void update_gui(); - int load_from_file(char *data); - int save_to_file(char *data); +// int load_from_file(char *data); +// int save_to_file(char *data); // data for reverb char config_directory[1024]; diff --git a/cinelerra-5.1/plugins/reverb/reverbwindow.C b/cinelerra-5.1/plugins/reverb/reverbwindow.C index 4da0fafc..add6ab45 100644 --- a/cinelerra-5.1/plugins/reverb/reverbwindow.C +++ b/cinelerra-5.1/plugins/reverb/reverbwindow.C @@ -33,9 +33,9 @@ ReverbWindow::ReverbWindow(Reverb *reverb) : PluginClientWindow(reverb, - 250, - 230, - 250, + 300, + 230, + 300, 230, 0) { @@ -48,7 +48,7 @@ ReverbWindow::~ReverbWindow() void ReverbWindow::create_objects() { - int x = 170, y = 10; + int x = 200, y = 10; add_tool(new BC_Title(5, y + 10, _("Initial signal level:"))); add_tool(level_init = new ReverbLevelInit(reverb, x, y)); y += 25; add_tool(new BC_Title(5, y + 10, _("ms before reflections:"))); @@ -215,319 +215,317 @@ int ReverbLowPass2::handle_event() return 1; } -ReverbMenu::ReverbMenu(Reverb *reverb, ReverbWindow *window) - : BC_MenuBar(0, 0, window->get_w()) -{ - this->window = window; - this->reverb = reverb; -} - -ReverbMenu::~ReverbMenu() -{ - delete load; - delete save; - //delete set_default; - for(int i = 0; i < total_loads; i++) - { - delete prev_load[i]; - } - delete prev_load_thread; -} - -void ReverbMenu::create_objects(BC_Hash *defaults) -{ - add_menu(filemenu = new BC_Menu(_("File"))); - filemenu->add_item(load = new ReverbLoad(reverb, this)); - filemenu->add_item(save = new ReverbSave(reverb, this)); - //filemenu->add_item(set_default = new ReverbSetDefault); - load_defaults(defaults); - prev_load_thread = new ReverbLoadPrevThread(reverb, this); -} - -int ReverbMenu::load_defaults(BC_Hash *defaults) -{ - FileSystem fs; - total_loads = defaults->get("TOTAL_LOADS", 0); - if(total_loads > 0) - { - filemenu->add_item(new BC_MenuItem("-")); - char string[1024], path[1024], filename[1024]; - - for(int i = 0; i < total_loads; i++) - { - sprintf(string, "LOADPREVIOUS%d", i); - defaults->get(string, path); - fs.extract_name(filename, path); -//printf("ReverbMenu::load_defaults %s\n", path); - filemenu->add_item(prev_load[i] = new ReverbLoadPrev(reverb, this, filename, path)); - } - } - return 0; -} - -int ReverbMenu::save_defaults(BC_Hash *defaults) -{ - if(total_loads > 0) - { - defaults->update("TOTAL_LOADS", total_loads); - char string[1024]; - - for(int i = 0; i < total_loads; i++) - { - sprintf(string, "LOADPREVIOUS%d", i); - defaults->update(string, prev_load[i]->path); - } - } - return 0; -} - -int ReverbMenu::add_load(char *path) -{ - if(total_loads == 0) - { - filemenu->add_item(new BC_MenuItem("-")); - } - -// test for existing copy - FileSystem fs; - char text[1024], new_path[1024]; // get text and path - fs.extract_name(text, path); - strcpy(new_path, path); - - for(int i = 0; i < total_loads; i++) - { - if(!strcmp(prev_load[i]->get_text(), text)) // already exists - { // swap for top load - for(int j = i; j > 0; j--) // move preceeding loads down - { - prev_load[j]->set_text(prev_load[j - 1]->get_text()); - prev_load[j]->set_path(prev_load[j - 1]->path); - } - prev_load[0]->set_text(text); - prev_load[0]->set_path(new_path); - return 1; - } - } - -// add another load - if(total_loads < TOTAL_LOADS) - { - filemenu->add_item(prev_load[total_loads] = new ReverbLoadPrev(reverb, this)); - total_loads++; - } - -// cycle loads down - for(int i = total_loads - 1; i > 0; i--) - { - // set menu item text - prev_load[i]->set_text(prev_load[i - 1]->get_text()); - // set filename - prev_load[i]->set_path(prev_load[i - 1]->path); - } - -// set up the new load - prev_load[0]->set_text(text); - prev_load[0]->set_path(new_path); - return 0; -} - -ReverbLoad::ReverbLoad(Reverb *reverb, ReverbMenu *menu) - : BC_MenuItem(_("Load...")) -{ - this->reverb = reverb; - this->menu = menu; - thread = new ReverbLoadThread(reverb, menu); -} -ReverbLoad::~ReverbLoad() -{ - delete thread; -} -int ReverbLoad::handle_event() -{ - thread->start(); - return 0; -} - -ReverbSave::ReverbSave(Reverb *reverb, ReverbMenu *menu) - : BC_MenuItem(_("Save...")) -{ - this->reverb = reverb; - this->menu = menu; - thread = new ReverbSaveThread(reverb, menu); -} -ReverbSave::~ReverbSave() -{ - delete thread; -} -int ReverbSave::handle_event() -{ - thread->start(); - return 0; -} - -ReverbSetDefault::ReverbSetDefault() - : BC_MenuItem(_("Set default")) -{ -} -int ReverbSetDefault::handle_event() -{ - return 0; -} - -ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu, char *filename, char *path) - : BC_MenuItem(filename) -{ - this->reverb = reverb; - this->menu = menu; - strcpy(this->path, path); -} -ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu) - : BC_MenuItem("") -{ - this->reverb = reverb; - this->menu = menu; -} -int ReverbLoadPrev::handle_event() -{ - menu->prev_load_thread->set_path(path); - menu->prev_load_thread->start(); - return 0; -} -int ReverbLoadPrev::set_path(char *path) -{ - strcpy(this->path, path); - return 0; -} - - -ReverbSaveThread::ReverbSaveThread(Reverb *reverb, ReverbMenu *menu) - : Thread() -{ - this->reverb = reverb; - this->menu = menu; -} -ReverbSaveThread::~ReverbSaveThread() -{ -} -void ReverbSaveThread::run() -{ - int result = 0; - { - ReverbSaveDialog dialog(reverb); - dialog.create_objects(); - result = dialog.run_window(); -// if(!result) strcpy(reverb->config_directory, dialog.get_path()); - } - if(!result) - { - result = reverb->save_to_file(reverb->config_directory); - menu->add_load(reverb->config_directory); - } -} - -ReverbSaveDialog::ReverbSaveDialog(Reverb *reverb) - : BC_FileBox(0, - 0, - reverb->config_directory, - _("Save reverb"), - _("Select the reverb file to save as"), 0, 0) -{ - this->reverb = reverb; -} -ReverbSaveDialog::~ReverbSaveDialog() -{ -} -int ReverbSaveDialog::ok_event() -{ - set_done(0); - return 0; -} -int ReverbSaveDialog::cancel_event() -{ - set_done(1); - return 0; -} - - - -ReverbLoadThread::ReverbLoadThread(Reverb *reverb, ReverbMenu *menu) - : Thread() -{ - this->reverb = reverb; - this->menu = menu; -} -ReverbLoadThread::~ReverbLoadThread() -{ -} -void ReverbLoadThread::run() -{ - int result = 0; - { - ReverbLoadDialog dialog(reverb); - dialog.create_objects(); - result = dialog.run_window(); -// if(!result) strcpy(reverb->config_directory, dialog.get_path()); - } - if(!result) - { - result = reverb->load_from_file(reverb->config_directory); - if(!result) - { - menu->add_load(reverb->config_directory); - reverb->send_configure_change(); - } - } -} - -ReverbLoadPrevThread::ReverbLoadPrevThread(Reverb *reverb, ReverbMenu *menu) : Thread() -{ - this->reverb = reverb; - this->menu = menu; -} -ReverbLoadPrevThread::~ReverbLoadPrevThread() -{ -} -void ReverbLoadPrevThread::run() -{ - int result = 0; - strcpy(reverb->config_directory, path); - result = reverb->load_from_file(path); - if(!result) - { - menu->add_load(path); - reverb->send_configure_change(); - } -} -int ReverbLoadPrevThread::set_path(char *path) -{ - strcpy(this->path, path); - return 0; -} - - - - - -ReverbLoadDialog::ReverbLoadDialog(Reverb *reverb) - : BC_FileBox(0, - 0, - reverb->config_directory, - _("Load reverb"), - _("Select the reverb file to load from"), 0, 0) -{ - this->reverb = reverb; -} -ReverbLoadDialog::~ReverbLoadDialog() -{ -} -int ReverbLoadDialog::ok_event() -{ - set_done(0); - return 0; -} -int ReverbLoadDialog::cancel_event() -{ - set_done(1); - return 0; -} +// ReverbMenu::ReverbMenu(Reverb *reverb, ReverbWindow *window) +// : BC_MenuBar(0, 0, window->get_w()) +// { +// this->window = window; +// this->reverb = reverb; +// } +// +// ReverbMenu::~ReverbMenu() +// { +// delete load; +// delete save; +// //delete set_default; +// for(int i = 0; i < total_loads; i++) +// { +// delete prev_load[i]; +// } +// delete prev_load_thread; +// } +// +// void ReverbMenu::create_objects(BC_Hash *defaults) +// { +// add_menu(filemenu = new BC_Menu(_("File"))); +// filemenu->add_item(load = new ReverbLoad(reverb, this)); +// filemenu->add_item(save = new ReverbSave(reverb, this)); +// //filemenu->add_item(set_default = new ReverbSetDefault); +// load_defaults(defaults); +// prev_load_thread = new ReverbLoadPrevThread(reverb, this); +// } +// +// int ReverbMenu::load_defaults(BC_Hash *defaults) +// { +// FileSystem fs; +// total_loads = defaults->get("TOTAL_LOADS", 0); +// if(total_loads > 0) +// { +// filemenu->add_item(new BC_MenuItem("-")); +// char string[1024], path[1024], filename[1024]; +// +// for(int i = 0; i < total_loads; i++) +// { +// sprintf(string, "LOADPREVIOUS%d", i); +// defaults->get(string, path); +// fs.extract_name(filename, path); +// //printf("ReverbMenu::load_defaults %s\n", path); +// filemenu->add_item(prev_load[i] = new ReverbLoadPrev(reverb, this, filename, path)); +// } +// } +// return 0; +// } +// +// int ReverbMenu::save_defaults(BC_Hash *defaults) +// { +// if(total_loads > 0) +// { +// defaults->update("TOTAL_LOADS", total_loads); +// char string[1024]; +// +// for(int i = 0; i < total_loads; i++) +// { +// sprintf(string, "LOADPREVIOUS%d", i); +// defaults->update(string, prev_load[i]->path); +// } +// } +// return 0; +// } +// +// int ReverbMenu::add_load(char *path) +// { +// if(total_loads == 0) +// { +// filemenu->add_item(new BC_MenuItem("-")); +// } +// +// // test for existing copy +// FileSystem fs; +// char text[1024], new_path[1024]; // get text and path +// fs.extract_name(text, path); +// strcpy(new_path, path); +// +// for(int i = 0; i < total_loads; i++) +// { +// if(!strcmp(prev_load[i]->get_text(), text)) // already exists +// { // swap for top load +// for(int j = i; j > 0; j--) // move preceeding loads down +// { +// prev_load[j]->set_text(prev_load[j - 1]->get_text()); +// prev_load[j]->set_path(prev_load[j - 1]->path); +// } +// prev_load[0]->set_text(text); +// prev_load[0]->set_path(new_path); +// return 1; +// } +// } +// +// // add another load +// if(total_loads < TOTAL_LOADS) +// { +// filemenu->add_item(prev_load[total_loads] = new ReverbLoadPrev(reverb, this)); +// total_loads++; +// } +// +// // cycle loads down +// for(int i = total_loads - 1; i > 0; i--) +// { +// // set menu item text +// prev_load[i]->set_text(prev_load[i - 1]->get_text()); +// // set filename +// prev_load[i]->set_path(prev_load[i - 1]->path); +// } +// +// // set up the new load +// prev_load[0]->set_text(text); +// prev_load[0]->set_path(new_path); +// return 0; +// } +// +// ReverbLoad::ReverbLoad(Reverb *reverb, ReverbMenu *menu) +// : BC_MenuItem(_("Load...")) +// { +// this->reverb = reverb; +// this->menu = menu; +// thread = new ReverbLoadThread(reverb, menu); +// } +// ReverbLoad::~ReverbLoad() +// { +// delete thread; +// } +// int ReverbLoad::handle_event() +// { +// thread->start(); +// return 0; +// } +// +// ReverbSave::ReverbSave(Reverb *reverb, ReverbMenu *menu) +// : BC_MenuItem(_("Save...")) +// { +// this->reverb = reverb; +// this->menu = menu; +// thread = new ReverbSaveThread(reverb, menu); +// } +// ReverbSave::~ReverbSave() +// { +// delete thread; +// } +// int ReverbSave::handle_event() +// { +// thread->start(); +// return 0; +// } +// +// ReverbSetDefault::ReverbSetDefault() +// : BC_MenuItem(_("Set default")) +// { +// } +// int ReverbSetDefault::handle_event() +// { +// return 0; +// } +// +// ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu, char *filename, char *path) +// : BC_MenuItem(filename) +// { +// this->reverb = reverb; +// this->menu = menu; +// strcpy(this->path, path); +// } +// ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu) +// : BC_MenuItem("") +// { +// this->reverb = reverb; +// this->menu = menu; +// } +// int ReverbLoadPrev::handle_event() +// { +// menu->prev_load_thread->set_path(path); +// menu->prev_load_thread->start(); +// } +// int ReverbLoadPrev::set_path(char *path) +// { +// strcpy(this->path, path); +// } +// +// +// ReverbSaveThread::ReverbSaveThread(Reverb *reverb, ReverbMenu *menu) +// : Thread() +// { +// this->reverb = reverb; +// this->menu = menu; +// } +// ReverbSaveThread::~ReverbSaveThread() +// { +// } +// void ReverbSaveThread::run() +// { +// int result = 0; +// { +// ReverbSaveDialog dialog(reverb); +// dialog.create_objects(); +// result = dialog.run_window(); +// // if(!result) strcpy(reverb->config_directory, dialog.get_path()); +// } +// if(!result) +// { +// result = reverb->save_to_file(reverb->config_directory); +// menu->add_load(reverb->config_directory); +// } +// } +// +// ReverbSaveDialog::ReverbSaveDialog(Reverb *reverb) +// : BC_FileBox(0, +// 0, +// reverb->config_directory, +// _("Save reverb"), +// _("Select the reverb file to save as"), 0, 0) +// { +// this->reverb = reverb; +// } +// ReverbSaveDialog::~ReverbSaveDialog() +// { +// } +// int ReverbSaveDialog::ok_event() +// { +// set_done(0); +// return 0; +// } +// int ReverbSaveDialog::cancel_event() +// { +// set_done(1); +// return 0; +// } +// +// +// +// ReverbLoadThread::ReverbLoadThread(Reverb *reverb, ReverbMenu *menu) +// : Thread() +// { +// this->reverb = reverb; +// this->menu = menu; +// } +// ReverbLoadThread::~ReverbLoadThread() +// { +// } +// void ReverbLoadThread::run() +// { +// int result = 0; +// { +// ReverbLoadDialog dialog(reverb); +// dialog.create_objects(); +// result = dialog.run_window(); +// // if(!result) strcpy(reverb->config_directory, dialog.get_path()); +// } +// if(!result) +// { +// result = reverb->load_from_file(reverb->config_directory); +// if(!result) +// { +// menu->add_load(reverb->config_directory); +// reverb->send_configure_change(); +// } +// } +// } +// +// ReverbLoadPrevThread::ReverbLoadPrevThread(Reverb *reverb, ReverbMenu *menu) : Thread() +// { +// this->reverb = reverb; +// this->menu = menu; +// } +// ReverbLoadPrevThread::~ReverbLoadPrevThread() +// { +// } +// void ReverbLoadPrevThread::run() +// { +// int result = 0; +// strcpy(reverb->config_directory, path); +// result = reverb->load_from_file(path); +// if(!result) +// { +// menu->add_load(path); +// reverb->send_configure_change(); +// } +// } +// int ReverbLoadPrevThread::set_path(char *path) +// { +// strcpy(this->path, path); +// return 0; +// } +// +// +// +// +// +// ReverbLoadDialog::ReverbLoadDialog(Reverb *reverb) +// : BC_FileBox(0, +// 0, +// reverb->config_directory, +// _("Load reverb"), +// _("Select the reverb file to load from"), 0, 0) +// { +// this->reverb = reverb; +// } +// ReverbLoadDialog::~ReverbLoadDialog() +// { +// } +// int ReverbLoadDialog::ok_event() +// { +// set_done(0); +// return 0; +// } +// int ReverbLoadDialog::cancel_event() +// { +// set_done(1); +// return 0; +// } diff --git a/cinelerra-5.1/plugins/rgbshift/rgbshift.C b/cinelerra-5.1/plugins/rgbshift/rgbshift.C index 6cfb38b2..21dd4274 100644 --- a/cinelerra-5.1/plugins/rgbshift/rgbshift.C +++ b/cinelerra-5.1/plugins/rgbshift/rgbshift.C @@ -25,7 +25,7 @@ #include "filexml.h" #include "guicast.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/spectrogram/spectrogram.C b/cinelerra-5.1/plugins/spectrogram/spectrogram.C index 9707f126..4648737b 100644 --- a/cinelerra-5.1/plugins/spectrogram/spectrogram.C +++ b/cinelerra-5.1/plugins/spectrogram/spectrogram.C @@ -25,7 +25,7 @@ #include "bchash.h" #include "filexml.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "samples.h" #include "spectrogram.h" #include "theme.h" diff --git a/cinelerra-5.1/plugins/spherecam/Makefile b/cinelerra-5.1/plugins/spherecam/Makefile new file mode 100644 index 00000000..9bdb0c7f --- /dev/null +++ b/cinelerra-5.1/plugins/spherecam/Makefile @@ -0,0 +1,9 @@ +include ../../plugin_defs + +OBJS = $(OBJDIR)/spherecam.o + +PLUGIN = spherecam + +include ../../plugin_config + +$(OBJDIR)/spherecam.o: spherecam.C diff --git a/cinelerra-5.1/plugins/spherecam/picon_cinfinity.png b/cinelerra-5.1/plugins/spherecam/picon_cinfinity.png new file mode 100644 index 00000000..ee0b79ab Binary files /dev/null and b/cinelerra-5.1/plugins/spherecam/picon_cinfinity.png differ diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.C b/cinelerra-5.1/plugins/spherecam/spherecam.C new file mode 100644 index 00000000..8b1f6951 --- /dev/null +++ b/cinelerra-5.1/plugins/spherecam/spherecam.C @@ -0,0 +1,1026 @@ + +/* + * CINELERRA + * Copyright (C) 2017 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "affine.h" +#include "bcdisplayinfo.h" +#include "bchash.h" +#include "bcsignals.h" +#include "clip.h" +#include "filexml.h" +#include "language.h" +#include "spherecam.h" +#include "theme.h" + +#include + +// largely based on equations from http://paulbourke.net/dome/fish2/ + +REGISTER_PLUGIN(SphereCamMain) + + +SphereCamConfig::SphereCamConfig() +{ + feather = 0; + + for( int i = 0; i < EYES; i++ ) { + enabled[i] = 1; + fov[i] = 180; + radius[i] = 100.0; + center_y[i] = 50.0; + rotate_y[i] = 50.0; + rotate_z[i] = 0; + } + + center_x[0] = 25.0; + center_x[1] = 75.0; + rotate_x[0] = 50.0; + rotate_x[1] = 100.0; + draw_guides = 1; + mode = SphereCamConfig::DO_NOTHING; +} + +int SphereCamConfig::equivalent(SphereCamConfig &that) +{ + for( int i = 0; i < EYES; i++ ) { + if( enabled[i] != that.enabled[i] || + !EQUIV(fov[i], that.fov[i]) || + !EQUIV(radius[i], that.radius[i]) || + !EQUIV(center_x[i], that.center_x[i]) || + !EQUIV(center_y[i], that.center_y[i]) || + !EQUIV(rotate_x[i], that.rotate_x[i]) || + !EQUIV(rotate_y[i], that.rotate_y[i]) || + !EQUIV(rotate_z[i], that.rotate_z[i]) ) { + return 0; + } + } + + if( feather != that.feather || mode != that.mode || + draw_guides != that.draw_guides ) { + return 0; + } + + + return 1; +} + +void SphereCamConfig::copy_from(SphereCamConfig &that) +{ + *this = that; +} + +void SphereCamConfig::interpolate(SphereCamConfig &prev, + SphereCamConfig &next, + int64_t prev_frame, + int64_t next_frame, + int64_t current_frame) +{ + double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); + double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); + + for( int i = 0; i < EYES; i++ ) { + enabled[i] = prev.enabled[i]; + fov[i] = prev.fov[i] * prev_scale + next.fov[i] * next_scale; + radius[i] = prev.radius[i] * prev_scale + next.radius[i] * next_scale; + center_x[i] = prev.center_x[i] * prev_scale + next.center_x[i] * next_scale; + center_y[i] = prev.center_y[i] * prev_scale + next.center_y[i] * next_scale; + rotate_x[i] = prev.rotate_x[i] * prev_scale + next.rotate_x[i] * next_scale; + rotate_y[i] = prev.rotate_y[i] * prev_scale + next.rotate_y[i] * next_scale; + rotate_z[i] = prev.rotate_z[i] * prev_scale + next.rotate_z[i] * next_scale; + } + + feather = prev.feather * prev_scale + next.feather * next_scale; + draw_guides = prev.draw_guides; + mode = prev.mode; + + boundaries(); +} + +void SphereCamConfig::boundaries() +{ + for( int i = 0; i < EYES; i++ ) { + CLAMP(fov[i], 1.0, 359.0); + CLAMP(radius[i], 1.0, 150.0); + CLAMP(center_x[i], 0.0, 100.0); + CLAMP(center_y[i], 0.0, 100.0); + CLAMP(rotate_x[i], 0.0, 100.0); + CLAMP(rotate_y[i], 0.0, 100.0); + CLAMP(rotate_z[i], -180.0, 180.0); + } + + CLAMP(feather, 0, 50); +} + + +SphereCamSlider::SphereCamSlider(SphereCamMain *client, + SphereCamGUI *gui, + SphereCamText *text, + float *output, + int x, + int y, + float min, + float max) + : BC_FSlider(x, + y, + 0, + gui->get_w() / 2 - client->get_theme()->widget_border * 3 - 100, + gui->get_w() / 2 - client->get_theme()->widget_border * 3 - 100, + min, + max, + *output) +{ + this->gui = gui; + this->client = client; + this->output = output; + this->text = text; + set_precision(0.01); +} + +int SphereCamSlider::handle_event() +{ + *output = get_value(); + text->update(*output); + client->send_configure_change(); + return 1; +} + + +SphereCamText::SphereCamText(SphereCamMain *client, + SphereCamGUI *gui, + SphereCamSlider *slider, + float *output, + int x, + int y) + : BC_TextBox(x, y, 100, 1, *output) +{ + this->gui = gui; + this->client = client; + this->output = output; + this->slider = slider; +} + +int SphereCamText::handle_event() +{ + *output = atof(get_text()); + slider->update(*output); + client->send_configure_change(); + return 1; +} + + +SphereCamToggle::SphereCamToggle(SphereCamMain *client, + int *output, int x, int y, const char *text) + : BC_CheckBox(x, y, *output, text) +{ + this->output = output; + this->client = client; +} + +int SphereCamToggle::handle_event() +{ + *output = get_value(); + client->send_configure_change(); + return 1; +} + + +SphereCamMode::SphereCamMode(SphereCamMain *plugin, + SphereCamGUI *gui, int x, int y) + : BC_PopupMenu(x, y, calculate_w(gui), "", 1) +{ + this->plugin = plugin; + this->gui = gui; +} + +int SphereCamMode::handle_event() +{ + plugin->config.mode = from_text(get_text()); + plugin->send_configure_change(); + return 1; + +} + +void SphereCamMode::create_objects() +{ + add_item(new BC_MenuItem(to_text(SphereCamConfig::DO_NOTHING))); + add_item(new BC_MenuItem(to_text(SphereCamConfig::EQUIRECT))); + add_item(new BC_MenuItem(to_text(SphereCamConfig::ALIGN))); + update(plugin->config.mode); +} + +void SphereCamMode::update(int mode) +{ + char string[BCTEXTLEN]; + sprintf(string, "%s", to_text(mode)); + set_text(string); +} + +int SphereCamMode::calculate_w(SphereCamGUI *gui) +{ + int result = 0; + result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(SphereCamConfig::EQUIRECT))); + result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(SphereCamConfig::DO_NOTHING))); + result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(SphereCamConfig::ALIGN))); + return result + 50; +} + +int SphereCamMode::from_text(char *text) +{ + for( int i = 0; i < 3; i++ ) { + if( !strcmp(text, to_text(i)) ) { + return i; + } + } + + return SphereCamConfig::EQUIRECT; +} + +const char* SphereCamMode::to_text(int mode) +{ + switch( mode ) { + case SphereCamConfig::DO_NOTHING: + return "Do nothing"; + break; + case SphereCamConfig::EQUIRECT: + return "Equirectangular"; + break; + case SphereCamConfig::ALIGN: + return "Align only"; + break; + } + return "Equirectangular"; +} + + +SphereCamGUI::SphereCamGUI(SphereCamMain *client) + : PluginClientWindow(client, 640, 600, 640, 600, 0) +{ + this->client = client; +} + +SphereCamGUI::~SphereCamGUI() +{ +} + + +void SphereCamGUI::create_objects() +{ + int margin = client->get_theme()->widget_border; + int margin2 = margin; + int y = margin; + int x[EYES]; + + x[0] = margin; + x[1] = get_w() / 2 + margin / 2; + + BC_Title *title; + + for( int i = 0; i < EYES; i++ ) { + int x3 = x[i]; + y = margin; + + add_tool(title = new BC_Title(x[i], y, + i == 0 ? _("Left Eye") : _("Right Eye"), LARGEFONT)); + y += title->get_h() + margin2; + + add_tool(enabled[i] = new SphereCamToggle(client, + &client->config.enabled[i], x3, y, _("Enabled"))); + y += enabled[i]->get_h() + margin2; + + add_tool(title = new BC_Title(x3, y, _("FOV:"))); + y += title->get_h() + margin2; + add_tool(fov_slider[i] = new SphereCamSlider(client, this, + 0, &client->config.fov[i], x3, y, 1, 359)); + fov_slider[i]->set_precision(0.1); + x3 += fov_slider[i]->get_w() + margin; + add_tool(fov_text[i] = new SphereCamText(client, this, + fov_slider[i], &client->config.fov[i], x3, y)); + fov_slider[i]->text = fov_text[i]; + y += fov_text[i]->get_h() + margin2; + + x3 = x[i]; + add_tool(title = new BC_Title(x3, y, _("Radius:"))); + y += title->get_h() + margin2; + add_tool(radius_slider[i] = new SphereCamSlider(client, this, + 0, &client->config.radius[i], x3, y, 1, 150)); + radius_slider[i]->set_precision(0.1); + x3 += radius_slider[i]->get_w() + margin; + add_tool(radius_text[i] = new SphereCamText(client, this, + radius_slider[i], &client->config.radius[i], x3, y)); + radius_slider[i]->text = radius_text[i]; + y += radius_text[i]->get_h() + margin2; + + x3 = x[i]; + add_tool(title = new BC_Title(x3, y, _("Input X:"))); + y += title->get_h() + margin2; + add_tool(centerx_slider[i] = new SphereCamSlider(client, this, + 0, &client->config.center_x[i], x3, y, 0, 100)); + centerx_slider[i]->set_precision(0.1); + x3 += centerx_slider[i]->get_w() + margin; + add_tool(centerx_text[i] = new SphereCamText(client, this, + centerx_slider[i], &client->config.center_x[i], x3, y)); + centerx_slider[i]->text = centerx_text[i]; + y += centerx_text[i]->get_h() + margin2; + + x3 = x[i]; + add_tool(title = new BC_Title(x3, y, _("Input Y:"))); + y += title->get_h() + margin2; + add_tool(centery_slider[i] = new SphereCamSlider(client, this, + 0, &client->config.center_y[i], x3, y, 0, 100)); + centery_slider[i]->set_precision(0.1); + x3 += centery_slider[i]->get_w() + margin; + add_tool(centery_text[i] = new SphereCamText(client, this, + centery_slider[i], &client->config.center_y[i], x3, y)); + centery_slider[i]->text = centery_text[i]; + y += centery_text[i]->get_h() + margin2; + + x3 = x[i]; + add_tool(title = new BC_Title(x3, y, _("Output X:"))); + y += title->get_h() + margin2; + add_tool(rotatex_slider[i] = new SphereCamSlider(client, this, + 0, &client->config.rotate_x[i], x3, y, 0, 100)); + rotatex_slider[i]->set_precision(0.1); + x3 += rotatex_slider[i]->get_w() + margin; + add_tool(rotatex_text[i] = new SphereCamText(client, this, + rotatex_slider[i], &client->config.rotate_x[i], x3, y)); + rotatex_slider[i]->text = rotatex_text[i]; + y += rotatex_text[i]->get_h() + margin2; + + x3 = x[i]; + add_tool(title = new BC_Title(x3, y, _("Output Y:"))); + y += title->get_h() + margin2; + add_tool(rotatey_slider[i] = new SphereCamSlider(client, this, + 0, &client->config.rotate_y[i], x3, y, 0, 100)); + rotatey_slider[i]->set_precision(0.1); + x3 += rotatey_slider[i]->get_w() + margin; + add_tool(rotatey_text[i] = new SphereCamText(client, this, + rotatey_slider[i], &client->config.rotate_y[i], x3, y)); + rotatey_slider[i]->text = rotatey_text[i]; + y += rotatey_text[i]->get_h() + margin2; + + x3 = x[i]; + add_tool(title = new BC_Title(x3, y, _("Rotate:"))); + y += title->get_h() + margin2; + add_tool(rotatez_slider[i] = new SphereCamSlider(client, this, + 0, &client->config.rotate_z[i], x3, y, -180, 180)); + rotatez_slider[i]->set_precision(0.1); + x3 += rotatez_slider[i]->get_w() + margin; + add_tool(rotatez_text[i] = new SphereCamText(client, this, + rotatez_slider[i], &client->config.rotate_z[i], x3, y)); + rotatez_slider[i]->text = rotatez_text[i]; + y += rotatez_text[i]->get_h() + margin2; + } + + int x3 = x[0]; + add_tool(title = new BC_Title(x3, y, _("Feather:"))); + y += title->get_h() + margin2; + add_tool(feather_slider = new SphereCamSlider(client, this, + 0, &client->config.feather, x3, y, 0, 100)); + feather_slider->set_precision(0.1); + x3 += feather_slider->get_w() + margin; + add_tool(feather_text = new SphereCamText(client, this, + feather_slider, &client->config.feather, x3, y)); + feather_slider->text = feather_text; + y += feather_text->get_h() + margin2; + +//printf("SphereCamGUI::create_objects %d %f\n", __LINE__, client->config.distance); + + x3 = x[0]; + add_tool(draw_guides = new SphereCamToggle(client, + &client->config.draw_guides, x3, y, _("Draw guides"))); + y += draw_guides->get_h() + margin2; + + add_tool(title = new BC_Title(x3, y, _("Mode:"))); + add_tool(mode = new SphereCamMode(client, + this, + x3 + title->get_w() + margin, + y)); + mode->create_objects(); + y += mode->get_h() + margin2; + + show_window(); + flush(); +} + + +SphereCamMain::SphereCamMain(PluginServer *server) + : PluginVClient(server) +{ + engine = 0; + affine = 0; +} + +SphereCamMain::~SphereCamMain() +{ + delete engine; + delete affine; +} + +NEW_WINDOW_MACRO(SphereCamMain, SphereCamGUI) +LOAD_CONFIGURATION_MACRO(SphereCamMain, SphereCamConfig) +int SphereCamMain::is_realtime() { return 1; } +const char* SphereCamMain::plugin_title() { return N_("Sphere Cam"); } + +void SphereCamMain::update_gui() +{ + if( !thread ) return; + if( !load_configuration() ) return; + ((SphereCamGUI*)thread->window)->lock_window("SphereCamMain::update_gui"); + SphereCamGUI *window = (SphereCamGUI*)thread->window; + + for( int i = 0; i < EYES; i++ ) { + window->enabled[i]->update(config.enabled[i]); + + window->fov_slider[i]->update(config.fov[i]); + window->fov_text[i]->update(config.fov[i]); + + window->radius_slider[i]->update(config.radius[i]); + window->radius_text[i]->update(config.radius[i]); + + window->centerx_slider[i]->update(config.center_x[i]); + window->centerx_text[i]->update(config.center_x[i]); + + window->centery_slider[i]->update(config.center_y[i]); + window->centery_text[i]->update(config.center_y[i]); + + window->rotatex_slider[i]->update(config.rotate_x[i]); + window->rotatex_text[i]->update(config.rotate_x[i]); + + window->rotatey_slider[i]->update(config.rotate_y[i]); + window->rotatey_text[i]->update(config.rotate_y[i]); + + window->rotatez_slider[i]->update(config.rotate_z[i]); + window->rotatez_text[i]->update(config.rotate_z[i]); + } + + window->feather_slider->update(config.feather); + window->feather_text->update(config.feather); + + window->mode->update(config.mode); + window->draw_guides->update(config.draw_guides); + window->unlock_window(); +} + +void SphereCamMain::save_data(KeyFrame *keyframe) +{ + FileXML output; + char string[BCTEXTLEN]; + +// cause data to be stored directly in text + output.set_shared_output(keyframe->get_data(), MESSAGESIZE); + output.tag.set_title("SPHERECAM"); + + for( int i = 0; i < EYES; i++ ) { + sprintf(string, "ENABLED_%d", i); + output.tag.set_property(string, config.enabled[i]); + sprintf(string, "FOV_%d", i); + output.tag.set_property(string, config.fov[i]); + sprintf(string, "RADIUS_%d", i); + output.tag.set_property(string, config.radius[i]); + sprintf(string, "CENTER_X_%d", i); + output.tag.set_property(string, config.center_x[i]); + sprintf(string, "CENTER_Y_%d", i); + output.tag.set_property(string, config.center_y[i]); + sprintf(string, "ROTATE_X_%d", i); + output.tag.set_property(string, config.rotate_x[i]); + sprintf(string, "ROTATE_Y_%d", i); + output.tag.set_property(string, config.rotate_y[i]); + sprintf(string, "ROTATE_Z_%d", i); + output.tag.set_property(string, config.rotate_z[i]); + } + + output.tag.set_property("FEATHER", config.feather); + output.tag.set_property("DRAW_GUIDES", config.draw_guides); + output.tag.set_property("MODE", config.mode); + output.append_tag(); + output.terminate_string(); +} + + +void SphereCamMain::read_data(KeyFrame *keyframe) +{ + FileXML input; + char string[BCTEXTLEN]; + + + input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); + + int result = 0; + + while(!result) + { + result = input.read_tag(); + + if( !result ) { + if( input.tag.title_is("SPHERECAM") ) { + for( int i = 0; i < EYES; i++ ) { + sprintf(string, "ENABLED_%d", i); + config.enabled[i] = input.tag.get_property(string, config.enabled[i]); + sprintf(string, "FOV_%d", i); + config.fov[i] = input.tag.get_property(string, config.fov[i]); + sprintf(string, "RADIUS_%d", i); + config.radius[i] = input.tag.get_property(string, config.radius[i]); + sprintf(string, "CENTER_X_%d", i); + config.center_x[i] = input.tag.get_property(string, config.center_x[i]); + sprintf(string, "CENTER_Y_%d", i); + config.center_y[i] = input.tag.get_property(string, config.center_y[i]); + sprintf(string, "ROTATE_X_%d", i); + config.rotate_x[i] = input.tag.get_property(string, config.rotate_x[i]); + sprintf(string, "ROTATE_Y_%d", i); + config.rotate_y[i] = input.tag.get_property(string, config.rotate_y[i]); + sprintf(string, "ROTATE_Z_%d", i); + config.rotate_z[i] = input.tag.get_property(string, config.rotate_z[i]); + } + + config.feather = input.tag.get_property("FEATHER", config.feather); + config.draw_guides = input.tag.get_property("DRAW_GUIDES", config.draw_guides); + config.mode = input.tag.get_property("MODE", config.mode); + } + } + } +} + + + +int SphereCamMain::process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate) +{ + load_configuration(); + + VFrame *input = new_temp(frame->get_w(), frame->get_h(), frame->get_color_model()); + + read_frame(input, 0, start_position, frame_rate, 0); // use opengl + +// find_lenses(); + calculate_extents(); + + if( config.mode == SphereCamConfig::DO_NOTHING ) { + get_output()->copy_from(input); + } + else { + get_output()->clear_frame(); + if( !engine ) engine = new SphereCamEngine(this); + engine->process_packages(); + } + + if( config.draw_guides ) { +// input regions +// printf("SphereCamMain::process_buffer %d %d %d\n", __LINE__, out_x1[0], out_x4[0]); + for( int eye = 0; eye < EYES; eye++ ) { + if( config.enabled[eye] ) { +// input regions + get_output()->draw_oval(input_x[eye] - radius[eye], + input_y[eye] - radius[eye], + input_x[eye] + radius[eye], + input_y[eye] + radius[eye]); + + +// output regions. If they overlap, don't xor out the line + if( eye == 0 || (out_x1[eye] != out_x1[0] && out_x1[eye] != out_x4[0]) ) { + get_output()->draw_line(out_x1[eye], 0, out_x1[eye], h); + } + + if( eye == 0 || (out_x4[eye] != out_x4[0] && out_x4[eye] != out_x1[0]) ) { + get_output()->draw_line(out_x4[eye], 0, out_x4[eye], h); + } + + if( feather != 0 && eye == 1 ) { +// crosshatch feather of right eye only, since only the right eye feathers + int feather_gap = h / 20; + for( int j = 0; j < h + feather; j += feather_gap ) { + draw_feather(out_x1[eye], out_x1[eye] + feather, eye, j); + draw_feather(out_x4[eye] - feather, out_x4[eye], eye, j); + } + } + } + } + + } + + return 0; +} + +void SphereCamMain::draw_feather(int left, int right, int eye, int y) +{ + int slope = 1; + if( eye == 1 ) { + slope = -1; + } + +// wrap + if( left < 0 ) { + int left2 = w + left; + get_output()->draw_line(left2, y, left2 + right - left, y + feather * slope); + } + + if( right > w ) { + int right2 = right - w; + get_output()->draw_line(0, y, right2, y + feather * slope); + + } + +// proper + get_output()->draw_line(left, y, right, y + feather * slope); + +} + + +// void SphereCamMain::find_lenses() +// { +// } + + +void SphereCamMain::calculate_extents() +{ + w = get_output()->get_w(); + h = get_output()->get_h(); + + feather = (int)(config.feather * w / 100); + + for( int i = 0; i < EYES; i++ ) { +// input regions + input_x[i] = (int)(config.center_x[i] * w / 100); + input_y[i] = (int)(config.center_y[i] * h / 100); + radius[i] = (int)(h / 2 * config.radius[i] / 100); + +// output regions + output_x[i] = (int)(config.rotate_x[i] * w / 100); + output_y[i] = (int)(config.rotate_y[i] * h / 100); + + +// Assume each lens fills 1/2 the width + out_x1[i] = output_x[i] - w / 4 - feather / 2; + out_x2[i] = output_x[i]; + out_x3[i] = output_x[i]; + out_x4[i] = output_x[i] + w / 4 + feather / 2; + } + +// If the output isn't 50% apart, we have to expand the left eye to fill the feathering region +//printf("SphereCamMain::calculate_extents %d %f\n", __LINE__, config.rotate_x[0] - config.rotate_x[1]); + float x_separation = config.rotate_x[0] - config.rotate_x[1]; + if( !EQUIV(fabs(x_separation), 50) ) { + if( x_separation < -50 ) { + out_x4[0] += (-49.5 - x_separation) * w / 100; + } + else + if( x_separation < 0 ) { + out_x1[0] -= (x_separation + 50) * w / 100; + } + else + if( x_separation < 50 ) { + out_x4[0] += (50.5 - x_separation) * w / 100; + } + else { + out_x1[0] -= (x_separation - 49.5) * w / 100; + } + } + + +// wrap around + for( int i = 0; i < EYES; i++ ) { + if( out_x1[i] < 0 ) { + out_x1[i] = w + out_x1[i]; + out_x2[i] = w; + out_x3[i] = 0; + } + + if( out_x4[i] > w ) { + out_x2[i] = w; + out_x3[i] = 0; + out_x4[i] -= w; + } + +// printf("SphereCamMain::calculate_extents %d i=%d x=%d y=%d radius=%d\n", +// __LINE__, +// i, +// center_x[i], +// center_y[i], +// radius[i]); + } +} + +SphereCamPackage::SphereCamPackage() + : LoadPackage() {} + +SphereCamUnit::SphereCamUnit(SphereCamEngine *engine, SphereCamMain *plugin) + : LoadClient(engine) +{ + this->plugin = plugin; +} + + +SphereCamUnit::~SphereCamUnit() +{ +} + + + +// interpolate & accumulate a pixel in the output +#define BLEND_PIXEL(type, components) \ + if( x_in < 0.0 || x_in >= w - 1 || \ + y_in < 0.0 || y_in >= h - 1 ) { \ + out_row += components; \ + } \ + else { \ + float y1_fraction = y_in - floor(y_in); \ + float y2_fraction = 1.0 - y1_fraction; \ + float x1_fraction = x_in - floor(x_in); \ + float x2_fraction = 1.0 - x1_fraction; \ + type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \ + type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \ + for( int i = 0; i < components; i++ ) { \ + float value = in_pixel1[i] * x2_fraction * y2_fraction + \ + in_pixel2[i] * x2_fraction * y1_fraction + \ + in_pixel1[i + components] * x1_fraction * y2_fraction + \ + in_pixel2[i + components] * x1_fraction * y1_fraction; \ + value = *out_row * inv_a + value * a; \ + *out_row++ = (type)value; \ + } \ + } + + +// nearest neighbor & accumulate a pixel in the output +#define BLEND_NEAREST(type, components) \ + if( x_in < 0.0 || x_in >= w - 1 || \ + y_in < 0.0 || y_in >= h - 1 ) { \ + out_row += components; \ + } \ + else { \ + type *in_pixel = in_rows[(int)y_in] + (int)x_in * components; \ + for( int i = 0; i < components; i++ ) { \ + float value = in_pixel[i]; \ + value = *out_row * inv_a + value * a; \ + *out_row++ = (type)value; \ + } \ + } + + +#define COLORSPACE_SWITCH(function) \ + switch( plugin->get_input()->get_color_model() ) { \ + case BC_RGB888: function(unsigned char, 3, 0x0); break; \ + case BC_RGBA8888: function(unsigned char, 4, 0x0); break; \ + case BC_RGB_FLOAT: function(float, 3, 0.0); break; \ + case BC_RGBA_FLOAT: function(float, 4, 0.0); break; \ + case BC_YUV888: function(unsigned char, 3, 0x80); break; \ + case BC_YUVA8888: function(unsigned char, 4, 0x80); break; \ + } + +void SphereCamUnit::process_equirect(SphereCamPackage *pkg) +{ + VFrame *input = plugin->get_temp(); + VFrame *output = plugin->get_output(); + + +// overlay a single eye +#define PROCESS_EQUIRECT(type, components, chroma) \ +{ \ + type **in_rows = (type**)input->get_rows(); \ + type **out_rows = (type**)output->get_rows(); \ + \ + for( int out_y = row1; out_y < row2; out_y++ ) { \ + type *out_row = out_rows[out_y]; \ +/* polar angle - -M_PI/2 to M_PI/2 */ \ + float y_diff = out_y - output_y; \ + float phi = M_PI / 2 * (y_diff / radius); \ + \ + for( int out_x = 0; out_x < w; out_x++ ) { \ +/* alpha */ \ + float a = alpha[out_x]; \ + float inv_a = 1.0f - a; \ + if( a > 0 ) { \ +/* polar angle */ \ + float x_diff = out_x - output_x; \ +/* -M_PI/2 to M_PI/2 */ \ + float theta = M_PI / 2 * (x_diff / radius); \ +/* vector in 3D space */ \ + float vect_x = cos(phi) * sin(theta); \ + float vect_y = cos(phi) * cos(theta); \ + float vect_z = sin(phi); \ +/* fisheye angle & radius */ \ + float theta2 = atan2(vect_z, vect_x) - rotate_z; \ + float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \ + float r = radius * 2 * phi2 / fov; \ +/* pixel in fisheye space */ \ + float x_in = input_x + r * cos(theta2); \ + float y_in = input_y + r * sin(theta2); \ + \ + BLEND_PIXEL(type, components) \ + } \ + else { \ + out_row += components; \ + } \ + } \ + } \ +} + + int row1 = pkg->row1; + int row2 = pkg->row2; + for( int eye = 0; eye < EYES; eye++ ) { + if( plugin->config.enabled[eye] ) { + int w = plugin->w; + int h = plugin->h; + float fov = plugin->config.fov[eye] * M_PI * 2 / 360; +// float radius = plugin->radius[eye]; + float radius = h / 2; + float input_x = plugin->input_x[eye]; + float input_y = plugin->input_y[eye]; + float output_x = plugin->output_x[eye]; + float output_y = plugin->output_y[eye]; + float rotate_z = plugin->config.rotate_z[eye] * M_PI * 2 / 360; + int feather = plugin->feather; + int out_x1 = plugin->out_x1[eye]; + int out_x2 = plugin->out_x2[eye]; + int out_x3 = plugin->out_x3[eye]; + int out_x4 = plugin->out_x4[eye]; + +// compute the alpha for every X + float alpha[w]; + for( int i = 0; i < w; i++ ) { + alpha[i] = 0; + } + + for( int i = out_x1; i < out_x2; i++ ) { + alpha[i] = 1.0f; + } + + for( int i = out_x3; i < out_x4; i++ ) { + alpha[i] = 1.0f; + } + + if( eye == 1 ) { + for( int i = out_x1; i < out_x1 + feather; i++ ) { + float value = (float)(i - out_x1) / feather; + if( i >= w ) { + alpha[i - w] = value; + } + else { + alpha[i] = value; + } + } + + for( int i = out_x4 - feather; i < out_x4; i++ ) { + float value = (float)(out_x4 - i) / feather; + if( i < 0 ) { + alpha[w + i] = value; + } + else { + alpha[i] = value; + } + } + } + + +//printf("SphereCamUnit::process_equirect %d rotate_x=%f rotate_y=%f rotate_z=%f\n", +// __LINE__, rotate_x, rotate_y, rotate_z); + + COLORSPACE_SWITCH(PROCESS_EQUIRECT) + } + } +} + + + +void SphereCamUnit::process_align(SphereCamPackage *pkg) +{ + VFrame *input = plugin->get_temp(); + VFrame *output = plugin->get_output(); + + +// overlay a single eye +#define PROCESS_ALIGN(type, components, chroma) \ +{ \ + type **in_rows = (type**)input->get_rows(); \ + type **out_rows = (type**)output->get_rows(); \ + \ + for( int out_y = row1; out_y < row2; out_y++ ) { \ + type *out_row = out_rows[out_y]; \ +/* polar angle */ \ +/* -M_PI/2 to M_PI/2 */ \ + float y_diff = out_y - output_y; \ + float phi = M_PI / 2 * (y_diff / radius); \ + \ + for( int out_x = 0; out_x < w; out_x++ ) { \ +/* alpha */ \ + float a = alpha[out_x]; \ + float inv_a = 1.0f - a; \ + if( a > 0 ) { \ +/* polar angle */ \ + float x_diff = out_x - output_x; \ +/* -M_PI/2 to M_PI/2 */ \ + float theta = M_PI / 2 * (x_diff / radius); \ + /* vector in 3D space */ \ + float vect_x = cos(phi) * sin(theta); \ + float vect_y = cos(phi) * cos(theta); \ + float vect_z = sin(phi); \ + /* fisheye angle & radius */ \ + float theta2 = atan2(vect_z, vect_x) - rotate_z; \ + float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \ + float r = radius * 2 * phi2 / fov; \ + /* pixel in fisheye space */ \ + float x_in = input_x + r * cos(theta2); \ + float y_in = input_y + r * sin(theta2); \ + \ + BLEND_NEAREST(type, components) \ + } \ + else { \ + out_row += components; \ + } \ + } \ + } \ +} + + int row1 = pkg->row1; + int row2 = pkg->row2; + for( int eye = 0; eye < EYES; eye++ ) { + if( plugin->config.enabled[eye] ) { + int w = plugin->w; + int h = plugin->h; + float fov = plugin->config.fov[eye] * M_PI * 2 / 360; +// float radius = plugin->radius[eye]; + float radius = h / 2; + float input_x = plugin->input_x[eye]; + float input_y = plugin->input_y[eye]; + float output_x = plugin->output_x[eye]; + float output_y = plugin->output_y[eye]; + float rotate_z = plugin->config.rotate_z[eye] * M_PI * 2 / 360; + int out_x1 = plugin->out_x1[eye]; + int out_x2 = plugin->out_x2[eye]; + int out_x3 = plugin->out_x3[eye]; + int out_x4 = plugin->out_x4[eye]; +// left eye is opaque. right eye overlaps +// compute the alpha for every X + float alpha[w]; + for( int i = 0; i < w; i++ ) alpha[i] = 0; + float v = eye == 0 || !plugin->config.enabled[0] ? 1.0f : 0.5f; + for( int i = out_x1; i < out_x2; i++ ) alpha[i] = v; + for( int i = out_x3; i < out_x4; i++ ) alpha[i] = v; + + COLORSPACE_SWITCH(PROCESS_ALIGN) + } + } +} + +void SphereCamUnit::process_package(LoadPackage *package) +{ + SphereCamPackage *pkg = (SphereCamPackage*)package; + + switch( plugin->config.mode ) { + case SphereCamConfig::EQUIRECT: + process_equirect(pkg); + break; + case SphereCamConfig::ALIGN: + process_align(pkg); + break; + } +} + + +SphereCamEngine::SphereCamEngine(SphereCamMain *plugin) + : LoadServer(plugin->PluginClient::smp + 1, plugin->PluginClient::smp + 1) +// : LoadServer(1, 1) +{ + this->plugin = plugin; +} + +SphereCamEngine::~SphereCamEngine() +{ +} + +void SphereCamEngine::init_packages() +{ + for( int i = 0; i < LoadServer::get_total_packages(); i++ ) { + SphereCamPackage *package = (SphereCamPackage*)LoadServer::get_package(i); + package->row1 = plugin->get_input()->get_h() * i / LoadServer::get_total_packages(); + package->row2 = plugin->get_input()->get_h() * (i + 1) / LoadServer::get_total_packages(); + } +} + +LoadClient* SphereCamEngine::new_client() +{ + return new SphereCamUnit(this, plugin); +} + +LoadPackage* SphereCamEngine::new_package() +{ + return new SphereCamPackage; +} + + diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.C.bak b/cinelerra-5.1/plugins/spherecam/spherecam.C.bak new file mode 100644 index 00000000..99d40770 --- /dev/null +++ b/cinelerra-5.1/plugins/spherecam/spherecam.C.bak @@ -0,0 +1,1310 @@ + +/* + * CINELERRA + * Copyright (C) 2017 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "affine.h" +#include "bcdisplayinfo.h" +#include "bchash.h" +#include "bcsignals.h" +#include "clip.h" +#include "filexml.h" +#include "language.h" +#include "360fuser.h" + + +#include + + + +// largely based on equations from http://paulbourke.net/dome/fish2/ + + + +REGISTER_PLUGIN(Fuse360Main) + + + + +Fuse360Config::Fuse360Config() +{ + fov = 1.0; + radius_x = 0.5; + radius_y = 0.5; + center_x = 50.0; + center_y = 50.0; + distance_x = 50; + distance_y = 0; + feather = 0; + translate_x = 0; + rotation = 0; + draw_guides = 1; + mode = Fuse360Config::DO_NOTHING; +} + +int Fuse360Config::equivalent(Fuse360Config &that) +{ + if(EQUIV(fov, that.fov) && + EQUIV(radius_x, that.radius_x) && + EQUIV(radius_y, that.radius_y) && + EQUIV(feather, that.feather) && + EQUIV(center_x, that.center_x) && + EQUIV(center_y, that.center_y) && + EQUIV(distance_x, that.distance_x) && + EQUIV(distance_y, that.distance_y) && + EQUIV(translate_x, that.translate_x) && + EQUIV(rotation, that.rotation) && + mode == that.mode && + draw_guides == that.draw_guides) + { + return 1; + } + else + { + return 0; + } +} + +void Fuse360Config::copy_from(Fuse360Config &that) +{ + *this = that; +} + +void Fuse360Config::interpolate(Fuse360Config &prev, + Fuse360Config &next, + int64_t prev_frame, + int64_t next_frame, + int64_t current_frame) +{ + double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); + double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); + + fov = prev.fov * prev_scale + next.fov * next_scale; + radius_x = prev.radius_x * prev_scale + next.radius_x * next_scale; + radius_y = prev.radius_y * prev_scale + next.radius_y * next_scale; + feather = prev.feather * prev_scale + next.feather * next_scale; + center_x = prev.center_x * prev_scale + next.center_x * next_scale; + center_y = prev.center_y * prev_scale + next.center_y * next_scale; + distance_x = prev.distance_x * prev_scale + next.distance_x * next_scale; + distance_y = prev.distance_y * prev_scale + next.distance_y * next_scale; + rotation = prev.rotation * prev_scale + next.rotation * next_scale; + translate_x = prev.translate_x * prev_scale + next.translate_x * next_scale; + draw_guides = prev.draw_guides; + mode = prev.mode; + + boundaries(); +} + +void Fuse360Config::boundaries() +{ + CLAMP(fov, 0.0, 1.0); + CLAMP(radius_x, 0.3, 1.0); + CLAMP(radius_y, 0.3, 1.0); + CLAMP(feather, 0, 50); + CLAMP(center_x, 0.0, 99.0); + CLAMP(center_y, 0.0, 99.0); + CLAMP(distance_x, 0.0, 100.0); + CLAMP(distance_y, -50.0, 50.0); + CLAMP(translate_x, -100, 100); + CLAMP(rotation, -180, 180); +} + + + + +Fuse360Slider::Fuse360Slider(Fuse360Main *client, + Fuse360GUI *gui, + Fuse360Text *text, + float *output, + int x, + int y, + float min, + float max) + : BC_FSlider(x, y, 0, 200, 200, min, max, *output) +{ + this->gui = gui; + this->client = client; + this->output = output; + this->text = text; + set_precision(0.01); +} + +int Fuse360Slider::handle_event() +{ + float prev_output = *output; + *output = get_value(); + text->update(*output); + + + client->send_configure_change(); + return 1; +} + + + +Fuse360Text::Fuse360Text(Fuse360Main *client, + Fuse360GUI *gui, + Fuse360Slider *slider, + float *output, + int x, + int y) + : BC_TextBox(x, y, 100, 1, *output) +{ + this->gui = gui; + this->client = client; + this->output = output; + this->slider = slider; +} + +int Fuse360Text::handle_event() +{ + float prev_output = *output; + *output = atof(get_text()); + slider->update(*output); + + + client->send_configure_change(); + return 1; +} + + + +Fuse360Toggle::Fuse360Toggle(Fuse360Main *client, + int *output, + int x, + int y, + const char *text) + : BC_CheckBox(x, y, *output, text) +{ + this->output = output; + this->client = client; +} + +int Fuse360Toggle::handle_event() +{ + *output = get_value(); + client->send_configure_change(); + return 1; +} + + + + + + + + + + +Fuse360Mode::Fuse360Mode(Fuse360Main *plugin, + Fuse360GUI *gui, + int x, + int y) + : BC_PopupMenu(x, + y, + calculate_w(gui), + "", + 1) +{ + this->plugin = plugin; + this->gui = gui; +} + +int Fuse360Mode::handle_event() +{ + plugin->config.mode = from_text(get_text()); + plugin->send_configure_change(); + return 1; + +} + +void Fuse360Mode::create_objects() +{ + add_item(new BC_MenuItem(to_text(Fuse360Config::DO_NOTHING))); + add_item(new BC_MenuItem(to_text(Fuse360Config::STRETCHXY))); + add_item(new BC_MenuItem(to_text(Fuse360Config::STANDARD))); + add_item(new BC_MenuItem(to_text(Fuse360Config::BLEND))); + update(plugin->config.mode); +} + +void Fuse360Mode::update(int mode) +{ + char string[BCTEXTLEN]; + sprintf(string, "%s", to_text(mode)); + set_text(string); +} + +int Fuse360Mode::calculate_w(Fuse360GUI *gui) +{ + int result = 0; + result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::STRETCHXY))); + result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::STANDARD))); + result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::BLEND))); + result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::DO_NOTHING))); + return result + 50; +} + +int Fuse360Mode::from_text(char *text) +{ + for(int i = 0; i < 4; i++) + { + if(!strcmp(text, to_text(i))) + { + return i; + } + } + + return Fuse360Config::STRETCHXY; +} + +const char* Fuse360Mode::to_text(int mode) +{ + switch(mode) + { + case Fuse360Config::DO_NOTHING: + return "Do nothing"; + break; + case Fuse360Config::STRETCHXY: + return "Stretch"; + break; + case Fuse360Config::STANDARD: + return "Equirectangular"; + break; + } + return "Blend"; +} + + + + + + + + + + + + + + + + +Fuse360GUI::Fuse360GUI(Fuse360Main *client) + : PluginClientWindow(client, + 350, + 650, + 350, + 650, + 0) +{ + this->client = client; +} + +Fuse360GUI::~Fuse360GUI() +{ +} + + +void Fuse360GUI::create_objects() +{ + int x = 10; + int y = 10; + int x1; + int margin = 10; + BC_Title *title; + Fuse360Toggle *toggle; + +// add_tool(title = new BC_Title(x, y, _("Field of View:"))); +// y += title->get_h() + 5; +// add_tool(fov_slider = new Fuse360Slider(client, +// this, +// 0, +// &client->config.fov, +// x, +// y, +// 0.0001, +// 1.0)); +// +// +// x1 = x + fov_slider->get_w() + margin; +// add_tool(fov_text = new Fuse360Text(client, +// this, +// fov_slider, +// &client->config.fov, +// x1, +// y)); +// fov_slider->text = fov_text; +// y += fov_text->get_h() + margin; + + + + + add_tool(title = new BC_Title(x, y, _("Eye Radius X:"))); + y += title->get_h() + 5; + add_tool(radiusx_slider = new Fuse360Slider(client, + this, + 0, + &client->config.radius_x, + x, + y, + 0.3, + 1.0)); + x1 = x + radiusx_slider->get_w() + margin; + add_tool(radiusx_text = new Fuse360Text(client, + this, + radiusx_slider, + &client->config.radius_x, + x1, + y)); + radiusx_slider->text = radiusx_text; + y += radiusx_text->get_h() + 5; + + + add_tool(title = new BC_Title(x, y, _("Eye Radius Y:"))); + y += title->get_h() + margin; + add_tool(radiusy_slider = new Fuse360Slider(client, + this, + 0, + &client->config.radius_y, + x, + y, + 0.3, + 1.0)); + x1 = x + radiusy_slider->get_w() + margin; + add_tool(radiusy_text = new Fuse360Text(client, + this, + radiusy_slider, + &client->config.radius_y, + x1, + y)); + radiusy_slider->text = radiusy_text; + y += radiusy_text->get_h() + margin; + + +// add_tool(title = new BC_Title(x, y, _("Center X:"))); +// y += title->get_h() + 5; +// add_tool(centerx_slider = new Fuse360Slider(client, +// this, +// 0, +// &client->config.center_x, +// x, +// y, +// 0.0, +// 99.0)); +// x1 = x + centerx_slider->get_w() + margin; +// add_tool(centerx_text = new Fuse360Text(client, +// this, +// centerx_slider, +// &client->config.center_x, +// x1, +// y)); +// centerx_slider->text = centerx_text; +// centerx_slider->set_precision(0.1); +// y += centerx_text->get_h() + margin; +// +// +// add_tool(title = new BC_Title(x, y, _("Center Y:"))); +// y += title->get_h() + 5; +// add_tool(centery_slider = new Fuse360Slider(client, +// this, +// 0, +// &client->config.center_y, +// x, +// y, +// 0.0, +// 99.0)); +// x1 = x + centery_slider->get_w() + margin; +// add_tool(centery_text = new Fuse360Text(client, +// this, +// centery_slider, +// &client->config.center_y, +// x1, +// y)); +// centery_slider->text = centery_text; +// centery_slider->set_precision(0.1); +// y += centery_text->get_h() + margin; + + + + + add_tool(title = new BC_Title(x, y, _("X Eye Spacing:"))); + y += title->get_h() + 5; + add_tool(distancex_slider = new Fuse360Slider(client, + this, + 0, + &client->config.distance_x, + x, + y, + 0.0, + 100.0)); + x1 = x + distancex_slider->get_w() + margin; + add_tool(distancex_text = new Fuse360Text(client, + this, + distancex_slider, + &client->config.distance_x, + x1, + y)); + distancex_slider->text = distancex_text; + distancex_slider->set_precision(0.1); + y += distancex_text->get_h() + margin; + + + + + + + + add_tool(title = new BC_Title(x, y, _("Y Eye Spacing:"))); + y += title->get_h() + 5; + add_tool(distancey_slider = new Fuse360Slider(client, + this, + 0, + &client->config.distance_y, + x, + y, + -50, + 50)); + x1 = x + distancey_slider->get_w() + margin; + add_tool(distancey_text = new Fuse360Text(client, + this, + distancey_slider, + &client->config.distance_y, + x1, + y)); + distancey_slider->text = distancey_text; + distancey_slider->set_precision(0.1); + y += distancey_text->get_h() + margin; + + + + + + + add_tool(title = new BC_Title(x, y, _("X Translation:"))); + y += title->get_h() + 5; + add_tool(translatex_slider = new Fuse360Slider(client, + this, + 0, + &client->config.translate_x, + x, + y, + -50.0, + 50.0)); + x1 = x + translatex_slider->get_w() + margin; + add_tool(translatex_text = new Fuse360Text(client, + this, + translatex_slider, + &client->config.translate_x, + x1, + y)); + translatex_slider->text = translatex_text; + translatex_slider->set_precision(0.1); + y += translatex_text->get_h() + margin; + + + + + + + add_tool(title = new BC_Title(x, y, _("Feather:"))); + y += title->get_h() + 5; + add_tool(feather_slider = new Fuse360Slider(client, + this, + 0, + &client->config.feather, + x, + y, + 0, + 50)); + x1 = x + feather_slider->get_w() + margin; + add_tool(feather_text = new Fuse360Text(client, + this, + feather_slider, + &client->config.feather, + x1, + y)); + feather_slider->text = feather_text; + feather_slider->set_precision(1); + y += feather_text->get_h() + margin; + + + + + + + add_tool(title = new BC_Title(x, y, _("Rotation:"))); + y += title->get_h() + 5; + add_tool(rotation_slider = new Fuse360Slider(client, + this, + 0, + &client->config.rotation, + x, + y, + -180, + 180)); + x1 = x + rotation_slider->get_w() + margin; + add_tool(rotation_text = new Fuse360Text(client, + this, + rotation_slider, + &client->config.rotation, + x1, + y)); + rotation_slider->text = rotation_text; + rotation_slider->set_precision(0.1); + y += rotation_text->get_h() + margin; + + + + + + + +//printf("Fuse360GUI::create_objects %d %f\n", __LINE__, client->config.distance); + + + add_tool(draw_guides = new Fuse360Toggle(client, + &client->config.draw_guides, + x, + y, + _("Draw guides"))); + y += draw_guides->get_h() + margin; + + + add_tool(title = new BC_Title(x, y, _("Mode:"))); + add_tool(mode = new Fuse360Mode(client, + this, + x + title->get_w() + margin, + y)); + mode->create_objects(); + y += mode->get_h() + margin; + + + + show_window(); + flush(); +} + + + + + + + +Fuse360Main::Fuse360Main(PluginServer *server) + : PluginVClient(server) +{ + engine = 0; + affine = 0; +} + +Fuse360Main::~Fuse360Main() +{ + delete engine; + delete affine; +} + +NEW_WINDOW_MACRO(Fuse360Main, Fuse360GUI) +LOAD_CONFIGURATION_MACRO(Fuse360Main, Fuse360Config) +int Fuse360Main::is_realtime() { return 1; } +const char* Fuse360Main::plugin_title() { return N_("360 Fuser"); } + +void Fuse360Main::update_gui() +{ + if(thread) + { + if(load_configuration()) + { + ((Fuse360GUI*)thread->window)->lock_window("Fuse360Main::update_gui"); +// ((Fuse360GUI*)thread->window)->fov_slider->update(config.fov); +// ((Fuse360GUI*)thread->window)->fov_text->update(config.fov); + ((Fuse360GUI*)thread->window)->radiusx_slider->update(config.radius_x); + ((Fuse360GUI*)thread->window)->radiusx_text->update(config.radius_x); + ((Fuse360GUI*)thread->window)->radiusy_slider->update(config.radius_y); + ((Fuse360GUI*)thread->window)->radiusy_text->update(config.radius_y); +// ((Fuse360GUI*)thread->window)->centerx_slider->update(config.center_x); +// ((Fuse360GUI*)thread->window)->centerx_text->update(config.center_x); +// ((Fuse360GUI*)thread->window)->centery_slider->update(config.center_y); +// ((Fuse360GUI*)thread->window)->centery_text->update(config.center_y); + ((Fuse360GUI*)thread->window)->distancex_slider->update(config.distance_x); + ((Fuse360GUI*)thread->window)->distancex_text->update(config.distance_x); + ((Fuse360GUI*)thread->window)->distancey_slider->update(config.distance_y); + ((Fuse360GUI*)thread->window)->distancey_text->update(config.distance_y); + ((Fuse360GUI*)thread->window)->translatex_slider->update(config.translate_x); + ((Fuse360GUI*)thread->window)->translatex_text->update(config.translate_x); + ((Fuse360GUI*)thread->window)->feather_slider->update(config.feather); + ((Fuse360GUI*)thread->window)->feather_text->update(config.feather); + ((Fuse360GUI*)thread->window)->rotation_slider->update(config.rotation); + ((Fuse360GUI*)thread->window)->rotation_text->update(config.rotation); + ((Fuse360GUI*)thread->window)->mode->update(config.mode); + ((Fuse360GUI*)thread->window)->draw_guides->update(config.draw_guides); + ((Fuse360GUI*)thread->window)->unlock_window(); + } + } +} + + +void Fuse360Main::save_data(KeyFrame *keyframe) +{ + FileXML output; + char string[BCTEXTLEN]; + + + +// cause data to be stored directly in text + output.set_shared_string(keyframe->get_data(), MESSAGESIZE); + output.tag.set_title("360FUSER"); + output.tag.set_property("FOCAL_LENGTH", config.fov); + output.tag.set_property("RADIUS_X", config.radius_x); + output.tag.set_property("RADIUS_Y", config.radius_y); + output.tag.set_property("FEATHER", config.feather); + output.tag.set_property("CENTER_X", config.center_x); + output.tag.set_property("CENTER_Y", config.center_y); + output.tag.set_property("DISTANCE_X", config.distance_x); + output.tag.set_property("DISTANCE_Y", config.distance_y); + output.tag.set_property("TRANSLATE_X", config.translate_x); + output.tag.set_property("ROTATION", config.rotation); + output.tag.set_property("DRAW_GUIDES", config.draw_guides); + output.tag.set_property("MODE", config.mode); + output.append_tag(); + output.terminate_string(); + +} + + +void Fuse360Main::read_data(KeyFrame *keyframe) +{ + FileXML input; + char string[BCTEXTLEN]; + + + input.set_shared_string(keyframe->get_data(), strlen(keyframe->get_data())); + + int result = 0; + + while(!result) + { + result = input.read_tag(); + + if(!result) + { + if(input.tag.title_is("360FUSER")) + { + config.fov = input.tag.get_property("FOCAL_LENGTH", config.fov); + config.radius_x = input.tag.get_property("RADIUS_X", config.radius_x); + config.radius_y = input.tag.get_property("RADIUS_Y", config.radius_y); + config.feather = input.tag.get_property("FEATHER", config.feather); + config.center_x = input.tag.get_property("CENTER_X", config.center_x); + config.center_y = input.tag.get_property("CENTER_Y", config.center_y); + config.distance_x = input.tag.get_property("DISTANCE_X", config.distance_x); + config.distance_y = input.tag.get_property("DISTANCE_Y", config.distance_y); + config.translate_x = input.tag.get_property("TRANSLATE_X", config.translate_x); + config.rotation = input.tag.get_property("ROTATION", config.rotation); + config.draw_guides = input.tag.get_property("DRAW_GUIDES", config.draw_guides); + config.mode = input.tag.get_property("MODE", config.mode); + } + } + } +} + + + +int Fuse360Main::process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate) +{ + load_configuration(); + + VFrame *input = new_temp(frame->get_w(), frame->get_h(), frame->get_color_model()); + + read_frame(input, + 0, + start_position, + frame_rate, + 0); // use opengl + + calculate_extents(); + +// always rotate it + if(!EQUIV(config.rotation, 0)) + { + int center_x = w / 2; + int center_y = h / 2; + int center_x1 = w / 4; + int center_y1 = h / 2; + int center_x2 = w * 3 / 4; + int center_y2 = h / 2; + int radius_x = 0; + int radius_y = 0; + + radius_x = config.radius_x * w / 2; + radius_y = config.radius_y * h; + + if(!affine) affine = new AffineEngine(PluginClient::smp + 1, + PluginClient::smp + 1); + affine->set_in_pivot(center_x1, center_y1); + affine->set_in_viewport(0, 0, center_x, h); + affine->set_out_viewport(0, 0, center_x, h); + affine->rotate(get_output(), + input, + config.rotation); + + affine->set_in_pivot(center_x2, center_y2); + affine->set_in_viewport(center_x, 0, w - center_x, h); + affine->set_out_viewport(center_x, 0, w - center_x, h); + affine->rotate(get_output(), + input, + -config.rotation); + + input->copy_from(get_output()); + get_output()->clear_frame(); + + } + + if(config.mode == Fuse360Config::DO_NOTHING) + { + get_output()->copy_from(input); + } + else + { + + if(!engine) engine = new Fuse360Engine(this); + engine->process_packages(); + } + + + + if(config.draw_guides) + { + + get_output()->draw_line(center_x, 0, center_x, h); + +// draw lenses + get_output()->draw_oval(center_x1 - radius_x + distance_x, + center_y1 - radius_y + distance_y, + center_x1 + radius_x + distance_x, + center_y1 + radius_y + distance_y); + get_output()->draw_oval(center_x2 - radius_x - distance_x, + center_y2 - radius_y - distance_y, + center_x2 + radius_x - distance_x, + center_y2 + radius_y - distance_y); + +// draw feather + get_output()->draw_line(feather_x1, 0, feather_x1, h); + get_output()->draw_line(feather_x2, 0, feather_x2, h); + + + } + + return 0; +} + + +void Fuse360Main::calculate_extents() +{ + w = get_output()->get_w(); + h = get_output()->get_h(); + center_x = w / 2; + center_y = h / 2; + center_x1 = w * 1 / 4; + center_y1 = h / 2; + center_x2 = w * 3 / 4; + center_y2 = h / 2; + radius_x = 0; + radius_y = 0; + distance_x = (int)((50 - config.distance_x) * w / 100 / 2); + distance_y = (int)(config.distance_y * h / 100 / 2); + feather = (int)(config.feather * w / 100); + feather_x1 = center_x - (int)(config.feather * w / 100 / 2); + feather_x2 = center_x + (int)(config.feather * w / 100 / 2); + radius_x = config.radius_x * w / 2; + radius_y = config.radius_y * h; +//printf("Fuse360Main::calculate_extents %d radius_y=%d\n", __LINE__, radius_y); +} + + + + + +Fuse360Package::Fuse360Package() + : LoadPackage() {} + + + + + +Fuse360Unit::Fuse360Unit(Fuse360Engine *engine, Fuse360Main *plugin) + : LoadClient(engine) +{ + this->plugin = plugin; +} + + +Fuse360Unit::~Fuse360Unit() +{ +} + + + +void Fuse360Unit::process_blend(Fuse360Package *pkg) +{ + VFrame *input = plugin->get_temp(); + VFrame *output = plugin->get_output(); + + int row1 = pkg->row1; + int row2 = pkg->row2; + int width = input->get_w(); + int height = input->get_h(); + +#define PROCESS_BLEND(type, components, chroma) \ +{ \ + type **in_rows = (type**)input->get_rows(); \ + type **out_rows = (type**)output->get_rows(); \ + type black[4] = { 0, chroma, chroma, 0 }; \ + \ + for(int y = row1; y < row2; y++) \ + { \ + type *out_row = out_rows[y]; \ + type *in_row = in_rows[y]; \ + \ + for(int x = 0; x < width; x++) \ + { \ + } \ + } \ +} + + + switch(plugin->get_input()->get_color_model()) + { + case BC_RGB888: + PROCESS_BLEND(unsigned char, 3, 0x0); + break; + case BC_RGBA8888: + PROCESS_BLEND(unsigned char, 4, 0x0); + break; + case BC_RGB_FLOAT: + PROCESS_BLEND(float, 3, 0.0); + break; + case BC_RGBA_FLOAT: + PROCESS_BLEND(float, 4, 0.0); + break; + case BC_YUV888: + PROCESS_BLEND(unsigned char, 3, 0x80); + break; + case BC_YUVA8888: + PROCESS_BLEND(unsigned char, 4, 0x80); + break; + } + +} + +// interpolate 1 eye +#define BLEND_PIXEL(type, components) \ + if(x_in < 0.0 || x_in >= w - 1 || \ + y_in < 0.0 || y_in >= h - 1) \ + { \ + *out_row++ = black[0]; \ + *out_row++ = black[1]; \ + *out_row++ = black[2]; \ + if(components == 4) *out_row++ = black[3]; \ + } \ + else \ + { \ + float y1_fraction = y_in - floor(y_in); \ + float y2_fraction = 1.0 - y1_fraction; \ + float x1_fraction = x_in - floor(x_in); \ + float x2_fraction = 1.0 - x1_fraction; \ + type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \ + type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \ + for(int i = 0; i < components; i++) \ + { \ + *out_row++ = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \ + in_pixel2[i] * x2_fraction * y1_fraction + \ + in_pixel1[i + components] * x1_fraction * y2_fraction + \ + in_pixel2[i + components] * x1_fraction * y1_fraction); \ + } \ + } + + +// interpolate 2 eyes +#define BLEND_PIXEL2(type, components) \ + type pixel1[components], pixel2[components]; \ + \ +/* calculate the left eye */ \ + if(x_in1 < 0.0 || x_in1 >= w - 1 || \ + y_in1 < 0.0 || y_in1 >= h - 1) \ + { \ + pixel1[0] = black[0]; \ + pixel1[1] = black[1]; \ + pixel1[2] = black[2]; \ + if(components == 4) pixel1[3] = black[3]; \ + } \ + else \ + { \ + float y1_fraction = y_in1 - floor(y_in1); \ + float y2_fraction = 1.0 - y1_fraction; \ + float x1_fraction = x_in1 - floor(x_in1); \ + float x2_fraction = 1.0 - x1_fraction; \ + type *in_pixel1 = in_rows[(int)y_in1] + (int)x_in1 * components; \ + type *in_pixel2 = in_rows[(int)y_in1 + 1] + (int)x_in1 * components; \ + for(int i = 0; i < components; i++) \ + { \ + pixel1[i] = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \ + in_pixel2[i] * x2_fraction * y1_fraction + \ + in_pixel1[i + components] * x1_fraction * y2_fraction + \ + in_pixel2[i + components] * x1_fraction * y1_fraction); \ + } \ + } \ + \ + \ +/* calculate the right eye */ \ + if(x_in2 < 0.0 || x_in2 >= w - 1 || \ + y_in2 < 0.0 || y_in2 >= h - 1) \ + { \ + pixel2[0] = black[0]; \ + pixel2[1] = black[1]; \ + pixel2[2] = black[2]; \ + if(components == 4) pixel2[3] = black[3]; \ + } \ + else \ + { \ + float y1_fraction = y_in2 - floor(y_in2); \ + float y2_fraction = 1.0 - y1_fraction; \ + float x1_fraction = x_in2 - floor(x_in2); \ + float x2_fraction = 1.0 - x1_fraction; \ + type *in_pixel1 = in_rows[(int)y_in2] + (int)x_in2 * components; \ + type *in_pixel2 = in_rows[(int)y_in2 + 1] + (int)x_in2 * components; \ + for(int i = 0; i < components; i++) \ + { \ + pixel2[i] = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \ + in_pixel2[i] * x2_fraction * y1_fraction + \ + in_pixel1[i + components] * x1_fraction * y2_fraction + \ + in_pixel2[i + components] * x1_fraction * y1_fraction); \ + } \ + } \ + \ +/* blend the 2 eyes */ \ + for(int i = 0; i < components; i++) \ + { \ + *out_row++ = (type)(pixel1[i] * (1.0f - fraction) + \ + pixel2[i] * fraction); \ + } \ + + + + +#define COLORSPACE_SWITCH(function) \ + switch(plugin->get_input()->get_color_model()) \ + { \ + case BC_RGB888: \ + function(unsigned char, 3, 0x0); \ + break; \ + case BC_RGBA8888: \ + function(unsigned char, 4, 0x0); \ + break; \ + case BC_RGB_FLOAT: \ + function(float, 3, 0.0); \ + break; \ + case BC_RGBA_FLOAT: \ + function(float, 4, 0.0); \ + break; \ + case BC_YUV888: \ + function(unsigned char, 3, 0x80); \ + break; \ + case BC_YUVA8888: \ + function(unsigned char, 4, 0x80); \ + break; \ + } + + +double Fuse360Unit::calculate_max_z(double a, double r) +{ + if(a < 0) a += 2 * M_PI; + + if(a < M_PI / 4) + { + return r / cos(a); // bottom right edge + } + else + if(a < 3 * M_PI / 4) + { + return r / cos(M_PI / 2 - a); // bottom edge + } + else + if(a < 5 * M_PI / 4) + { + return r / cos(M_PI - a); // left edge + } + else + if(a < 7 * M_PI / 4) + { + return r / cos(3 * M_PI / 2 - a); // top edge + } + else + { + return r / cos(a); // top right edge + } +} + +void Fuse360Unit::process_stretch(Fuse360Package *pkg) +{ + VFrame *input = plugin->get_temp(); + VFrame *output = plugin->get_output(); + + float fov = plugin->config.fov; + int row1 = pkg->row1; + int row2 = pkg->row2; + int center_x1 = plugin->center_x1; + int center_x2 = plugin->center_x2; + int center_y1 = plugin->center_y1; + int center_y2 = plugin->center_y2; + int center_x = plugin->center_x; + int center_y = plugin->center_y; + int w = plugin->w; + int h = plugin->h; + double radius = plugin->radius_x; + + +#define PROCESS_STRETCH(type, components, chroma) \ +{ \ + type **in_rows = (type**)input->get_rows(); \ + type **out_rows = (type**)output->get_rows(); \ + type black[4] = { 0, chroma, chroma, 0 }; \ + \ + for(int y = row1; y < row2; y++) \ + { \ + type *out_row = out_rows[y]; \ + type *in_row = in_rows[y]; \ + double y_diff = y - center_y1; \ + \ +/* left eye */ \ + for(int x = 0; x < center_x; x++) \ + { \ + double x_diff = x - center_x1; \ +/* polar output coordinate */ \ + double z = hypot(x_diff, y_diff); \ + double a = atan2(y_diff, x_diff); \ + \ +/* scale the magnitude to the radius */ \ + double scaled_z = z * radius / calculate_max_z(a, radius); \ +/* xy input coordinate */ \ + double x_in = scaled_z * cos(a) + center_x1; \ + double y_in = scaled_z * sin(a) + center_y1; \ + \ + if(x_in < center_x) \ + { \ + BLEND_PIXEL(type, components) \ + } \ + } \ + } \ + \ + for(int y = row1; y < row2; y++) \ + { \ + type *out_row = out_rows[y] + center_x * components; \ + type *in_row = in_rows[y]; \ + double y_diff = y - center_y2; \ + \ +/* right eye */ \ + for(int x = center_x; x < w; x++) \ + { \ + double x_diff = x - center_x2; \ +/* polar output coordinate */ \ + double z = hypot(x_diff, y_diff); \ + double a = atan2(y_diff, x_diff); \ + \ +/* scale the magnitude to the radius */ \ + double scaled_z = z * radius / calculate_max_z(a, radius); \ +/* xy input coordinate */ \ + double x_in = scaled_z * cos(a) + center_x2; \ + double y_in = scaled_z * sin(a) + center_y2; \ + \ + if(x_in >= center_x) \ + { \ + BLEND_PIXEL(type, components) \ + } \ + } \ + } \ +} + + + + COLORSPACE_SWITCH(PROCESS_STRETCH) +} + + + + + +void Fuse360Unit::process_standard(Fuse360Package *pkg) +{ + VFrame *input = plugin->get_temp(); + VFrame *output = plugin->get_output(); + + float fov = plugin->config.fov; + int row1 = pkg->row1; + int row2 = pkg->row2; + int center_x1 = plugin->center_x1; + int center_x2 = plugin->center_x2; + int center_y1 = plugin->center_y1; + int center_y2 = plugin->center_y2; + int center_x = plugin->center_x; + int center_y = plugin->center_y; + int feather = plugin->feather; + int feather_x1 = plugin->feather_x1; + int feather_x2 = plugin->feather_x2; + int w = plugin->w; + int h = plugin->h; + float radius_x = plugin->radius_x; + float radius_y = plugin->radius_y; + int distance_x = plugin->distance_x; + int distance_y = plugin->distance_y; +// field of view of the fisheye + float FOV = M_PI; + +#define PROCESS_STANDARD(type, components, chroma) \ +{ \ + type **in_rows = (type**)input->get_rows(); \ + type **out_rows = (type**)output->get_rows(); \ + type black[4] = { 0, chroma, chroma, 0 }; \ + \ +/* left eye */ \ + for(int y = row1; y < row2; y++) \ + { \ + type *out_row = out_rows[y]; \ + \ +/* -M_PI/2 to M_PI/2 */ \ + float y_diff = y - center_y1; \ +/* polar angles */ \ + float phi = M_PI / 2 * (y_diff / radius_y); \ + for(int x = 0; x < feather_x1; x++) \ + { \ + float x_diff = x - center_x1; \ +/* polar angles */ \ +/* -M_PI/2 to M_PI/2 */ \ + float theta = M_PI / 2 * (x_diff / radius_x); \ +/* vector in 3D space */ \ + float vect_x = cos(phi) * sin(theta); \ + float vect_y = cos(phi) * cos(theta); \ + float vect_z = sin(phi); \ +/* fisheye angle & radius */ \ + float theta2 = atan2(vect_z, vect_x); \ + float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \ + float r = radius_x * 2 * phi2 / FOV; \ +/* pixel in fisheye space */ \ + float x_in = center_x1 + r * cos(theta2); \ + float y_in = center_y1 + r * sin(theta2); \ + \ + BLEND_PIXEL(type, components) \ + } \ + } \ + \ + \ + \ +/* right eye */ \ + for(int y = row1; y < row2; y++) \ + { \ + type *out_row = out_rows[y] + components * feather_x2; \ + \ +/* -M_PI/2 to M_PI/2 */ \ + float y_diff = y - center_y2; \ +/* polar angles */ \ + float phi = M_PI / 2 * (y_diff / radius_y); \ + for(int x = feather_x2; x < w; x++) \ + { \ + float x_diff = x - center_x2; \ +/* polar angles */ \ +/* -M_PI/2 to M_PI/2 */ \ + float theta = M_PI / 2 * (x_diff / radius_x); \ +/* vector in 3D space */ \ + float vect_x = cos(phi) * sin(theta); \ + float vect_y = cos(phi) * cos(theta); \ + float vect_z = sin(phi); \ +/* fisheye angle & radius */ \ + float theta2 = atan2(vect_z, vect_x); \ + float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \ + float r = radius_x * 2 * phi2 / FOV; \ +/* pixel in fisheye space */ \ + float x_in = center_x2 + r * cos(theta2); \ + float y_in = center_y2 + r * sin(theta2); \ + \ + BLEND_PIXEL(type, components) \ + } \ + } \ + \ + \ +} + + COLORSPACE_SWITCH(PROCESS_STANDARD) +} + + + +void Fuse360Unit::process_package(LoadPackage *package) +{ + Fuse360Package *pkg = (Fuse360Package*)package; + + switch(plugin->config.mode) + { + case Fuse360Config::STRETCHXY: + process_stretch(pkg); + break; + case Fuse360Config::STANDARD: + process_standard(pkg); + break; + case Fuse360Config::BLEND: + process_blend(pkg); + break; + } +} + + + + + +Fuse360Engine::Fuse360Engine(Fuse360Main *plugin) +// : LoadServer(plugin->PluginClient::smp + 1, plugin->PluginClient::smp + 1) + : LoadServer(1, 1) +{ + this->plugin = plugin; +} + +Fuse360Engine::~Fuse360Engine() +{ +} + +void Fuse360Engine::init_packages() +{ + for(int i = 0; i < LoadServer::get_total_packages(); i++) + { + Fuse360Package *package = (Fuse360Package*)LoadServer::get_package(i); + package->row1 = plugin->get_input()->get_h() * i / LoadServer::get_total_packages(); + package->row2 = plugin->get_input()->get_h() * (i + 1) / LoadServer::get_total_packages(); + } +} + +LoadClient* Fuse360Engine::new_client() +{ + return new Fuse360Unit(this, plugin); +} + +LoadPackage* Fuse360Engine::new_package() +{ + return new Fuse360Package; +} + + diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.h b/cinelerra-5.1/plugins/spherecam/spherecam.h new file mode 100644 index 00000000..cbc6ad25 --- /dev/null +++ b/cinelerra-5.1/plugins/spherecam/spherecam.h @@ -0,0 +1,273 @@ + +/* + * CINELERRA + * Copyright (C) 2017 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef FUSE360_H +#define FUSE360_H + + +#include "affine.inc" +#include "bchash.inc" +#include "guicast.h" +#include "loadbalance.h" +#include "pluginvclient.h" +#include "thread.h" + + +class SphereCamEngine; +class SphereCamGUI; +class SphereCamMain; +class SphereCamText; + +#define EYES 2 + +class SphereCamSlider : public BC_FSlider +{ +public: + SphereCamSlider(SphereCamMain *client, + SphereCamGUI *gui, + SphereCamText *text, + float *output, + int x, + int y, + float min, + float max); + int handle_event(); + + SphereCamGUI *gui; + SphereCamMain *client; + SphereCamText *text; + float *output; +}; + +class SphereCamText : public BC_TextBox +{ +public: + SphereCamText(SphereCamMain *client, + SphereCamGUI *gui, + SphereCamSlider *slider, + float *output, + int x, + int y); + int handle_event(); + + SphereCamGUI *gui; + SphereCamMain *client; + SphereCamSlider *slider; + float *output; +}; + + +class SphereCamToggle : public BC_CheckBox +{ +public: + SphereCamToggle(SphereCamMain *client, + int *output, + int x, + int y, + const char *text); + int handle_event(); + + SphereCamMain *client; + int *output; +}; + + +class SphereCamMode : public BC_PopupMenu +{ +public: + SphereCamMode(SphereCamMain *plugin, + SphereCamGUI *gui, + int x, + int y); + int handle_event(); + void create_objects(); + static int calculate_w(SphereCamGUI *gui); + static int from_text(char *text); + static const char* to_text(int mode); + void update(int mode); + SphereCamMain *plugin; + SphereCamGUI *gui; +}; + + +class SphereCamGUI : public PluginClientWindow +{ +public: + SphereCamGUI(SphereCamMain *client); + ~SphereCamGUI(); + + void create_objects(); + + SphereCamMain *client; + SphereCamToggle *enabled[EYES]; + SphereCamSlider *fov_slider[EYES]; + SphereCamText *fov_text[EYES]; + SphereCamSlider *radius_slider[EYES]; + SphereCamText *radius_text[EYES]; + SphereCamSlider *centerx_slider[EYES]; + SphereCamText *centerx_text[EYES]; + SphereCamSlider *centery_slider[EYES]; + SphereCamText *centery_text[EYES]; + SphereCamSlider *rotatex_slider[EYES]; + SphereCamText *rotatex_text[EYES]; + SphereCamSlider *rotatey_slider[EYES]; + SphereCamText *rotatey_text[EYES]; + SphereCamSlider *rotatez_slider[EYES]; + SphereCamText *rotatez_text[EYES]; + SphereCamSlider *feather_slider; + SphereCamText *feather_text; + + SphereCamMode *mode; + SphereCamToggle *draw_guides; +}; + +class SphereCamConfig +{ +public: + SphereCamConfig(); + int equivalent(SphereCamConfig &that); + void copy_from(SphereCamConfig &that); + void interpolate(SphereCamConfig &prev, + SphereCamConfig &next, + int64_t prev_frame, + int64_t next_frame, + int64_t current_frame); + void boundaries(); + + + int enabled[EYES]; +// degrees 1-359 + float fov[EYES]; +// radius of each eye 1-150 + float radius[EYES]; +// center of 2 eyes 0-100 + float center_x[EYES]; + float center_y[EYES]; +// rotation 0-359 + float rotate_x[EYES]; + float rotate_y[EYES]; + float rotate_z[EYES]; +// amount to feather eye edges 0-50 + float feather; + int draw_guides; + int mode; + enum + { +// draw guides only + DO_NOTHING, +// the standard algorithm + EQUIRECT, +// alignment only + ALIGN, + }; +}; + + + + + +class SphereCamPackage : public LoadPackage +{ +public: + SphereCamPackage(); + int row1, row2; +}; + + +class SphereCamUnit : public LoadClient +{ +public: + SphereCamUnit(SphereCamEngine *engine, SphereCamMain *plugin); + ~SphereCamUnit(); + + + void process_package(LoadPackage *package); + void process_equirect(SphereCamPackage *pkg); + void process_align(SphereCamPackage *pkg); + double calculate_max_z(double a, double r); + + + SphereCamEngine *engine; + SphereCamMain *plugin; +}; + +class SphereCamEngine : public LoadServer +{ +public: + SphereCamEngine(SphereCamMain *plugin); + ~SphereCamEngine(); + + void init_packages(); + LoadClient* new_client(); + LoadPackage* new_package(); + + SphereCamMain *plugin; +}; + +class SphereCamMain : public PluginVClient +{ +public: + SphereCamMain(PluginServer *server); + ~SphereCamMain(); + + PLUGIN_CLASS_MEMBERS2(SphereCamConfig) + int process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate); + void draw_feather(int left, int right, int eye, int y); + int is_realtime(); + void update_gui(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + void calculate_extents(); + double calculate_max_z(double a, int r); + +// config values converted to pixels + int w; + int h; + +// the center of the output regions, shifted by the rotations + int output_x[EYES]; + int output_y[EYES]; +// The output of each eye is split into 2 halves so it can wrap around + int out_x1[EYES]; + int out_y1[EYES]; + int out_x2[EYES]; + int out_y2[EYES]; + int out_x3[EYES]; + int out_y3[EYES]; + int out_x4[EYES]; + int out_y4[EYES]; +// the center of the input regions + int input_x[EYES]; + int input_y[EYES]; +// radius of the input regions for drawing the guide only + int radius[EYES]; +// pixels to add to the output regions + int feather; + + SphereCamEngine *engine; + AffineEngine *affine; +}; + + + +#endif diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.h.bak b/cinelerra-5.1/plugins/spherecam/spherecam.h.bak new file mode 100644 index 00000000..b3619c16 --- /dev/null +++ b/cinelerra-5.1/plugins/spherecam/spherecam.h.bak @@ -0,0 +1,272 @@ + +/* + * CINELERRA + * Copyright (C) 2017 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef FUSE360_H +#define FUSE360_H + + +#include "affine.inc" +#include "bchash.inc" +#include "guicast.h" +#include "loadbalance.h" +#include "pluginvclient.h" +#include "thread.h" + + +class Fuse360Engine; +class Fuse360GUI; +class Fuse360Main; +class Fuse360Text; + + +class Fuse360Slider : public BC_FSlider +{ +public: + Fuse360Slider(Fuse360Main *client, + Fuse360GUI *gui, + Fuse360Text *text, + float *output, + int x, + int y, + float min, + float max); + int handle_event(); + + Fuse360GUI *gui; + Fuse360Main *client; + Fuse360Text *text; + float *output; +}; + +class Fuse360Text : public BC_TextBox +{ +public: + Fuse360Text(Fuse360Main *client, + Fuse360GUI *gui, + Fuse360Slider *slider, + float *output, + int x, + int y); + int handle_event(); + + Fuse360GUI *gui; + Fuse360Main *client; + Fuse360Slider *slider; + float *output; +}; + + +class Fuse360Toggle : public BC_CheckBox +{ +public: + Fuse360Toggle(Fuse360Main *client, + int *output, + int x, + int y, + const char *text); + int handle_event(); + + Fuse360Main *client; + int *output; +}; + + +class Fuse360Mode : public BC_PopupMenu +{ +public: + Fuse360Mode(Fuse360Main *plugin, + Fuse360GUI *gui, + int x, + int y); + int handle_event(); + void create_objects(); + static int calculate_w(Fuse360GUI *gui); + static int from_text(char *text); + static const char* to_text(int mode); + void update(int mode); + Fuse360Main *plugin; + Fuse360GUI *gui; +}; + + +class Fuse360GUI : public PluginClientWindow +{ +public: + Fuse360GUI(Fuse360Main *client); + ~Fuse360GUI(); + + void create_objects(); + + Fuse360Main *client; +// Fuse360Slider *fov_slider; +// Fuse360Text *fov_text; + Fuse360Slider *radiusx_slider; + Fuse360Text *radiusx_text; + Fuse360Slider *radiusy_slider; + Fuse360Text *radiusy_text; +// Fuse360Slider *centerx_slider; +// Fuse360Text *centerx_text; +// Fuse360Slider *centery_slider; +// Fuse360Text *centery_text; + Fuse360Slider *distancex_slider; + Fuse360Text *distancex_text; + Fuse360Slider *distancey_slider; + Fuse360Text *distancey_text; + Fuse360Slider *translatex_slider; + Fuse360Text *translatex_text; + Fuse360Slider *feather_slider; + Fuse360Text *feather_text; + Fuse360Slider *rotation_slider; + Fuse360Text *rotation_text; + + Fuse360Mode *mode; + Fuse360Toggle *draw_guides; +}; + +class Fuse360Config +{ +public: + Fuse360Config(); + int equivalent(Fuse360Config &that); + void copy_from(Fuse360Config &that); + void interpolate(Fuse360Config &prev, + Fuse360Config &next, + int64_t prev_frame, + int64_t next_frame, + int64_t current_frame); + void boundaries(); + + + + float fov; +// radius of each eye + float radius_x; + float radius_y; +// amount to feather eye edges + float feather; +// center of 2 eyes + float center_x; + float center_y; +// X distance between 2 eyes + float distance_x; +// Y offset between 2 eyes + float distance_y; +// translate output position + float translate_x; + float rotation; + int draw_guides; + int mode; + enum + { +// align guides only + DO_NOTHING, +// rectilinear + STRETCHXY, +// the standard blend + STANDARD, +// don't stretch eyes + BLEND + }; +}; + + + + + +class Fuse360Package : public LoadPackage +{ +public: + Fuse360Package(); + int row1, row2; +}; + + +class Fuse360Unit : public LoadClient +{ +public: + Fuse360Unit(Fuse360Engine *engine, Fuse360Main *plugin); + ~Fuse360Unit(); + + + void process_package(LoadPackage *package); + void process_stretch(Fuse360Package *pkg); + void process_blend(Fuse360Package *pkg); + void process_standard(Fuse360Package *pkg); + double calculate_max_z(double a, double r); + + + Fuse360Engine *engine; + Fuse360Main *plugin; +}; + +class Fuse360Engine : public LoadServer +{ +public: + Fuse360Engine(Fuse360Main *plugin); + ~Fuse360Engine(); + + void init_packages(); + LoadClient* new_client(); + LoadPackage* new_package(); + + Fuse360Main *plugin; +}; + +class Fuse360Main : public PluginVClient +{ +public: + Fuse360Main(PluginServer *server); + ~Fuse360Main(); + + PLUGIN_CLASS_MEMBERS2(Fuse360Config) + int process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate); + int is_realtime(); + void update_gui(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + void calculate_extents(); + double calculate_max_z(double a, int r); + + int w; + int h; + int center_x; + int center_y; + int center_x1; + int center_y1; + int center_x2; + int center_y2; + int radius_x; + int radius_y; + int distance_x; + int distance_y; + int feather; + int feather_x1; + int feather_x2; + + Fuse360Engine *engine; + AffineEngine *affine; +}; + + + +#endif diff --git a/cinelerra-5.1/plugins/swapframes/swapframes.C b/cinelerra-5.1/plugins/swapframes/swapframes.C index 0b867393..8284b6fa 100644 --- a/cinelerra-5.1/plugins/swapframes/swapframes.C +++ b/cinelerra-5.1/plugins/swapframes/swapframes.C @@ -25,7 +25,7 @@ #include "filexml.h" #include "guicast.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "swapframes.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/threshold/histogramengine.C b/cinelerra-5.1/plugins/threshold/histogramengine.C index 412a28ef..e7c69ff0 100644 --- a/cinelerra-5.1/plugins/threshold/histogramengine.C +++ b/cinelerra-5.1/plugins/threshold/histogramengine.C @@ -20,7 +20,7 @@ */ #include "histogramengine.h" -#include "cicolors.h" +#include "bccolors.h" #include "vframe.h" #include diff --git a/cinelerra-5.1/plugins/threshold/histogramengine.h b/cinelerra-5.1/plugins/threshold/histogramengine.h index e2591c61..41603cb8 100644 --- a/cinelerra-5.1/plugins/threshold/histogramengine.h +++ b/cinelerra-5.1/plugins/threshold/histogramengine.h @@ -24,7 +24,7 @@ #include "histogramengine.inc" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "vframe.inc" #include diff --git a/cinelerra-5.1/plugins/threshold/threshold.C b/cinelerra-5.1/plugins/threshold/threshold.C index 8ad43baf..052ba252 100644 --- a/cinelerra-5.1/plugins/threshold/threshold.C +++ b/cinelerra-5.1/plugins/threshold/threshold.C @@ -27,7 +27,7 @@ #include "filexml.h" #include "histogramengine.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "threshold.h" #include "thresholdwindow.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/threshold/threshold.h b/cinelerra-5.1/plugins/threshold/threshold.h index 6083737c..0d8769f2 100644 --- a/cinelerra-5.1/plugins/threshold/threshold.h +++ b/cinelerra-5.1/plugins/threshold/threshold.h @@ -26,7 +26,7 @@ #include "histogramengine.inc" #include "loadbalance.h" #include "thresholdwindow.inc" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" diff --git a/cinelerra-5.1/plugins/timeavg/timeavg.C b/cinelerra-5.1/plugins/timeavg/timeavg.C index 1929a140..fa055c3f 100644 --- a/cinelerra-5.1/plugins/timeavg/timeavg.C +++ b/cinelerra-5.1/plugins/timeavg/timeavg.C @@ -24,7 +24,7 @@ #include "filexml.h" #include "keyframe.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "timeavg.h" #include "timeavgwindow.h" #include "transportque.h" diff --git a/cinelerra-5.1/plugins/timefront/timefront.h b/cinelerra-5.1/plugins/timefront/timefront.h index 2fb38d19..9eeb4ee2 100644 --- a/cinelerra-5.1/plugins/timefront/timefront.h +++ b/cinelerra-5.1/plugins/timefront/timefront.h @@ -34,7 +34,7 @@ class TimeFrontServer; #include "guicast.h" #include "loadbalance.h" #include "overlayframe.inc" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "thread.h" #include "vframe.inc" diff --git a/cinelerra-5.1/plugins/timestretchrt/timestretchrt.C b/cinelerra-5.1/plugins/timestretchrt/timestretchrt.C index 5023212e..89b7efa4 100644 --- a/cinelerra-5.1/plugins/timestretchrt/timestretchrt.C +++ b/cinelerra-5.1/plugins/timestretchrt/timestretchrt.C @@ -42,19 +42,26 @@ REGISTER_PLUGIN(TimeStretchRT); TimeStretchRTConfig::TimeStretchRTConfig() { - scale = 1; +// scale = 1; + num = 1; + denom = 1; size = 40; } int TimeStretchRTConfig::equivalent(TimeStretchRTConfig &src) { - return fabs(scale - src.scale) < 0.0001 && size == src.size; +// return fabs(scale - src.scale) < 0.0001 && size == src.size; + return fabs(num - src.num) < 0.0001 && + fabs(denom - src.denom) < 0.0001 && + size == src.size; } void TimeStretchRTConfig::copy_from(TimeStretchRTConfig &src) { - this->scale = src.scale; + this->num = src.num; + this->denom = src.denom; +// this->scale = src.scale; this->size = src.size; } @@ -64,15 +71,19 @@ void TimeStretchRTConfig::interpolate(TimeStretchRTConfig &prev, int64_t next_frame, int64_t current_frame) { - this->scale = prev.scale; + this->num = prev.num; + this->denom = prev.denom; +// this->scale = prev.scale; this->size = prev.size; boundaries(); } void TimeStretchRTConfig::boundaries() { - if(fabs(scale) < 0.01) scale = 0.01; - if(fabs(scale) > 100) scale = 100; + if(num < 0.0001) num = 0.0001; + if(denom < 0.0001) denom = 0.0001; +// if(fabs(scale) < 0.01) scale = 0.01; +// if(fabs(scale) > 100) scale = 100; if(size < 10) size = 10; if(size > 1000) size = 1000; } @@ -82,10 +93,10 @@ void TimeStretchRTConfig::boundaries() TimeStretchRTWindow::TimeStretchRTWindow(TimeStretchRT *plugin) : PluginClientWindow(plugin, + 210, + 200, + 200, 210, - 160, - 200, - 160, 0) { this->plugin = plugin; @@ -98,19 +109,31 @@ TimeStretchRTWindow::~TimeStretchRTWindow() void TimeStretchRTWindow::create_objects() { int x = 10, y = 10; + int margin = plugin->get_theme()->widget_border; BC_Title *title = 0; - add_subwindow(title = new BC_Title(x, y, _("Fraction of original speed:"))); + add_subwindow(title = new BC_Title(x, y, _("Input samples:"))); y += title->get_h() + plugin->get_theme()->widget_border; - scale = new TimeStretchRTScale(this, - plugin, - x, - y); - scale->create_objects(); - - y += scale->get_h() + plugin->get_theme()->widget_border; - add_subwindow(title = new BC_Title(x, y, _("Window size (ms):"))); + num = new TimeStretchRTScale(this, + plugin, + x, + y, + &plugin->config.num); + num->create_objects(); + y += num->get_h() + margin; + + add_subwindow(title = new BC_Title(x, y, _("Output samples:"))); y += title->get_h() + plugin->get_theme()->widget_border; + denom = new TimeStretchRTScale(this, + plugin, + x, + y, + &plugin->config.denom); + denom->create_objects(); + + y += denom->get_h() + margin; + add_subwindow(title = new BC_Title(x, y, _("Window size (ms):"))); + y += title->get_h() + margin; size = new TimeStretchRTSize(this, plugin, x, @@ -128,9 +151,10 @@ void TimeStretchRTWindow::create_objects() TimeStretchRTScale::TimeStretchRTScale(TimeStretchRTWindow *window, TimeStretchRT *plugin, int x, - int y) + int y, + double *value) : BC_TumbleTextBox(window, - (float)(1.0 / plugin->config.scale), + (float)*value, (float)0.0001, (float)1000, x, @@ -138,12 +162,14 @@ TimeStretchRTScale::TimeStretchRTScale(TimeStretchRTWindow *window, 100) { this->plugin = plugin; + this->value = value; set_increment(0.01); } int TimeStretchRTScale::handle_event() { - plugin->config.scale = 1.0 / atof(get_text()); + *value = atof(get_text()); + plugin->config.boundaries(); plugin->send_configure_change(); return 1; } @@ -213,7 +239,7 @@ int TimeStretchRT::process_buffer(int64_t size, { need_reconfigure = load_configuration(); - if(!engine) engine = new TimeStretchEngine(config.scale, + if(!engine) engine = new TimeStretchEngine(config.denom / config.num, sample_rate, config.size); @@ -222,7 +248,6 @@ int TimeStretchRT::process_buffer(int64_t size, // Get start position of the input. // Sample 0 is the keyframe position -//printf("TimeStretchRT::process_buffer %d %f\n", __LINE__, config.scale); if(need_reconfigure) { int64_t prev_position = edl_to_local( @@ -234,15 +259,18 @@ int TimeStretchRT::process_buffer(int64_t size, prev_position = get_source_start(); } - source_start = (int64_t)((start_position - prev_position) / - config.scale) + prev_position; + source_start = (int64_t)((start_position - prev_position) * + config.num / config.denom) + prev_position; engine->reset(); - engine->update(config.scale, sample_rate, config.size); + engine->update(config.denom / config.num, sample_rate, config.size); need_reconfigure = 0; -//printf("TimeStretchRT::process_buffer %d start_position=" _LD -// " prev_position=%jd scale=%f source_start=%jd\n", -// __LINE__, start_position, prev_position, config.scale, source_start); +// printf("TimeStretchRT::process_buffer %d start_position=%lld prev_position=%lld scale=%f source_start=%lld\n", +// __LINE__, +// start_position, +// prev_position, +// config.scale, +// source_start); } // process buffers until output length is reached @@ -297,7 +325,8 @@ void TimeStretchRT::save_data(KeyFrame *keyframe) // cause data to be stored directly in text output.set_shared_output(keyframe->get_data(), MESSAGESIZE); output.tag.set_title("TIMESTRETCHRT"); - output.tag.set_property("SCALE", config.scale); + output.tag.set_property("NUM", config.num); + output.tag.set_property("DENOM", config.denom); output.tag.set_property("SIZE", config.size); output.append_tag(); output.tag.set_title("/TIMESTRETCHRT"); @@ -316,7 +345,8 @@ void TimeStretchRT::read_data(KeyFrame *keyframe) { if(input.tag.title_is("TIMESTRETCHRT")) { - config.scale = input.tag.get_property("SCALE", config.scale); + config.num = input.tag.get_property("NUM", config.num); + config.denom = input.tag.get_property("DENOM", config.denom); config.size = input.tag.get_property("SIZE", config.size); } } @@ -330,7 +360,8 @@ void TimeStretchRT::update_gui() { thread->window->lock_window("TimeStretchRT::update_gui"); - ((TimeStretchRTWindow*)thread->window)->scale->update((float)(1.0 / config.scale)); + ((TimeStretchRTWindow*)thread->window)->num->update((float)config.num); + ((TimeStretchRTWindow*)thread->window)->denom->update((float)config.denom); ((TimeStretchRTWindow*)thread->window)->size->update((int64_t)config.size); thread->window->unlock_window(); } diff --git a/cinelerra-5.1/plugins/timestretchrt/timestretchrt.h b/cinelerra-5.1/plugins/timestretchrt/timestretchrt.h index 652e4a11..6e0be35c 100644 --- a/cinelerra-5.1/plugins/timestretchrt/timestretchrt.h +++ b/cinelerra-5.1/plugins/timestretchrt/timestretchrt.h @@ -45,7 +45,9 @@ public: int64_t prev_frame, int64_t next_frame, int64_t current_frame); - double scale; +// double scale; + double num; + double denom; int size; }; @@ -56,9 +58,11 @@ public: TimeStretchRTScale(TimeStretchRTWindow *window, TimeStretchRT *plugin, int x, - int y); + int y, + double *value); int handle_event(); TimeStretchRT *plugin; + double *value; }; @@ -80,7 +84,8 @@ public: void create_objects(); TimeStretchRT *plugin; - TimeStretchRTScale *scale; + TimeStretchRTScale *num; + TimeStretchRTScale *denom; TimeStretchRTSize *size; }; diff --git a/cinelerra-5.1/plugins/videoscope/videoscope.C b/cinelerra-5.1/plugins/videoscope/videoscope.C index a420acf2..0fbae88f 100644 --- a/cinelerra-5.1/plugins/videoscope/videoscope.C +++ b/cinelerra-5.1/plugins/videoscope/videoscope.C @@ -26,7 +26,7 @@ #include "guicast.h" #include "language.h" #include "loadbalance.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "fonts.h" #include "scopewindow.h" diff --git a/cinelerra-5.1/plugins/yuv/yuv.C b/cinelerra-5.1/plugins/yuv/yuv.C index 28d9fc2a..18846756 100644 --- a/cinelerra-5.1/plugins/yuv/yuv.C +++ b/cinelerra-5.1/plugins/yuv/yuv.C @@ -25,7 +25,7 @@ #include "filexml.h" #include "guicast.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "vframe.h" diff --git a/cinelerra-5.1/plugins/yuv/yuv.h b/cinelerra-5.1/plugins/yuv/yuv.h index 6f877c48..b1e07d36 100644 --- a/cinelerra-5.1/plugins/yuv/yuv.h +++ b/cinelerra-5.1/plugins/yuv/yuv.h @@ -28,7 +28,7 @@ class YUVMain; class YUVEngine; #include "bcbase.h" -#include "colors.h" +#include "bccolors.h" #include "yuvwindow.h" #include "pluginvclient.h" diff --git a/cinelerra-5.1/plugins/yuv411/yuv411win.h b/cinelerra-5.1/plugins/yuv411/yuv411win.h index 393fc11b..a08eeffe 100644 --- a/cinelerra-5.1/plugins/yuv411/yuv411win.h +++ b/cinelerra-5.1/plugins/yuv411/yuv411win.h @@ -6,7 +6,7 @@ #include "mutex.h" #include "pluginvclient.h" #include "bctitle.h" -#include "colors.h" +#include "bccolors.h" #include "fonts.h" class yuv411Toggle; diff --git a/cinelerra-5.1/plugins/yuvshift/yuvshift.C b/cinelerra-5.1/plugins/yuvshift/yuvshift.C index 2b814c03..e16364a2 100644 --- a/cinelerra-5.1/plugins/yuvshift/yuvshift.C +++ b/cinelerra-5.1/plugins/yuvshift/yuvshift.C @@ -25,7 +25,7 @@ #include "filexml.h" #include "guicast.h" #include "language.h" -#include "cicolors.h" +#include "bccolors.h" #include "pluginvclient.h" #include "vframe.h" diff --git a/cinelerra-5.1/thirdparty/src/libXft-2.3.2.patch1 b/cinelerra-5.1/thirdparty/src/libXft-2.3.2.patch1 new file mode 100644 index 00000000..79cf7272 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/libXft-2.3.2.patch1 @@ -0,0 +1,61 @@ +diff -ur libXft-2.3.2.orig/src/xftdpy.c libXft-2.3.2/src/xftdpy.c +--- libXft-2.3.2.orig/src/xftdpy.c 2014-06-06 00:05:07.000000000 -0600 ++++ libXft-2.3.2/src/xftdpy.c 2017-10-17 08:55:30.227746279 -0600 +@@ -22,6 +22,11 @@ + + #include "xftint.h" + ++#include ++static pthread_mutex_t info_mutex = PTHREAD_MUTEX_INITIALIZER; ++static inline void info_lock() { pthread_mutex_lock(&info_mutex); } ++static inline void info_unlock() { pthread_mutex_unlock(&info_mutex); } ++ + _X_HIDDEN XftDisplayInfo *_XftDisplayInfo; + + static int +@@ -48,10 +53,12 @@ + /* + * Unhook from the global list + */ ++ info_lock(); + for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next) + if (info->display == dpy) + break; + *prev = info->next; ++ info_unlock(); + + free (info); + return 0; +@@ -66,6 +73,7 @@ + int i; + int event_base, error_base; + ++ info_lock(); + for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next) + { + if (info->display == dpy) +@@ -79,9 +87,12 @@ + info->next = _XftDisplayInfo; + _XftDisplayInfo = info; + } ++ info_unlock(); + return info; + } + } ++ info_unlock(); ++ + if (!createIfNecessary) + return NULL; + +@@ -157,8 +168,10 @@ + } + info->fonts = NULL; + ++ info_lock(); + info->next = _XftDisplayInfo; + _XftDisplayInfo = info; ++ info_unlock(); + + info->glyph_memory = 0; + info->max_glyph_memory = XftDefaultGetInteger (dpy, +Only in libXft-2.3.2: tags