remove whitespace at eol
[goodguy/history.git] / cinelerra-5.1 / plugins / reframert / reframert.C
index d79e63a82a87c43b866bb000a17f37875bed7ad6..ac5b384679ac8932341314d3822b28959fe82a11 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2016 Adam Williams <broadcast at earthling dot net>
  *
  * 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
@@ -46,17 +46,30 @@ public:
                int64_t prev_frame,
                int64_t next_frame,
                int64_t current_frame);
-       double scale;
+// was scale
+       double num;
+       double denom;
        int stretch;
        int interp;
        int optic_flow;
 };
 
 
-class ReframeRTScale : public BC_TumbleTextBox
+class ReframeRTNum : public BC_TumbleTextBox
 {
 public:
-       ReframeRTScale(ReframeRT *plugin,
+       ReframeRTNum(ReframeRT *plugin,
+               ReframeRTWindow *gui,
+               int x,
+               int y);
+       int handle_event();
+       ReframeRT *plugin;
+};
+
+class ReframeRTDenom : public BC_TumbleTextBox
+{
+public:
+       ReframeRTDenom(ReframeRT *plugin,
                ReframeRTWindow *gui,
                int x,
                int y);
@@ -107,7 +120,8 @@ public:
        ~ReframeRTWindow();
        void create_objects();
        ReframeRT *plugin;
-       ReframeRTScale *scale;
+       ReframeRTNum *num;
+       ReframeRTDenom *denom;
        ReframeRTStretch *stretch;
        ReframeRTDownsample *downsample;
        ReframeRTInterpolate *interpolate;
@@ -144,7 +158,8 @@ REGISTER_PLUGIN(ReframeRT);
 
 ReframeRTConfig::ReframeRTConfig()
 {
-       scale = 1.0;
+       num = 1.0;
+       denom = 1.0;
        stretch = 0;
        interp = 0;
        optic_flow = 1;
@@ -152,14 +167,16 @@ ReframeRTConfig::ReframeRTConfig()
 
 int ReframeRTConfig::equivalent(ReframeRTConfig &src)
 {
-       return fabs(scale - src.scale) < 0.0001 &&
+       return fabs(num - src.num) < 0.0001 &&
+               fabs(denom - src.denom) < 0.0001 &&
                stretch == src.stretch &&
                interp == src.interp;
 }
 
 void ReframeRTConfig::copy_from(ReframeRTConfig &src)
 {
-       this->scale = src.scale;
+       this->num = src.num;
+       this->denom = src.denom;
        this->stretch = src.stretch;
        this->interp = src.interp;
 }
@@ -172,22 +189,27 @@ void ReframeRTConfig::interpolate(ReframeRTConfig &prev,
 {
        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 slope = (next.scale - prev.scale) / (next_frame - prev_frame);
-               this->scale = (slope * (current_frame - prev_frame)) + prev.scale;
+               double scale = prev_slope * prev_weight + next_slope * next_weight;
+               this->num = this->denom * scale;
        }
        else
        {
-               this->scale = prev.scale;
+               this->num = prev.num;
        }
 }
 
 void ReframeRTConfig::boundaries()
 {
-       if(fabs(scale) < 0.0001) scale = 0.0001;
+       if(num < 0.0001) num = 0.0001;
+       if(denom < 0.0001) denom = 0.0001;
 }
 
 
@@ -198,7 +220,7 @@ void ReframeRTConfig::boundaries()
 
 
 ReframeRTWindow::ReframeRTWindow(ReframeRT *plugin)
- : PluginClientWindow(plugin, 230, 160, 230, 160, 0)
+ : PluginClientWindow(plugin, 230, 190, 230, 190, 0)
 {
        this->plugin = plugin;
 }
@@ -209,33 +231,40 @@ ReframeRTWindow::~ReframeRTWindow()
 
 void ReframeRTWindow::create_objects()
 {
-       int x = 10, y = 10;
+       int x = plugin->get_theme()->window_border;
+       int y = plugin->get_theme()->window_border;
        BC_Title *title;
-       add_subwindow(title = new BC_Title(x, y, _("Scale by amount:")));
+       add_subwindow(title = new BC_Title(x, y, _("Input frames:")));
        y += title->get_h() + plugin->get_theme()->widget_border;
-       scale = new ReframeRTScale(plugin,
+       num = new ReframeRTNum(plugin,
                this,
                x,
                y);
-       scale->create_objects();
-       scale->set_increment(0.1);
-       y += 30;
-       add_subwindow(stretch = new ReframeRTStretch(plugin,
+       num->create_objects();
+       num->set_increment(1.0);
+
+       y += num->get_h() + plugin->get_theme()->widget_border;
+       add_subwindow(title = new BC_Title(x, y, _("Output frames:")));
+       y += title->get_h() + plugin->get_theme()->widget_border;
+       denom = new ReframeRTDenom(plugin,
                this,
                x,
-               y));
+               y);
+       denom->create_objects();
+       denom->set_increment(1.0);
+
+
+       y += denom->get_h() + plugin->get_theme()->widget_border;
+       add_subwindow(stretch = new ReframeRTStretch(plugin, this, x, y));
        y += 30;
-       add_subwindow(downsample = new ReframeRTDownsample(plugin,
-               this,
-               x,
-               y));
+       add_subwindow(downsample = new ReframeRTDownsample(plugin, this, x, y));
        y += 30;
-       add_subwindow(interpolate = new ReframeRTInterpolate(plugin,
-               this,
-               x,
-               y));
+       add_subwindow(interpolate = new ReframeRTInterpolate(plugin, this, x, y));
+       y += 30;
+       add_subwindow(stretch = new ReframeRTStretch(plugin, this, x, y));
+       y += stretch->get_h() + plugin->get_theme()->widget_border;
+       add_subwindow(downsample = new ReframeRTDownsample(plugin, this, x, y));
        show_window();
-       flush();
 }
 
 
@@ -245,29 +274,54 @@ void ReframeRTWindow::create_objects()
 
 
 
-ReframeRTScale::ReframeRTScale(ReframeRT *plugin,
+ReframeRTNum::ReframeRTNum(ReframeRT *plugin,
+       ReframeRTWindow *gui,
+       int x,
+       int y)
+ : BC_TumbleTextBox(gui,
+       (float)plugin->config.num,
+       (float)0.0001,
+       (float)1000,
+       x,
+       y,
+       gui->get_w() - plugin->get_theme()->window_border * 3)
+{
+       this->plugin = plugin;
+}
+
+int ReframeRTNum::handle_event()
+{
+       plugin->config.num = atof(get_text());
+       plugin->config.boundaries();
+       plugin->send_configure_change();
+       return 1;
+}
+
+
+ReframeRTDenom::ReframeRTDenom(ReframeRT *plugin,
        ReframeRTWindow *gui,
        int x,
        int y)
  : BC_TumbleTextBox(gui,
-       (float)plugin->config.scale,
+       (float)plugin->config.denom,
        (float)-1000,
        (float)1000,
        x,
        y,
-       100)
+       gui->get_w() - plugin->get_theme()->window_border * 3)
 {
        this->plugin = plugin;
 }
 
-int ReframeRTScale::handle_event()
+int ReframeRTDenom::handle_event()
 {
-       plugin->config.scale = atof(get_text());
+       plugin->config.denom = atof(get_text());
        plugin->config.boundaries();
        plugin->send_configure_change();
        return 1;
 }
 
+
 ReframeRTStretch::ReframeRTStretch(ReframeRT *plugin,
        ReframeRTWindow *gui,
        int x,
@@ -389,12 +443,17 @@ int ReframeRT::process_buffer(VFrame *frame,
                // 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
-               input_frame += (int64_t)(segment_len * ((prev_config.scale + config.scale) / 2));
+               double prev_scale = prev_config.num / prev_config.denom;
+               double config_scale = config.num / config.denom;
+               input_frame += (int64_t)(segment_len * ((prev_scale + config_scale) / 2));
        } while (!is_current_keyframe);
 
 // Change rate
        if (!config.stretch)
-               input_rate *= config.scale;
+       {
+               input_rate *= config.num / config.denom;
+
+       }
 
 // printf("ReframeRT::process_buffer %d %lld %f %lld %f\n",
 // __LINE__,
@@ -423,7 +482,9 @@ void ReframeRT::save_data(KeyFrame *keyframe)
 // cause data to be stored directly in text
        output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
        output.tag.set_title("REFRAMERT");
-       output.tag.set_property("SCALE", config.scale);
+// for backwards compatability, we call num scale
+       output.tag.set_property("SCALE", 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();
@@ -443,7 +504,9 @@ void ReframeRT::read_data(KeyFrame *keyframe)
        {
                if(input.tag.title_is("REFRAMERT"))
                {
-                       config.scale = input.tag.get_property("SCALE", config.scale);
+// for backwards compatability, we call num scale
+                       config.num = input.tag.get_property("SCALE", 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);
                }
@@ -460,7 +523,8 @@ void ReframeRT::update_gui()
                {
                        ReframeRTWindow* window = (ReframeRTWindow*)thread->window;
                        window->lock_window("ReframeRT::update_gui");
-                       window->scale->update((float)config.scale);
+                       window->num->update((float)config.num);
+                       window->denom->update((float)config.denom);
                        window->stretch->update(config.stretch);
                        window->downsample->update(!config.stretch);
                        window->interpolate->update(config.interp);