4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "translate.h"
26 #include "translatewin.h"
33 REGISTER_PLUGIN(TranslateMain)
35 TranslateConfig::TranslateConfig()
47 int TranslateConfig::equivalent(TranslateConfig &that)
49 return EQUIV(in_x, that.in_x) &&
50 EQUIV(in_y, that.in_y) &&
51 EQUIV(in_w, that.in_w) &&
52 EQUIV(in_h, that.in_h) &&
53 EQUIV(out_x, that.out_x) &&
54 EQUIV(out_y, that.out_y) &&
55 EQUIV(out_w, that.out_w) &&
56 EQUIV(out_h, that.out_h);
59 void TranslateConfig::copy_from(TranslateConfig &that)
71 void TranslateConfig::interpolate(TranslateConfig &prev,
72 TranslateConfig &next,
75 int64_t current_frame)
77 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
78 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
80 this->in_x = prev.in_x * prev_scale + next.in_x * next_scale;
81 this->in_y = prev.in_y * prev_scale + next.in_y * next_scale;
82 this->in_w = prev.in_w * prev_scale + next.in_w * next_scale;
83 this->in_h = prev.in_h * prev_scale + next.in_h * next_scale;
84 this->out_x = prev.out_x * prev_scale + next.out_x * next_scale;
85 this->out_y = prev.out_y * prev_scale + next.out_y * next_scale;
86 this->out_w = prev.out_w * prev_scale + next.out_w * next_scale;
87 this->out_h = prev.out_h * prev_scale + next.out_h * next_scale;
97 TranslateMain::TranslateMain(PluginServer *server)
98 : PluginVClient(server)
105 TranslateMain::~TranslateMain()
109 if(temp_frame) delete temp_frame;
111 if(overlayer) delete overlayer;
115 const char* TranslateMain::plugin_title() { return N_("Translate"); }
116 int TranslateMain::is_realtime() { return 1; }
120 LOAD_CONFIGURATION_MACRO(TranslateMain, TranslateConfig)
122 void TranslateMain::save_data(KeyFrame *keyframe)
126 // cause data to be stored directly in text
127 output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
130 output.tag.set_title("TRANSLATE");
131 output.tag.set_property("IN_X", config.in_x);
132 output.tag.set_property("IN_Y", config.in_y);
133 output.tag.set_property("IN_W", config.in_w);
134 output.tag.set_property("IN_H", config.in_h);
135 output.tag.set_property("OUT_X", config.out_x);
136 output.tag.set_property("OUT_Y", config.out_y);
137 output.tag.set_property("OUT_W", config.out_w);
138 output.tag.set_property("OUT_H", config.out_h);
141 output.terminate_string();
142 // data is now in *text
145 void TranslateMain::read_data(KeyFrame *keyframe)
149 input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
155 result = input.read_tag();
159 if(input.tag.title_is("TRANSLATE"))
161 config.in_x = input.tag.get_property("IN_X", config.in_x);
162 config.in_y = input.tag.get_property("IN_Y", config.in_y);
163 config.in_w = input.tag.get_property("IN_W", config.in_w);
164 config.in_h = input.tag.get_property("IN_H", config.in_h);
165 config.out_x = input.tag.get_property("OUT_X", config.out_x);
166 config.out_y = input.tag.get_property("OUT_Y", config.out_y);
167 config.out_w = input.tag.get_property("OUT_W", config.out_w);
168 config.out_h = input.tag.get_property("OUT_H", config.out_h);
181 int TranslateMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
183 VFrame *input, *output;
189 load_configuration();
191 //printf("TranslateMain::process_realtime 1 %p\n", input);
192 if(input->get_rows()[0] == output->get_rows()[0])
195 temp_frame = new VFrame(0,
199 input->get_color_model(),
201 temp_frame->copy_from(input);
204 //printf("TranslateMain::process_realtime 2 %p\n", input);
209 overlayer = new OverlayFrame(smp + 1);
212 output->clear_frame();
215 // printf("TranslateMain::process_realtime 3 output=%p input=%p config.w=%f config.h=%f"
216 // "%f %f %f %f -> %f %f %f %f\n", output, input, config.w, config.h,
217 // in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2);
218 overlayer->overlay(output, input,
219 config.in_x, config.in_y,
220 config.in_x + config.in_w, config.in_y + config.in_h,
221 config.out_x, config.out_y,
222 config.out_x + config.out_w, config.out_y + config.out_h,
223 1, TRANSFER_REPLACE, get_interpolation_type());
229 NEW_WINDOW_MACRO(TranslateMain, TranslateWin)
231 void TranslateMain::update_gui()
235 if(load_configuration())
237 thread->window->lock_window();
238 ((TranslateWin*)thread->window)->in_x->update(config.in_x);
239 ((TranslateWin*)thread->window)->in_y->update(config.in_y);
240 ((TranslateWin*)thread->window)->in_w->update(config.in_w);
241 ((TranslateWin*)thread->window)->in_h->update(config.in_h);
242 ((TranslateWin*)thread->window)->out_x->update(config.out_x);
243 ((TranslateWin*)thread->window)->out_y->update(config.out_y);
244 ((TranslateWin*)thread->window)->out_w->update(config.out_w);
245 ((TranslateWin*)thread->window)->out_h->update(config.out_h);
246 thread->window->unlock_window();