00001 #include "clip.h"
00002 #include "filexml.h"
00003 #include "language.h"
00004 #include "picon_png.h"
00005 #include "scale.h"
00006 #include "scalewin.h"
00007
00008 #include <string.h>
00009
00010
00011 REGISTER_PLUGIN(ScaleMain)
00012
00013
00014
00015 ScaleConfig::ScaleConfig()
00016 {
00017 w = 1;
00018 h = 1;
00019 constrain = 0;
00020 }
00021
00022 void ScaleConfig::copy_from(ScaleConfig &src)
00023 {
00024 w = src.w;
00025 h = src.h;
00026 constrain = src.constrain;
00027 }
00028 int ScaleConfig::equivalent(ScaleConfig &src)
00029 {
00030 return EQUIV(w, src.w) &&
00031 EQUIV(h, src.h) &&
00032 constrain == src.constrain;
00033 }
00034
00035 void ScaleConfig::interpolate(ScaleConfig &prev,
00036 ScaleConfig &next,
00037 int64_t prev_frame,
00038 int64_t next_frame,
00039 int64_t current_frame)
00040 {
00041 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
00042 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
00043
00044 this->w = prev.w * prev_scale + next.w * next_scale;
00045 this->h = prev.h * prev_scale + next.h * next_scale;
00046 this->constrain = prev.constrain;
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056 ScaleMain::ScaleMain(PluginServer *server)
00057 : PluginVClient(server)
00058 {
00059 overlayer = 0;
00060 PLUGIN_CONSTRUCTOR_MACRO
00061 }
00062
00063 ScaleMain::~ScaleMain()
00064 {
00065 PLUGIN_DESTRUCTOR_MACRO
00066
00067 if(overlayer) delete overlayer;
00068 overlayer = 0;
00069 }
00070
00071 char* ScaleMain::plugin_title() { return N_("Scale"); }
00072 int ScaleMain::is_realtime() { return 1; }
00073
00074 NEW_PICON_MACRO(ScaleMain)
00075
00076 int ScaleMain::load_defaults()
00077 {
00078 char directory[1024], string[1024];
00079
00080 sprintf(directory, "%sscale.rc", BCASTDIR);
00081
00082
00083 defaults = new BC_Hash(directory);
00084 defaults->load();
00085
00086 config.w = defaults->get("WIDTH", config.w);
00087 config.h = defaults->get("HEIGHT", config.h);
00088 config.constrain = defaults->get("CONSTRAIN", config.constrain);
00089
00090 }
00091
00092 int ScaleMain::save_defaults()
00093 {
00094 defaults->update("WIDTH", config.w);
00095 defaults->update("HEIGHT", config.h);
00096 defaults->update("CONSTRAIN", config.constrain);
00097 defaults->save();
00098 }
00099
00100 LOAD_CONFIGURATION_MACRO(ScaleMain, ScaleConfig)
00101
00102
00103 void ScaleMain::save_data(KeyFrame *keyframe)
00104 {
00105 FileXML output;
00106
00107
00108 output.set_shared_string(keyframe->data, MESSAGESIZE);
00109
00110
00111 output.tag.set_title("SCALE");
00112 output.tag.set_property("WIDTH", config.w);
00113 output.tag.set_property("HEIGHT", config.h);
00114 output.append_tag();
00115
00116 if(config.constrain)
00117 {
00118 output.tag.set_title("CONSTRAIN");
00119 output.append_tag();
00120 output.tag.set_title("/CONSTRAIN");
00121 output.append_tag();
00122 }
00123 output.tag.set_title("/SCALE");
00124 output.append_tag();
00125 output.terminate_string();
00126
00127 }
00128
00129 void ScaleMain::read_data(KeyFrame *keyframe)
00130 {
00131 FileXML input;
00132
00133 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00134
00135 int result = 0;
00136 config.constrain = 0;
00137
00138 while(!result)
00139 {
00140 result = input.read_tag();
00141
00142 if(!result)
00143 {
00144 if(input.tag.title_is("SCALE"))
00145 {
00146 config.w = input.tag.get_property("WIDTH", config.w);
00147 config.h = input.tag.get_property("HEIGHT", config.h);
00148 }
00149 else
00150 if(input.tag.title_is("CONSTRAIN"))
00151 {
00152 config.constrain = 1;
00153 }
00154 }
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165 int ScaleMain::process_buffer(VFrame *frame,
00166 int64_t start_position,
00167 double frame_rate)
00168 {
00169 VFrame *input, *output;
00170
00171 input = frame;
00172 output = frame;
00173
00174 load_configuration();
00175
00176 read_frame(frame,
00177 0,
00178 start_position,
00179 frame_rate,
00180 get_use_opengl());
00181
00182
00183 if(config.w == 1 && config.h == 1)
00184 return 0;
00185
00186 if(get_use_opengl()) return run_opengl();
00187
00188 VFrame *temp_frame = new_temp(frame->get_w(),
00189 frame->get_h(),
00190 frame->get_color_model());
00191 temp_frame->copy_from(frame);
00192 input = temp_frame;
00193
00194 if(!overlayer)
00195 {
00196 overlayer = new OverlayFrame(smp + 1);
00197 }
00198
00199
00200
00201 float in_x1, in_x2, in_y1, in_y2, out_x1, out_x2, out_y1, out_y2;
00202 calculate_transfer(output,
00203 in_x1,
00204 in_x2,
00205 in_y1,
00206 in_y2,
00207 out_x1,
00208 out_x2,
00209 out_y1,
00210 out_y2);
00211 output->clear_frame();
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 overlayer->overlay(output,
00228 input,
00229 in_x1,
00230 in_y1,
00231 in_x2,
00232 in_y2,
00233 out_x1,
00234 out_y1,
00235 out_x2,
00236 out_y2,
00237 1,
00238 TRANSFER_REPLACE,
00239 get_interpolation_type());
00240
00241 return 0;
00242 }
00243
00244 void ScaleMain::calculate_transfer(VFrame *frame,
00245 float &in_x1,
00246 float &in_x2,
00247 float &in_y1,
00248 float &in_y2,
00249 float &out_x1,
00250 float &out_x2,
00251 float &out_y1,
00252 float &out_y2)
00253 {
00254 float center_x, center_y;
00255 center_x = (float)frame->get_w() / 2;
00256 center_y = (float)frame->get_h() / 2;
00257 in_x1 = 0;
00258 in_x2 = frame->get_w();
00259 in_y1 = 0;
00260 in_y2 = frame->get_h();
00261 out_x1 = (float)center_x - (float)frame->get_w() * config.w / 2;
00262 out_x2 = (float)center_x + (float)frame->get_w() * config.w / 2;
00263 out_y1 = (float)center_y - (float)frame->get_h() * config.h / 2;
00264 out_y2 = (float)center_y + (float)frame->get_h() * config.h / 2;
00265
00266
00267
00268 if(out_x1 < 0)
00269 {
00270 in_x1 += -out_x1 / config.w;
00271 out_x1 = 0;
00272 }
00273
00274 if(out_x2 > frame->get_w())
00275 {
00276 in_x2 -= (out_x2 - frame->get_w()) / config.w;
00277 out_x2 = frame->get_w();
00278 }
00279
00280 if(out_y1 < 0)
00281 {
00282 in_y1 += -out_y1 / config.h;
00283 out_y1 = 0;
00284 }
00285
00286 if(out_y2 > frame->get_h())
00287 {
00288 in_y2 -= (out_y2 - frame->get_h()) / config.h;
00289 out_y2 = frame->get_h();
00290 }
00291 }
00292
00293 int ScaleMain::handle_opengl()
00294 {
00295 #ifdef HAVE_GL
00296 float in_x1, in_x2, in_y1, in_y2, out_x1, out_x2, out_y1, out_y2;
00297 calculate_transfer(get_output(),
00298 in_x1,
00299 in_x2,
00300 in_y1,
00301 in_y2,
00302 out_x1,
00303 out_x2,
00304 out_y1,
00305 out_y2);
00306
00307 get_output()->to_texture();
00308 get_output()->enable_opengl();
00309 get_output()->init_screen();
00310 get_output()->clear_pbuffer();
00311 get_output()->bind_texture(0);
00312 get_output()->draw_texture(in_x1,
00313 in_y1,
00314 in_x2,
00315 in_y2,
00316 out_x1,
00317 out_y1,
00318 out_x2,
00319 out_y2);
00320 get_output()->set_opengl_state(VFrame::SCREEN);
00321 #endif
00322 }
00323
00324
00325
00326 SHOW_GUI_MACRO(ScaleMain, ScaleThread)
00327 RAISE_WINDOW_MACRO(ScaleMain)
00328 SET_STRING_MACRO(ScaleMain)
00329
00330 void ScaleMain::update_gui()
00331 {
00332 if(thread)
00333 {
00334 load_configuration();
00335 thread->window->lock_window();
00336 thread->window->width->update(config.w);
00337 thread->window->height->update(config.h);
00338 thread->window->constrain->update(config.constrain);
00339 thread->window->unlock_window();
00340 }
00341 }
00342
00343
00344