00001 #include "bandwipe.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
00015
00016
00017
00018
00019
00020 REGISTER_PLUGIN(BandWipeMain)
00021
00022
00023
00024
00025
00026 BandWipeCount::BandWipeCount(BandWipeMain *plugin,
00027 BandWipeWindow *window,
00028 int x,
00029 int y)
00030 : BC_TumbleTextBox(window,
00031 (int64_t)plugin->bands,
00032 (int64_t)0,
00033 (int64_t)1000,
00034 x,
00035 y,
00036 50)
00037 {
00038 this->plugin = plugin;
00039 this->window = window;
00040 }
00041
00042 int BandWipeCount::handle_event()
00043 {
00044 plugin->bands = atol(get_text());
00045 plugin->send_configure_change();
00046 return 0;
00047 }
00048
00049
00050 BandWipeIn::BandWipeIn(BandWipeMain *plugin,
00051 BandWipeWindow *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 BandWipeIn::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 BandWipeOut::BandWipeOut(BandWipeMain *plugin,
00073 BandWipeWindow *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 BandWipeOut::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 BandWipeWindow::BandWipeWindow(BandWipeMain *plugin, int x, int y)
00101 : BC_Window(plugin->gui_string,
00102 x,
00103 y,
00104 320,
00105 50,
00106 320,
00107 50,
00108 0,
00109 0,
00110 1)
00111 {
00112 this->plugin = plugin;
00113 }
00114
00115
00116 int BandWipeWindow::close_event()
00117 {
00118 set_done(1);
00119 return 1;
00120 }
00121
00122 void BandWipeWindow::create_objects()
00123 {
00124 int x = 10, y = 10;
00125 add_subwindow(new BC_Title(x, y, _("Bands:")));
00126 x += 50;
00127 count = new BandWipeCount(plugin,
00128 this,
00129 x,
00130 y);
00131 count->create_objects();
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 show_window();
00147 flush();
00148 }
00149
00150
00151
00152
00153 PLUGIN_THREAD_OBJECT(BandWipeMain, BandWipeThread, BandWipeWindow)
00154
00155
00156
00157
00158
00159
00160 BandWipeMain::BandWipeMain(PluginServer *server)
00161 : PluginVClient(server)
00162 {
00163 bands = 9;
00164 direction = 0;
00165 PLUGIN_CONSTRUCTOR_MACRO
00166 }
00167
00168 BandWipeMain::~BandWipeMain()
00169 {
00170 PLUGIN_DESTRUCTOR_MACRO
00171 }
00172
00173 char* BandWipeMain::plugin_title() { return N_("BandWipe"); }
00174 int BandWipeMain::is_video() { return 1; }
00175 int BandWipeMain::is_transition() { return 1; }
00176 int BandWipeMain::uses_gui() { return 1; }
00177
00178 SHOW_GUI_MACRO(BandWipeMain, BandWipeThread);
00179 SET_STRING_MACRO(BandWipeMain)
00180 RAISE_WINDOW_MACRO(BandWipeMain)
00181
00182
00183 VFrame* BandWipeMain::new_picon()
00184 {
00185 return new VFrame(picon_png);
00186 }
00187
00188 int BandWipeMain::load_defaults()
00189 {
00190 char directory[BCTEXTLEN];
00191
00192 sprintf(directory, "%sbandwipe.rc", BCASTDIR);
00193
00194
00195 defaults = new BC_Hash(directory);
00196 defaults->load();
00197
00198 bands = defaults->get("BANDS", bands);
00199 direction = defaults->get("DIRECTION", direction);
00200 return 0;
00201 }
00202
00203 int BandWipeMain::save_defaults()
00204 {
00205 defaults->update("BANDS", bands);
00206 defaults->update("DIRECTION", direction);
00207 defaults->save();
00208 return 0;
00209 }
00210
00211 void BandWipeMain::save_data(KeyFrame *keyframe)
00212 {
00213 FileXML output;
00214 output.set_shared_string(keyframe->data, MESSAGESIZE);
00215 output.tag.set_title("BANDWIPE");
00216 output.tag.set_property("BANDS", bands);
00217 output.tag.set_property("DIRECTION", direction);
00218 output.append_tag();
00219 output.tag.set_title("/BANDWIPE");
00220 output.append_tag();
00221 output.terminate_string();
00222 }
00223
00224 void BandWipeMain::read_data(KeyFrame *keyframe)
00225 {
00226 FileXML input;
00227
00228 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00229
00230 while(!input.read_tag())
00231 {
00232 if(input.tag.title_is("BANDWIPE"))
00233 {
00234 bands = input.tag.get_property("BANDS", bands);
00235 direction = input.tag.get_property("DIRECTION", direction);
00236 }
00237 }
00238 }
00239
00240 void BandWipeMain::load_configuration()
00241 {
00242 read_data(get_prev_keyframe(get_source_position()));
00243 }
00244
00245
00246
00247 #define BANDWIPE(type, components) \
00248 { \
00249 if(direction == 0) \
00250 { \
00251 int x = w * \
00252 PluginClient::get_source_position() / \
00253 PluginClient::get_total_len(); \
00254 \
00255 for(int i = 0; i < bands; i++) \
00256 { \
00257 for(int j = 0; j < band_h; j++) \
00258 { \
00259 int row = i * band_h + j; \
00260 \
00261 if(row >= 0 && row < h) \
00262 { \
00263 type *in_row = (type*)incoming->get_rows()[row]; \
00264 type *out_row = (type*)outgoing->get_rows()[row]; \
00265 \
00266 if(i % 2) \
00267 { \
00268 for(int k = 0; k < x; k++) \
00269 { \
00270 out_row[k * components + 0] = in_row[k * components + 0]; \
00271 out_row[k * components + 1] = in_row[k * components + 1]; \
00272 out_row[k * components + 2] = in_row[k * components + 2]; \
00273 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00274 } \
00275 } \
00276 else \
00277 { \
00278 for(int k = w - x; k < w; k++) \
00279 { \
00280 out_row[k * components + 0] = in_row[k * components + 0]; \
00281 out_row[k * components + 1] = in_row[k * components + 1]; \
00282 out_row[k * components + 2] = in_row[k * components + 2]; \
00283 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00284 } \
00285 } \
00286 } \
00287 } \
00288 } \
00289 } \
00290 else \
00291 { \
00292 int x = w - w * \
00293 PluginClient::get_source_position() / \
00294 PluginClient::get_total_len(); \
00295 \
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 for(int k = x; k < w; k++) \
00310 { \
00311 out_row[k * components + 0] = in_row[k * components + 0]; \
00312 out_row[k * components + 1] = in_row[k * components + 1]; \
00313 out_row[k * components + 2] = in_row[k * components + 2]; \
00314 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00315 } \
00316 } \
00317 else \
00318 { \
00319 for(int k = 0; k < w - x; k++) \
00320 { \
00321 out_row[k * components + 0] = in_row[k * components + 0]; \
00322 out_row[k * components + 1] = in_row[k * components + 1]; \
00323 out_row[k * components + 2] = in_row[k * components + 2]; \
00324 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00325 } \
00326 } \
00327 } \
00328 } \
00329 } \
00330 } \
00331 }
00332
00333
00334
00335 int BandWipeMain::process_realtime(VFrame *incoming, VFrame *outgoing)
00336 {
00337 load_configuration();
00338
00339 int w = incoming->get_w();
00340 int h = incoming->get_h();
00341 int band_h = ((bands == 0) ? h : (h / bands + 1));
00342
00343 switch(incoming->get_color_model())
00344 {
00345 case BC_RGB888:
00346 case BC_YUV888:
00347 BANDWIPE(unsigned char, 3)
00348 break;
00349 case BC_RGB_FLOAT:
00350 BANDWIPE(float, 3);
00351 break;
00352 case BC_RGBA8888:
00353 case BC_YUVA8888:
00354 BANDWIPE(unsigned char, 4)
00355 break;
00356 case BC_RGBA_FLOAT:
00357 BANDWIPE(float, 4);
00358 break;
00359 case BC_RGB161616:
00360 case BC_YUV161616:
00361 BANDWIPE(uint16_t, 3)
00362 break;
00363 case BC_RGBA16161616:
00364 case BC_YUVA16161616:
00365 BANDWIPE(uint16_t, 4)
00366 break;
00367 }
00368
00369 return 0;
00370 }