00001 #include "bandslide.h"
00002 #include "bcdisplayinfo.h"
00003 #include "bchash.h"
00004 #include "edl.inc"
00005 #include "filexml.h"
00006 #include "language.h"
00007 #include "overlayframe.h"
00008 #include "picon_png.h"
00009 #include "vframe.h"
00010
00011
00012 #include <stdint.h>
00013 #include <string.h>
00014 #include <libintl.h>
00015
00016
00017
00018
00019
00020
00021 REGISTER_PLUGIN(BandSlideMain)
00022
00023
00024
00025
00026
00027 BandSlideCount::BandSlideCount(BandSlideMain *plugin,
00028 BandSlideWindow *window,
00029 int x,
00030 int y)
00031 : BC_TumbleTextBox(window,
00032 (int64_t)plugin->bands,
00033 (int64_t)0,
00034 (int64_t)1000,
00035 x,
00036 y,
00037 50)
00038 {
00039 this->plugin = plugin;
00040 this->window = window;
00041 }
00042
00043 int BandSlideCount::handle_event()
00044 {
00045 plugin->bands = atol(get_text());
00046 plugin->send_configure_change();
00047 return 0;
00048 }
00049
00050 BandSlideIn::BandSlideIn(BandSlideMain *plugin,
00051 BandSlideWindow *window,
00052 int x,
00053 int y)
00054 : BC_Radial(x,
00055 y,
00056 plugin->direction == 0,
00057 _("In"))
00058 {
00059 this->plugin = plugin;
00060 this->window = window;
00061 }
00062
00063 int BandSlideIn::handle_event()
00064 {
00065 update(1);
00066 plugin->direction = 0;
00067 window->out->update(0);
00068 plugin->send_configure_change();
00069 return 0;
00070 }
00071
00072 BandSlideOut::BandSlideOut(BandSlideMain *plugin,
00073 BandSlideWindow *window,
00074 int x,
00075 int y)
00076 : BC_Radial(x,
00077 y,
00078 plugin->direction == 1,
00079 _("Out"))
00080 {
00081 this->plugin = plugin;
00082 this->window = window;
00083 }
00084
00085 int BandSlideOut::handle_event()
00086 {
00087 update(1);
00088 plugin->direction = 1;
00089 window->in->update(0);
00090 plugin->send_configure_change();
00091 return 0;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101 BandSlideWindow::BandSlideWindow(BandSlideMain *plugin, int x, int y)
00102 : BC_Window(plugin->gui_string,
00103 x,
00104 y,
00105 320,
00106 100,
00107 320,
00108 100,
00109 0,
00110 0,
00111 1)
00112 {
00113 this->plugin = plugin;
00114 }
00115
00116
00117 int BandSlideWindow::close_event()
00118 {
00119 set_done(1);
00120 return 1;
00121 }
00122
00123 void BandSlideWindow::create_objects()
00124 {
00125 int x = 10, y = 10;
00126 add_subwindow(new BC_Title(x, y, _("Bands:")));
00127 x += 50;
00128 count = new BandSlideCount(plugin,
00129 this,
00130 x,
00131 y);
00132 count->create_objects();
00133
00134 y += 30;
00135 x = 10;
00136 add_subwindow(new BC_Title(x, y, _("Direction:")));
00137 x += 100;
00138 add_subwindow(in = new BandSlideIn(plugin,
00139 this,
00140 x,
00141 y));
00142 x += 100;
00143 add_subwindow(out = new BandSlideOut(plugin,
00144 this,
00145 x,
00146 y));
00147
00148 show_window();
00149 flush();
00150 }
00151
00152
00153
00154
00155 PLUGIN_THREAD_OBJECT(BandSlideMain, BandSlideThread, BandSlideWindow)
00156
00157
00158
00159
00160
00161
00162 BandSlideMain::BandSlideMain(PluginServer *server)
00163 : PluginVClient(server)
00164 {
00165 bands = 9;
00166 direction = 0;
00167 PLUGIN_CONSTRUCTOR_MACRO
00168 }
00169
00170 BandSlideMain::~BandSlideMain()
00171 {
00172 PLUGIN_DESTRUCTOR_MACRO
00173 }
00174
00175 char* BandSlideMain::plugin_title() { return N_("BandSlide"); }
00176 int BandSlideMain::is_video() { return 1; }
00177 int BandSlideMain::is_transition() { return 1; }
00178 int BandSlideMain::uses_gui() { return 1; }
00179
00180 SHOW_GUI_MACRO(BandSlideMain, BandSlideThread);
00181 SET_STRING_MACRO(BandSlideMain)
00182 RAISE_WINDOW_MACRO(BandSlideMain)
00183
00184
00185 VFrame* BandSlideMain::new_picon()
00186 {
00187 return new VFrame(picon_png);
00188 }
00189
00190 int BandSlideMain::load_defaults()
00191 {
00192 char directory[BCTEXTLEN];
00193
00194 sprintf(directory, "%sbandslide.rc", BCASTDIR);
00195
00196
00197 defaults = new BC_Hash(directory);
00198 defaults->load();
00199
00200 bands = defaults->get("BANDS", bands);
00201 direction = defaults->get("DIRECTION", direction);
00202 return 0;
00203 }
00204
00205 int BandSlideMain::save_defaults()
00206 {
00207 defaults->update("BANDS", bands);
00208 defaults->update("DIRECTION", direction);
00209 defaults->save();
00210 return 0;
00211 }
00212
00213 void BandSlideMain::save_data(KeyFrame *keyframe)
00214 {
00215 FileXML output;
00216 output.set_shared_string(keyframe->data, MESSAGESIZE);
00217 output.tag.set_title("BANDSLIDE");
00218 output.tag.set_property("BANDS", bands);
00219 output.tag.set_property("DIRECTION", direction);
00220 output.append_tag();
00221 output.tag.set_title("/BANDSLIDE");
00222 output.append_tag();
00223 output.terminate_string();
00224 }
00225
00226 void BandSlideMain::read_data(KeyFrame *keyframe)
00227 {
00228 FileXML input;
00229
00230 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00231
00232 while(!input.read_tag())
00233 {
00234 if(input.tag.title_is("BANDSLIDE"))
00235 {
00236 bands = input.tag.get_property("BANDS", bands);
00237 direction = input.tag.get_property("DIRECTION", direction);
00238 }
00239 }
00240 }
00241
00242 void BandSlideMain::load_configuration()
00243 {
00244 read_data(get_prev_keyframe(get_source_position()));
00245 }
00246
00247
00248
00249 #define BANDSLIDE(type, components) \
00250 { \
00251 if(direction == 0) \
00252 { \
00253 int x = w * \
00254 PluginClient::get_source_position() / \
00255 PluginClient::get_total_len(); \
00256 for(int i = 0; i < bands; i++) \
00257 { \
00258 for(int j = 0; j < band_h; j++) \
00259 { \
00260 int row = i * band_h + j; \
00261 \
00262 if(row >= 0 && row < h) \
00263 { \
00264 type *in_row = (type*)incoming->get_rows()[row]; \
00265 type *out_row = (type*)outgoing->get_rows()[row]; \
00266 \
00267 if(i % 2) \
00268 { \
00269 for(int k = 0, l = w - x; k < x; k++, l++) \
00270 { \
00271 out_row[k * components + 0] = in_row[l * components + 0]; \
00272 out_row[k * components + 1] = in_row[l * components + 1]; \
00273 out_row[k * components + 2] = in_row[l * components + 2]; \
00274 if(components == 4) out_row[k * components + 3] = in_row[l * components + 3]; \
00275 } \
00276 } \
00277 else \
00278 { \
00279 for(int k = w - x, l = 0; k < w; k++, l++) \
00280 { \
00281 out_row[k * components + 0] = in_row[l * components + 0]; \
00282 out_row[k * components + 1] = in_row[l * components + 1]; \
00283 out_row[k * components + 2] = in_row[l * components + 2]; \
00284 if(components == 4) out_row[k * components + 3] = in_row[l * components + 3]; \
00285 } \
00286 } \
00287 } \
00288 } \
00289 } \
00290 } \
00291 else \
00292 { \
00293 int x = w - w * \
00294 PluginClient::get_source_position() / \
00295 PluginClient::get_total_len(); \
00296 for(int i = 0; i < bands; i++) \
00297 { \
00298 for(int j = 0; j < band_h; j++) \
00299 { \
00300 int row = i * band_h + j; \
00301 \
00302 if(row >= 0 && row < h) \
00303 { \
00304 type *in_row = (type*)incoming->get_rows()[row]; \
00305 type *out_row = (type*)outgoing->get_rows()[row]; \
00306 \
00307 if(i % 2) \
00308 { \
00309 int k, l; \
00310 for(k = 0, l = w - x; k < x; k++, l++) \
00311 { \
00312 out_row[k * components + 0] = out_row[l * components + 0]; \
00313 out_row[k * components + 1] = out_row[l * components + 1]; \
00314 out_row[k * components + 2] = out_row[l * components + 2]; \
00315 if(components == 4) out_row[k * components + 3] = out_row[l * components + 3]; \
00316 } \
00317 for( ; k < w; k++) \
00318 { \
00319 out_row[k * components + 0] = in_row[k * components + 0]; \
00320 out_row[k * components + 1] = in_row[k * components + 1]; \
00321 out_row[k * components + 2] = in_row[k * components + 2]; \
00322 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00323 } \
00324 } \
00325 else \
00326 { \
00327 for(int k = w - 1, l = x - 1; k >= w - x; k--, l--) \
00328 { \
00329 out_row[k * components + 0] = out_row[l * components + 0]; \
00330 out_row[k * components + 1] = out_row[l * components + 1]; \
00331 out_row[k * components + 2] = out_row[l * components + 2]; \
00332 if(components == 4) out_row[k * components + 3] = out_row[l * components + 3]; \
00333 } \
00334 for(int k = 0; k < w - x; k++) \
00335 { \
00336 out_row[k * components + 0] = in_row[k * components + 0]; \
00337 out_row[k * components + 1] = in_row[k * components + 1]; \
00338 out_row[k * components + 2] = in_row[k * components + 2]; \
00339 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00340 } \
00341 } \
00342 } \
00343 } \
00344 } \
00345 } \
00346 }
00347
00348
00349
00350 int BandSlideMain::process_realtime(VFrame *incoming, VFrame *outgoing)
00351 {
00352 load_configuration();
00353
00354 int w = incoming->get_w();
00355 int h = incoming->get_h();
00356 int band_h = ((bands == 0) ? h : (h / bands + 1));
00357
00358 switch(incoming->get_color_model())
00359 {
00360 case BC_RGB888:
00361 case BC_YUV888:
00362 BANDSLIDE(unsigned char, 3)
00363 break;
00364 case BC_RGB_FLOAT:
00365 BANDSLIDE(float, 3);
00366 break;
00367 case BC_RGBA8888:
00368 case BC_YUVA8888:
00369 BANDSLIDE(unsigned char, 4)
00370 break;
00371 case BC_RGBA_FLOAT:
00372 BANDSLIDE(float, 4);
00373 break;
00374 case BC_RGB161616:
00375 case BC_YUV161616:
00376 BANDSLIDE(uint16_t, 3)
00377 break;
00378 case BC_RGBA16161616:
00379 case BC_YUVA16161616:
00380 BANDSLIDE(uint16_t, 4)
00381 break;
00382 }
00383
00384 return 0;
00385 }