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 "scaleratio.h"
26 #include "scaleratiowin.h"
33 REGISTER_PLUGIN(ScaleRatioMain)
35 ScaleRatioConfig::ScaleRatioConfig()
38 in_w = 720; in_h = 480; in_r = 1;
39 out_w = 720; out_h = 480; out_r = 1;
40 src_x = src_y = 0; src_w = 720; src_h = 480;
41 dst_x = dst_y = 0; dst_w = 720; dst_h = 480;
44 int ScaleRatioConfig::equivalent(ScaleRatioConfig &that)
46 return EQUIV(src_x, that.src_x) && EQUIV(src_y, that.src_y) &&
47 EQUIV(src_w, that.src_w) && EQUIV(src_h, that.src_h) &&
48 EQUIV(dst_x, that.dst_x) && EQUIV(dst_y, that.dst_y) &&
49 EQUIV(dst_w, that.dst_w) && EQUIV(dst_h, that.dst_h);
52 void ScaleRatioConfig::copy_from(ScaleRatioConfig &that)
54 in_w = that.in_w; in_h = that.in_h; in_r = that.in_r;
55 out_w = that.out_w; out_h = that.out_h; out_r = that.out_r;
56 src_x = that.src_x; src_y = that.src_y;
57 src_w = that.src_w; src_h = that.src_h;
58 dst_x = that.dst_x; dst_y = that.dst_y;
59 dst_w = that.dst_w; dst_h = that.dst_h;
62 void ScaleRatioConfig::interpolate(ScaleRatioConfig &prev, ScaleRatioConfig &next,
63 int64_t prev_frame, int64_t next_frame, int64_t current_frame)
65 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
66 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
68 this->src_x = prev.src_x * prev_scale + next.src_x * next_scale;
69 this->src_y = prev.src_y * prev_scale + next.src_y * next_scale;
70 this->src_w = prev.src_w * prev_scale + next.src_w * next_scale;
71 this->src_h = prev.src_h * prev_scale + next.src_h * next_scale;
72 this->dst_x = prev.dst_x * prev_scale + next.dst_x * next_scale;
73 this->dst_y = prev.dst_y * prev_scale + next.dst_y * next_scale;
74 this->dst_w = prev.dst_w * prev_scale + next.dst_w * next_scale;
75 this->dst_h = prev.dst_h * prev_scale + next.dst_h * next_scale;
79 ScaleRatioMain::ScaleRatioMain(PluginServer *server)
80 : PluginVClient(server)
86 ScaleRatioMain::~ScaleRatioMain()
90 if(temp_frame) delete temp_frame;
92 if(overlayer) delete overlayer;
96 const char* ScaleRatioMain::plugin_title() { return N_("Scale Ratio"); }
97 int ScaleRatioMain::is_realtime() { return 1; }
101 LOAD_CONFIGURATION_MACRO(ScaleRatioMain, ScaleRatioConfig)
103 void ScaleRatioMain::save_data(KeyFrame *keyframe)
107 // cause data to be stored directly in text
108 output.set_shared_output(keyframe->xbuf);
111 output.tag.set_title("SCALERATIO");
112 output.tag.set_property("TYPE", config.type);
113 output.tag.set_property("IN_W", config.in_w);
114 output.tag.set_property("IN_H", config.in_h);
115 output.tag.set_property("IN_ASPECT_RATIO", config.in_r);
116 output.tag.set_property("OUT_W", config.out_w);
117 output.tag.set_property("OUT_H", config.out_h);
118 output.tag.set_property("OUT_ASPECT_RATIO", config.out_r);
119 output.tag.set_property("SRC_X", config.src_x);
120 output.tag.set_property("SRC_Y", config.src_y);
121 output.tag.set_property("SRC_W", config.src_w);
122 output.tag.set_property("SRC_H", config.src_h);
123 output.tag.set_property("DST_X", config.dst_x);
124 output.tag.set_property("DST_Y", config.dst_y);
125 output.tag.set_property("DST_W", config.dst_w);
126 output.tag.set_property("DST_H", config.dst_h);
128 output.tag.set_title("/SCALERATIO");
130 output.append_newline();
131 output.terminate_string();
132 // data is now in *text
135 void ScaleRatioMain::read_data(KeyFrame *keyframe)
139 input.set_shared_input(keyframe->xbuf);
143 while( !(result = input.read_tag()) ) {
144 if(input.tag.title_is("SCALERATIO")) {
145 config.type = input.tag.get_property("TYPE", config.type);
146 config.in_w = input.tag.get_property("IN_W", config.in_w);
147 config.in_h = input.tag.get_property("IN_H", config.in_h);
148 config.in_r = input.tag.get_property("IN_ASPECT_RATIO", config.in_r);
149 config.out_w = input.tag.get_property("OUT_W", config.out_w);
150 config.out_h = input.tag.get_property("OUT_H", config.out_h);
151 config.out_r = input.tag.get_property("OUT_ASPECT_RATIO", config.out_r);
152 config.src_x = input.tag.get_property("SRC_X", config.src_x);
153 config.src_y = input.tag.get_property("SRC_Y", config.src_y);
154 config.src_w = input.tag.get_property("SRC_W", config.src_w);
155 config.src_h = input.tag.get_property("SRC_H", config.src_h);
156 config.dst_x = input.tag.get_property("DST_X", config.dst_x);
157 config.dst_y = input.tag.get_property("DST_Y", config.dst_y);
158 config.dst_w = input.tag.get_property("DST_W", config.dst_w);
159 config.dst_h = input.tag.get_property("DST_H", config.dst_h);
165 #define EPSILON 0.001
167 int ScaleRatioMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
169 VFrame *input = input_ptr;
170 VFrame *output = output_ptr;
172 load_configuration();
174 if(get_use_opengl()) return run_opengl();
176 //printf("ScaleRatioMain::process_realtime 1 %p\n", input);
177 if( input->get_rows()[0] == output->get_rows()[0] ) {
179 temp_frame->get_w() != input_ptr->get_w() ||
180 temp_frame->get_h() != input_ptr->get_h() ||
181 temp_frame->get_color_model() != input_ptr->get_color_model() ) ) {
186 temp_frame = new VFrame(input_ptr->get_w(), input_ptr->get_h(),
187 input->get_color_model(), 0);
188 temp_frame->copy_from(input);
191 //printf("ScaleRatioMain::process_realtime 2 %p\n", input);
195 overlayer = new OverlayFrame(smp + 1);
198 output->clear_frame();
200 if( config.src_w < EPSILON ) return 1;
201 if( config.src_h < EPSILON ) return 1;
202 if( config.dst_w < EPSILON ) return 1;
203 if( config.dst_h < EPSILON ) return 1;
204 float ix0 = (input->get_w() - config.src_w)/2 + config.src_x;
205 float iy0 = (input->get_h() - config.src_h)/2 + config.src_y;
206 float ix1 = ix0, ix2 = ix1 + config.src_w;
207 float iy1 = iy0, iy2 = iy1 + config.src_h;
208 float ox0 = (output->get_w() - config.dst_w)/2 + config.dst_x;
209 float oy0 = (output->get_h() - config.dst_h)/2 + config.dst_y;
210 float ox1 = ox0, ox2 = ox1 + config.dst_w;
211 float oy1 = oy0, oy2 = oy1 + config.dst_h;
213 overlayer->overlay(output, input,
217 get_interpolation_type());
222 NEW_WINDOW_MACRO(ScaleRatioMain, ScaleRatioWin)
224 void ScaleRatioMain::update_gui()
226 if( !thread ) return;
227 ScaleRatioWin *window = (ScaleRatioWin*)thread->get_window();
228 window->lock_window("ScaleRatio::update_gui");
229 if( load_configuration() )
230 window->update_gui();
231 window->unlock_window();
235 int ScaleRatioMain::handle_opengl()
238 VFrame *input = get_input(), *output = get_output();
239 float ix1 = (input->get_w() - config.src_w)/2 + config.src_x;
240 float iy1 = (input->get_h() - config.src_h)/2 + config.src_y;
241 float ix2 = ix1 + config.src_w;
242 float iy2 = iy1 + config.src_h;
243 float ox1 = (output->get_w() - config.dst_w)/2 + config.dst_x;
244 float oy1 = (output->get_h() - config.dst_h)/2 + config.dst_y;
245 float ox2 = ox1 + config.dst_w;
246 float oy2 = oy1 + config.dst_h;
248 output->to_texture();
249 output->enable_opengl();
250 output->init_screen();
251 output->clear_pbuffer();
252 output->bind_texture(0);
253 output->draw_texture(ix1,iy1, ix2,iy2, ox1,oy1, ox2,oy2);
254 output->set_opengl_state(VFrame::SCREEN);