From ed0d23fa63102c890bfd22e30abb1a0a40b4390b Mon Sep 17 00:00:00 2001 From: Good Guy Date: Sun, 22 Aug 2021 13:00:31 -0600 Subject: [PATCH] Contributed Speed PerCent video plugin --- cinelerra-5.1/expanders.txt | 1 + cinelerra-5.1/picon/cinfinity/speed_pc.png | Bin 0 -> 2999 bytes cinelerra-5.1/picon/cinfinity2/speed_pc.png | Bin 0 -> 2430 bytes cinelerra-5.1/plugin_defs | 1 + cinelerra-5.1/plugins/Makefile | 1 + cinelerra-5.1/plugins/speed_pc/Makefile | 13 + cinelerra-5.1/plugins/speed_pc/speed_pc.C | 564 ++++++++++++++++++++ cinelerra-5.1/plugins/speed_pc/speed_pc.h | 234 ++++++++ 8 files changed, 814 insertions(+) create mode 100644 cinelerra-5.1/picon/cinfinity/speed_pc.png create mode 100644 cinelerra-5.1/picon/cinfinity2/speed_pc.png create mode 100644 cinelerra-5.1/plugins/speed_pc/Makefile create mode 100644 cinelerra-5.1/plugins/speed_pc/speed_pc.C create mode 100644 cinelerra-5.1/plugins/speed_pc/speed_pc.h diff --git a/cinelerra-5.1/expanders.txt b/cinelerra-5.1/expanders.txt index 9bda7186..af915744 100644 --- a/cinelerra-5.1/expanders.txt +++ b/cinelerra-5.1/expanders.txt @@ -161,6 +161,7 @@ Video Effects Interpolate Video ReframeRT Reverse video + Speed PerCent Time Average TimeFront Timelapse Helper diff --git a/cinelerra-5.1/picon/cinfinity/speed_pc.png b/cinelerra-5.1/picon/cinfinity/speed_pc.png new file mode 100644 index 0000000000000000000000000000000000000000..a98ec84db338c3abe53ac31e9cf1a42c10cd78d4 GIT binary patch literal 2999 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 literal 0 HcmV?d00001 diff --git a/cinelerra-5.1/picon/cinfinity2/speed_pc.png b/cinelerra-5.1/picon/cinfinity2/speed_pc.png new file mode 100644 index 0000000000000000000000000000000000000000..22d6d1bceae76e0d8bda37546fd0af4261e6478c GIT binary patch literal 2430 zcmV-^34!*BP)VGyK~!jg)tYTgR970ue|PSkxdYCOl(@*45h{xXTc|H<8aGy~ zyNRWp0?wu&S*pfi*EaPfYip|?O!R{$MpGl(*h+k_)3rcDzS z5kX!mGL#`Qz|8Ci%9Ih1J2O!1FS#G)+;h(J|KD@&InTX!1Rle(Wy_*~e?>+{E}t}M zQk+_?*2=Q15(MFK&Bg_v&xhOX_V)JncDr1zJ6&B}Csis{L2+@hbEG!Is?5m9h}38_ zg;S?a{kvAHRgItI@aXC3@isR%U+C)U%KhrAuYP{?{19`myz)hw_ zjg`)@=e=lJ;ea*akKg{g7EaJ$`}+S=N`mX?+L$B8xBuV-=fRLA$XNZZ3Y1L>n@US^SaV8H55zpVfdzS|f9w?6KbUN9$Z=a&rQcq8hGL@qQHy8{& z^UO2Y?RI}zT3Q;bSFiT}zJ2>P)2B~Il74+2o<4m#H*emgt*uQ_Y^T$SQq6vIp^T7P zt!DA!#bjh;Fl*K<+S}X7$;km=&YU^C^Ugc|e$Smd$A=$&h}mpr{rdF*{fMGSVPRp= z@kc{)yWIf=N=?q2H;*k_wh$W|>n}TV<_vDPn}mb}wr}5#TCJw5tBc*ccT-kYMsjj8 zr%s(BAt3>?+3atZmX^lcxpT4EY-3_-z{3!8N?5pXA$#`h37B30)z#H_JRbJ!*@I4} zUr@z-F`2*4D=U{rgExO{JiqfVj9gYHMq;+wGW4CZ^9ckbb>hFK5r5rME>G9x5vTpnSx5iKmYu5 z7A;y7RFJ;DK5}z&sjsi6xVSiA)avT$SiO2Rw{G1U^M~G`UzI=i+;c$(IdbF(H8nMS z_St6v#>&gfF`LbZqR5gZOYnNVV|oN-P7nkR9z4k5!-u(e@uK3);{5sZx{|F4nrcIl;d-pCyMMVgL zKu1RhbLPzPzkZNqnfCVfAs6fP>C^1pyEjyMhz5gUd$5L&z_A|tL5s|tK7J8gSfajQc_Z=sHot=g$sQ5 z-FN=u%9ShJyLT^Sb3uIiLz<~oKCME`yI~)$)dh0DL77Im1MFGD7$ zs;UaLT0NwnW5ZXQ9g zxyHsup#N!LaOxBr8|zPi2kHR)@WT(o_9F-aAAIluM~@!m(@#G|mixcKba!{t(a}Li zN5_yiWTB#XwJa?yW&Qf~Oqnu;lP6Dd=+Gh5YBg`a{WcL15df5wl=$o0?e<|8AAev; z3V6gBd|}24#rK>}r{nC|v&@`1bJ+8CyPcezoN-(ELP7Dgbh%vQCb+uh+|| zQ>R$5V#O0>3_?u5;^N{+O--e*uMdaAL34BScxVe7!DKS^0Tc4qjB&=J0$L|p#W>Nd z0z%JBpKR`_fa?>jVm$Eqe0CL3GHT7=Au5%sL?ua58SrE-ccIfH%kqCkr_3B + * + * 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 + * + */ + +/* + * 2020. Derivative by ReframeRT plugin for a more easy use. + * It uses percentage value of the speed referred to originl speed (=100%). + * Some old ReframeRT parameters (Stretch and denom) have not been deleted, + * for future development, if any. + * Stretch and denom variables are set to a constant value: + * Stretch= 1; denom= 100.00. + * Speed_MIN= 1.00%; Speed_MAX= 1000.00% + */ + +#include "bcdisplayinfo.h" +#include "clip.h" +#include "bchash.h" +#include "filexml.h" +#include "speed_pc.h" +#include "guicast.h" +#include "language.h" +#include "pluginvclient.h" +#include "theme.h" +#include "transportque.h" + +#include + + + + +REGISTER_PLUGIN(SpeedPc); + + + +SpeedPcConfig::SpeedPcConfig() +{ + reset(RESET_DEFAULT_SETTINGS); +} + +void SpeedPcConfig::reset(int clear) +{ + switch(clear) { + case RESET_SPEED : + num = 100.00; + denom = 100.0; + stretch = 1; + break; + case RESET_ALL : + case RESET_DEFAULT_SETTINGS : + default: + num = 100.00; + denom = 100.0; + stretch = 1; + interp = 0; + optic_flow = 1; + break; + } +} + +int SpeedPcConfig::equivalent(SpeedPcConfig &src) +{ + return fabs(num - src.num) < 0.0001 && + fabs(denom - src.denom) < 0.0001 && + stretch == src.stretch && + interp == src.interp; +} + +void SpeedPcConfig::copy_from(SpeedPcConfig &src) +{ + this->num = src.num; + this->denom = src.denom; + this->stretch = src.stretch; + this->interp = src.interp; +} + +void SpeedPcConfig::interpolate(SpeedPcConfig &prev, + SpeedPcConfig &next, + int64_t prev_frame, + int64_t next_frame, + int64_t current_frame) +{ + this->interp = prev.interp; + this->stretch = prev.stretch; + this->denom = prev.denom; + + if (this->interp && prev_frame != next_frame) + { + double next_weight = (double)(current_frame - prev_frame) / (next_frame - prev_frame); + double prev_weight = (double)(next_frame - current_frame) / (next_frame - prev_frame); + double prev_slope = prev.num / prev.denom, next_slope = next.num / next.denom; + // for interpolation, this is (for now) a simple linear slope to the next keyframe. + double scale = prev_slope * prev_weight + next_slope * next_weight; + this->num = this->denom * scale; + } + else + { + this->num = prev.num; + } +} + +void SpeedPcConfig::boundaries() +{ + if(num < 0.0001) num = 0.0001; + if(denom < 0.0001) denom = 0.0001; +} + + + + + + + + +SpeedPcWindow::SpeedPcWindow(SpeedPc *plugin) + : PluginClientWindow(plugin, xS(420), yS(150), xS(420), yS(150), 0) // Note: with "Stretch" and "Downsample" gui yS was yS(210) +{ + this->plugin = plugin; +} + +SpeedPcWindow::~SpeedPcWindow() +{ +} + +void SpeedPcWindow::create_objects() +{ + int xs10 = xS(10), xs64 = xS(64), xs200 = xS(200); + int ys10 = yS(10), ys30 = yS(30), ys40 = yS(40); + int x2 = xS(80), x3 = xS(180); + int x = xs10, y = ys10; + int clr_x = get_w()-x - xS(22); // note: clrBtn_w = 22 + + BC_Bar *bar; + + add_subwindow(new BC_Title(x, y, _("Preset:"))); + x = x + x2; + add_subwindow(toggle25pc = new SpeedPcToggle(plugin, this, + plugin->config.num == 25, x, y, 25, "25%")); + x += xs64; + add_subwindow(toggle50pc = new SpeedPcToggle(plugin, this, + plugin->config.num == 50, x, y, 50, "50%")); + x += xs64; + add_subwindow(toggle100pc = new SpeedPcToggle(plugin, this, + plugin->config.num == 100, x, y, 100, "100%")); + x += xs64; + add_subwindow(toggle200pc = new SpeedPcToggle(plugin, this, + plugin->config.num == 200, x, y, 200, "200%")); + x += xs64; + add_subwindow(toggle400pc = new SpeedPcToggle(plugin, this, + plugin->config.num == 400, x, y, 400, "400%")); + x = xs10; y += ys30; + + add_tool(new BC_Title(x, y, _("Speed:"))); + add_tool(new BC_Title((x2-x), y, _("%"))); + speed_pc_text = new SpeedPcText(plugin, this, (x + x2), y); + speed_pc_text->create_objects(); + speed_pc_slider = new SpeedPcSlider(plugin, this, x3, y, xs200); + add_subwindow(speed_pc_slider); + clr_x = x3 + speed_pc_slider->get_w() + x; + add_subwindow(speed_pc_clr = new SpeedPcClr(plugin, this, + clr_x, y, RESET_SPEED)); + y += ys30; + +// REM 2020-06-23 +/* + add_subwindow(stretch = new SpeedPcStretch(plugin, this, x, y)); + y += yS(30); + add_subwindow(downsample = new SpeedPcDownsample(plugin, this, x, y)); + y += yS(30); +*/ + + add_subwindow(interpolate = new SpeedPcInterpolate(plugin, this, x, y)); + y += ys40; + +// Reset section + add_subwindow(bar = new BC_Bar(x, y, get_w()-2*x)); + y += ys10; + add_subwindow(reset = new SpeedPcReset(plugin, this, x, y)); + + update(RESET_ALL); + show_window(); +} + +void SpeedPcWindow::update(int clear) +{ + switch(clear) { + case RESET_SPEED : + speed_pc_text->update((float)plugin->config.num); + speed_pc_slider->update((float)plugin->config.num); + update_toggles(); + break; + case RESET_ALL : + case RESET_DEFAULT_SETTINGS : + default: + speed_pc_text->update((float)plugin->config.num); + speed_pc_slider->update((float)plugin->config.num); + update_toggles(); + +// OLD ReframeRT code +/* + stretch->update(plugin->config.stretch); + downsample->update(!plugin->config.stretch); +*/ + interpolate->update(plugin->config.interp); + break; + } +} + + +int SpeedPcWindow::update_toggles() +{ + toggle25pc->update(EQUIV(plugin->config.num, 25)); + toggle50pc->update(EQUIV(plugin->config.num, 50)); + toggle100pc->update(EQUIV(plugin->config.num, 100)); + toggle200pc->update(EQUIV(plugin->config.num, 200)); + toggle400pc->update(EQUIV(plugin->config.num, 400)); + return 0; +} + + +SpeedPcToggle::SpeedPcToggle(SpeedPc *plugin, SpeedPcWindow *gui, + int init_value, + int x, + int y, + int value, + const char *string) + : BC_Radial(x, y, init_value, string) +{ + this->value = value; + this->plugin = plugin; + this->gui = gui; +} + +int SpeedPcToggle::handle_event() +{ + plugin->config.num = (float)value; + gui->update(RESET_SPEED); + plugin->send_configure_change(); + return 1; +} + + + +/* *********************************** */ +/* **** SPEED ******************** */ +SpeedPcText::SpeedPcText(SpeedPc *plugin, SpeedPcWindow *gui, + int x, + int y) + : BC_TumbleTextBox(gui, (float)plugin->config.num, + (float)1.00, (float)1000.00, x, y, xS(60), 2) +{ + this->plugin = plugin; + this->gui = gui; +} + +SpeedPcText::~SpeedPcText() +{ +} + +int SpeedPcText::handle_event() +{ + plugin->config.num = atof(get_text()); + plugin->config.denom = 100.00; + plugin->config.stretch = 1; + plugin->config.boundaries(); + gui->update(RESET_SPEED); + plugin->send_configure_change(); + return 1; +} + +SpeedPcSlider::SpeedPcSlider(SpeedPc *plugin, SpeedPcWindow *gui, + int x, int y, int w) + : BC_FSlider(x, y, 0, w, w, 1.00, 1000.00, plugin->config.num) +{ + this->plugin = plugin; + this->gui = gui; + enable_show_value(0); // Hide caption + set_precision(1.00); +} + +SpeedPcSlider::~SpeedPcSlider() +{ +} + +int SpeedPcSlider::handle_event() +{ + plugin->config.num = get_value(); + plugin->config.denom = 100.00; + plugin->config.stretch = 1; + gui->update(RESET_SPEED); + plugin->send_configure_change(); + return 1; +} +/* *********************************** */ + + +SpeedPcStretch::SpeedPcStretch(SpeedPc *plugin, + SpeedPcWindow *gui, + int x, + int y) + : BC_Radial(x, y, plugin->config.stretch, _("Stretch")) +{ + this->plugin = plugin; + this->gui = gui; +} + +int SpeedPcStretch::handle_event() +{ + plugin->config.stretch = get_value(); + gui->downsample->update(!get_value()); + plugin->send_configure_change(); + return 1; +} + + +SpeedPcDownsample::SpeedPcDownsample(SpeedPc *plugin, SpeedPcWindow *gui, + int x, + int y) + : BC_Radial(x, y, !plugin->config.stretch, _("Downsample")) +{ + this->plugin = plugin; + this->gui = gui; +} + +int SpeedPcDownsample::handle_event() +{ + plugin->config.stretch = !get_value(); + gui->stretch->update(!get_value()); + plugin->send_configure_change(); + return 1; +} + +SpeedPcInterpolate::SpeedPcInterpolate(SpeedPc *plugin, SpeedPcWindow *gui, + int x, + int y) + : BC_CheckBox(x, y, 0, _("Interpolate")) +{ + this->plugin = plugin; + this->gui = gui; + set_tooltip(_("Interpolate between keyframes")); +} + +int SpeedPcInterpolate::handle_event() +{ + plugin->config.interp = get_value(); + gui->interpolate->update(get_value()); + plugin->send_configure_change(); + return 1; +} + + +SpeedPcClr::SpeedPcClr(SpeedPc *plugin, SpeedPcWindow *gui, int x, int y, int clear) + : BC_Button(x, y, plugin->get_theme()->get_image_set("reset_button")) +{ + this->plugin = plugin; + this->gui = gui; + this->clear = clear; +} +SpeedPcClr::~SpeedPcClr() +{ +} +int SpeedPcClr::handle_event() +{ + plugin->config.reset(clear); + gui->update(clear); + plugin->send_configure_change(); + return 1; +} + + +SpeedPcReset::SpeedPcReset(SpeedPc *plugin, SpeedPcWindow *gui, int x, int y) + : BC_GenericButton(x, y, _("Reset")) +{ + this->plugin = plugin; + this->gui = gui; +} +SpeedPcReset::~SpeedPcReset() +{ +} +int SpeedPcReset::handle_event() +{ + plugin->config.reset(RESET_ALL); + gui->update(RESET_ALL); + plugin->send_configure_change(); + return 1; +} + + + +SpeedPc::SpeedPc(PluginServer *server) + : PluginVClient(server) +{ +} + +SpeedPc::~SpeedPc() +{ + +} + +const char* SpeedPc::plugin_title() { return N_("Speed PerCent"); } +int SpeedPc::is_realtime() { return 1; } +int SpeedPc::is_synthesis() { return 1; } + + +NEW_WINDOW_MACRO(SpeedPc, SpeedPcWindow) +LOAD_CONFIGURATION_MACRO(SpeedPc, SpeedPcConfig) + +int SpeedPc::process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate) +{ + int64_t input_frame = get_source_start(); + SpeedPcConfig prev_config, next_config; + KeyFrame *tmp_keyframe, *next_keyframe = get_prev_keyframe(get_source_start()); + int64_t tmp_position, next_position; + int64_t segment_len; + double input_rate = frame_rate; + int is_current_keyframe; + +// if there are no keyframes, the default keyframe is used, and its position is always 0; +// if there are keyframes, the first keyframe can be after the effect start (and it controls settings before it) +// so let's calculate using a fake keyframe with the same settings but position == effect start + KeyFrame *fake_keyframe = new KeyFrame(); + fake_keyframe->copy_from(next_keyframe); + fake_keyframe->position = local_to_edl(get_source_start()); + next_keyframe = fake_keyframe; + + // calculate input_frame accounting for all previous keyframes + do + { + tmp_keyframe = next_keyframe; + next_keyframe = get_next_keyframe(tmp_keyframe->position+1, 0); + + tmp_position = edl_to_local(tmp_keyframe->position); + next_position = edl_to_local(next_keyframe->position); + + is_current_keyframe = + next_position > start_position // the next keyframe is after the current position + || next_keyframe->position == tmp_keyframe->position // there are no more keyframes + || !next_keyframe->position; // there are no keyframes at all + + if (is_current_keyframe) + segment_len = start_position - tmp_position; + else + segment_len = next_position - tmp_position; + + read_data(next_keyframe); + next_config.copy_from(config); + read_data(tmp_keyframe); + prev_config.copy_from(config); + config.interpolate(prev_config, next_config, tmp_position, next_position, tmp_position + segment_len); + + // the area under the curve is the number of frames to advance + // as long as interpolate() uses a linear slope we can use geometry to determine this + // if interpolate() changes to use a curve then this needs use (possibly) the definite integral + double prev_scale = prev_config.num / 100.00; + double config_scale = config.num / 100.00; + input_frame += (int64_t)(segment_len * ((prev_scale + config_scale) / 2)); + } while (!is_current_keyframe); + +// Change rate + if (!config.stretch) + { + input_rate *= config.num / 100.00; + + } + +// printf("SpeedPc::process_buffer %d %lld %f %lld %f\n", +// __LINE__, +// start_position, +// frame_rate, +// input_frame, +// input_rate); + + read_frame(frame, + 0, + input_frame, + input_rate, + 0); + + delete fake_keyframe; + + return 0; +} + + + +void SpeedPc::save_data(KeyFrame *keyframe) +{ + FileXML output; + +// cause data to be stored directly in text + output.set_shared_output(keyframe->xbuf); + output.tag.set_title("SPEED_PC"); + output.tag.set_property("SPEED", config.num); + output.tag.set_property("DENOM", config.denom); + output.tag.set_property("STRETCH", config.stretch); + output.tag.set_property("INTERPOLATE", config.interp); + output.append_tag(); + output.tag.set_title("/SPEED_PC"); + output.append_tag(); + output.append_newline(); + output.terminate_string(); +} + +void SpeedPc::read_data(KeyFrame *keyframe) +{ + FileXML input; + + input.set_shared_input(keyframe->xbuf); + + while(!input.read_tag()) + { + if(input.tag.title_is("SPEED_PC")) + { + config.num = input.tag.get_property("SPEED", config.num); + config.denom = input.tag.get_property("DENOM", config.denom); + config.stretch = input.tag.get_property("STRETCH", config.stretch); + config.interp = input.tag.get_property("INTERPOLATE", config.interp); + } + } +} + +void SpeedPc::update_gui() +{ + if(thread) + { + int changed = load_configuration(); + + if(changed) + { + SpeedPcWindow* window = (SpeedPcWindow*)thread->window; + window->lock_window("SpeedPc::update_gui"); + window->update(RESET_ALL); +// OLD ReframeRT code +/* + window->stretch->update(config.stretch); + window->downsample->update(!config.stretch); +*/ + window->unlock_window(); + } + } +} + + + + + diff --git a/cinelerra-5.1/plugins/speed_pc/speed_pc.h b/cinelerra-5.1/plugins/speed_pc/speed_pc.h new file mode 100644 index 00000000..58fb6939 --- /dev/null +++ b/cinelerra-5.1/plugins/speed_pc/speed_pc.h @@ -0,0 +1,234 @@ + +/* + * CINELERRA + * Copyright (C) 2008-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 + * + */ + +/* + * 2020. Derivative by ReframeRT plugin for a more easy use. + * It uses percentage value of the speed referred to originl speed (=100%). + * Some old ReframeRT parameters (Stretch and denom) have not been deleted, + * for future development, if any. + * Stretch and denom variables are set to a constant value: + * Stretch= 1; denom= 100.00. + * Speed_MIN= 1.00%; Speed_MAX= 1000.00% + */ + +#ifndef SPEED_PC_H +#define SPEED_PC_H + + +#include "bcdisplayinfo.h" +#include "clip.h" +#include "bchash.h" +#include "filexml.h" +#include "guicast.h" +#include "language.h" +#include "pluginvclient.h" +#include "theme.h" +#include "transportque.h" + + +#define RESET_DEFAULT_SETTINGS 10 +#define RESET_ALL 0 +#define RESET_SPEED 1 + +class SpeedPcConfig; +class SpeedPcText; +class SpeedPcSlider; +class SpeedPcStretch; +class SpeedPcDownsample; +class SpeedPcInterpolate; +class SpeedPcClr; +class SpeedPc; +class SpeedPcWindow; +class SpeedPcReset; + + + +class SpeedPcConfig +{ +public: + SpeedPcConfig(); + void boundaries(); + int equivalent(SpeedPcConfig &src); + void reset(int clear); + void copy_from(SpeedPcConfig &src); + void interpolate(SpeedPcConfig &prev, + SpeedPcConfig &next, + int64_t prev_frame, + int64_t next_frame, + int64_t current_frame); + + double num; + double denom; + int stretch; + int interp; + int optic_flow; +}; + + + +class SpeedPcToggle : public BC_Radial +{ +public: + SpeedPcToggle(SpeedPc *plugin, + SpeedPcWindow *gui, + int init_value, + int x, + int y, + int value, + const char *string); + int handle_event(); + + SpeedPc *plugin; + SpeedPcWindow *gui; + int value; +}; + +class SpeedPcText : public BC_TumbleTextBox +{ +public: + SpeedPcText(SpeedPc *plugin, + SpeedPcWindow *gui, + int x, + int y); + ~SpeedPcText(); + int handle_event(); + SpeedPc *plugin; + SpeedPcWindow *gui; +}; + +class SpeedPcSlider : public BC_FSlider +{ +public: + SpeedPcSlider(SpeedPc *plugin, + SpeedPcWindow *gui, + int x, int y, int w); + ~SpeedPcSlider(); + int handle_event(); + SpeedPc *plugin; + SpeedPcWindow *gui; +}; + +class SpeedPcClr : public BC_Button +{ +public: + SpeedPcClr(SpeedPc *plugin, SpeedPcWindow *gui, + int x, int y, int clear); + ~SpeedPcClr(); + int handle_event(); + SpeedPc *plugin; + SpeedPcWindow *gui; + int clear; +}; + +class SpeedPcStretch : public BC_Radial +{ +public: + SpeedPcStretch(SpeedPc *plugin, + SpeedPcWindow *gui, + int x, + int y); + int handle_event(); + SpeedPc *plugin; + SpeedPcWindow *gui; +}; + +class SpeedPcDownsample : public BC_Radial +{ +public: + SpeedPcDownsample(SpeedPc *plugin, + SpeedPcWindow *gui, + int x, + int y); + int handle_event(); + SpeedPc *plugin; + SpeedPcWindow *gui; +}; + +class SpeedPcInterpolate : public BC_CheckBox +{ +public: + SpeedPcInterpolate(SpeedPc *plugin, + SpeedPcWindow *gui, + int x, + int y); + int handle_event(); + SpeedPc *plugin; + SpeedPcWindow *gui; +}; + +class SpeedPcReset : public BC_GenericButton +{ +public: + SpeedPcReset(SpeedPc *plugin, SpeedPcWindow *gui, int x, int y); + ~SpeedPcReset(); + int handle_event(); + SpeedPc *plugin; + SpeedPcWindow *gui; +}; + +class SpeedPcWindow : public PluginClientWindow +{ +public: + SpeedPcWindow(SpeedPc *plugin); + ~SpeedPcWindow(); + void create_objects(); + void update(int clear); + + int update_toggles(); + + SpeedPc *plugin; + + SpeedPcToggle *toggle25pc; + SpeedPcToggle *toggle50pc; + SpeedPcToggle *toggle100pc; + SpeedPcToggle *toggle200pc; + SpeedPcToggle *toggle400pc; + + SpeedPcText *speed_pc_text; + SpeedPcSlider *speed_pc_slider; + SpeedPcClr *speed_pc_clr; + SpeedPcStretch *stretch; + SpeedPcDownsample *downsample; + SpeedPcInterpolate *interpolate; + + SpeedPcReset *reset; +}; + + +class SpeedPc : public PluginVClient +{ +public: + SpeedPc(PluginServer *server); + ~SpeedPc(); + + PLUGIN_CLASS_MEMBERS(SpeedPcConfig) + + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + void update_gui(); + int is_realtime(); + int is_synthesis(); + int process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate); +}; + +#endif \ No newline at end of file -- 2.26.2