00001 #include "bcdisplayinfo.h"
00002 #include "bchash.h"
00003 #include "edl.inc"
00004 #include "filexml.h"
00005 #include "language.h"
00006 #include "overlayframe.h"
00007 #include "picon_png.h"
00008 #include "vframe.h"
00009 #include "wipe.h"
00010
00011
00012 #include <stdint.h>
00013 #include <string.h>
00014
00015
00016 REGISTER_PLUGIN(WipeMain)
00017
00018
00019
00020
00021
00022 WipeLeft::WipeLeft(WipeMain *plugin,
00023 WipeWindow *window,
00024 int x,
00025 int y)
00026 : BC_Radial(x,
00027 y,
00028 plugin->direction == 0,
00029 _("Left"))
00030 {
00031 this->plugin = plugin;
00032 this->window = window;
00033 }
00034
00035 int WipeLeft::handle_event()
00036 {
00037 update(1);
00038 plugin->direction = 0;
00039 window->right->update(0);
00040 plugin->send_configure_change();
00041 return 0;
00042 }
00043
00044 WipeRight::WipeRight(WipeMain *plugin,
00045 WipeWindow *window,
00046 int x,
00047 int y)
00048 : BC_Radial(x,
00049 y,
00050 plugin->direction == 1,
00051 _("Right"))
00052 {
00053 this->plugin = plugin;
00054 this->window = window;
00055 }
00056
00057 int WipeRight::handle_event()
00058 {
00059 update(1);
00060 plugin->direction = 1;
00061 window->left->update(0);
00062 plugin->send_configure_change();
00063 return 0;
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073 WipeWindow::WipeWindow(WipeMain *plugin, int x, int y)
00074 : BC_Window(plugin->gui_string,
00075 x,
00076 y,
00077 320,
00078 50,
00079 320,
00080 50,
00081 0,
00082 0,
00083 1)
00084 {
00085 this->plugin = plugin;
00086 }
00087
00088
00089 int WipeWindow::close_event()
00090 {
00091 set_done(1);
00092 return 1;
00093 }
00094
00095 void WipeWindow::create_objects()
00096 {
00097 int x = 10, y = 10;
00098 add_subwindow(new BC_Title(x, y, _("Direction:")));
00099 x += 100;
00100 add_subwindow(left = new WipeLeft(plugin,
00101 this,
00102 x,
00103 y));
00104 x += 100;
00105 add_subwindow(right = new WipeRight(plugin,
00106 this,
00107 x,
00108 y));
00109 show_window();
00110 flush();
00111 }
00112
00113
00114
00115
00116 PLUGIN_THREAD_OBJECT(WipeMain, WipeThread, WipeWindow)
00117
00118
00119
00120
00121
00122
00123 WipeMain::WipeMain(PluginServer *server)
00124 : PluginVClient(server)
00125 {
00126 direction = 0;
00127 PLUGIN_CONSTRUCTOR_MACRO
00128 }
00129
00130 WipeMain::~WipeMain()
00131 {
00132 PLUGIN_DESTRUCTOR_MACRO
00133 }
00134
00135 char* WipeMain::plugin_title() { return N_("Wipe"); }
00136 int WipeMain::is_video() { return 1; }
00137 int WipeMain::is_transition() { return 1; }
00138 int WipeMain::uses_gui() { return 1; }
00139
00140 SHOW_GUI_MACRO(WipeMain, WipeThread);
00141 SET_STRING_MACRO(WipeMain)
00142 RAISE_WINDOW_MACRO(WipeMain)
00143
00144
00145 VFrame* WipeMain::new_picon()
00146 {
00147 return new VFrame(picon_png);
00148 }
00149
00150 int WipeMain::load_defaults()
00151 {
00152 char directory[BCTEXTLEN];
00153
00154 sprintf(directory, "%swipe.rc", BCASTDIR);
00155
00156
00157 defaults = new BC_Hash(directory);
00158 defaults->load();
00159
00160 direction = defaults->get("DIRECTION", direction);
00161 return 0;
00162 }
00163
00164 int WipeMain::save_defaults()
00165 {
00166 defaults->update("DIRECTION", direction);
00167 defaults->save();
00168 return 0;
00169 }
00170
00171 void WipeMain::save_data(KeyFrame *keyframe)
00172 {
00173 FileXML output;
00174 output.set_shared_string(keyframe->data, MESSAGESIZE);
00175 output.tag.set_title("WIPE");
00176 output.tag.set_property("DIRECTION", direction);
00177 output.append_tag();
00178 output.tag.set_title("/WIPE");
00179 output.append_tag();
00180 output.terminate_string();
00181 }
00182
00183 void WipeMain::read_data(KeyFrame *keyframe)
00184 {
00185 FileXML input;
00186
00187 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00188
00189 while(!input.read_tag())
00190 {
00191 if(input.tag.title_is("WIPE"))
00192 {
00193 direction = input.tag.get_property("DIRECTION", direction);
00194 }
00195 }
00196 }
00197
00198 void WipeMain::load_configuration()
00199 {
00200 read_data(get_prev_keyframe(get_source_position()));
00201 }
00202
00203
00204
00205
00206
00207
00208 #define WIPE(type, components) \
00209 { \
00210 if(direction == 0) \
00211 { \
00212 for(int j = 0; j < h; j++) \
00213 { \
00214 type *in_row = (type*)incoming->get_rows()[j]; \
00215 type *out_row = (type*)outgoing->get_rows()[j]; \
00216 int x = incoming->get_w() * \
00217 PluginClient::get_source_position() / \
00218 PluginClient::get_total_len(); \
00219 \
00220 for(int k = 0; k < x; k++) \
00221 { \
00222 out_row[k * components + 0] = in_row[k * components + 0]; \
00223 out_row[k * components + 1] = in_row[k * components + 1]; \
00224 out_row[k * components + 2] = in_row[k * components + 2]; \
00225 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00226 } \
00227 } \
00228 } \
00229 else \
00230 { \
00231 for(int j = 0; j < h; j++) \
00232 { \
00233 type *in_row = (type*)incoming->get_rows()[j]; \
00234 type *out_row = (type*)outgoing->get_rows()[j]; \
00235 int x = incoming->get_w() - incoming->get_w() * \
00236 PluginClient::get_source_position() / \
00237 PluginClient::get_total_len(); \
00238 \
00239 for(int k = x; k < w; k++) \
00240 { \
00241 out_row[k * components + 0] = in_row[k * components + 0]; \
00242 out_row[k * components + 1] = in_row[k * components + 1]; \
00243 out_row[k * components + 2] = in_row[k * components + 2]; \
00244 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
00245 } \
00246 } \
00247 } \
00248 }
00249
00250
00251
00252
00253
00254 int WipeMain::process_realtime(VFrame *incoming, VFrame *outgoing)
00255 {
00256 load_configuration();
00257
00258 int w = incoming->get_w();
00259 int h = incoming->get_h();
00260
00261
00262 switch(incoming->get_color_model())
00263 {
00264 case BC_RGB_FLOAT:
00265 WIPE(float, 3)
00266 break;
00267 case BC_RGB888:
00268 case BC_YUV888:
00269 WIPE(unsigned char, 3)
00270 break;
00271 case BC_RGBA_FLOAT:
00272 WIPE(float, 4)
00273 break;
00274 case BC_RGBA8888:
00275 case BC_YUVA8888:
00276 WIPE(unsigned char, 4)
00277 break;
00278 case BC_RGB161616:
00279 case BC_YUV161616:
00280 WIPE(uint16_t, 3)
00281 break;
00282 case BC_RGBA16161616:
00283 case BC_YUVA16161616:
00284 WIPE(uint16_t, 4)
00285 break;
00286 }
00287 return 0;
00288 }