1 #include "bcdisplayinfo.h"
7 #include "pluginvclient.h"
17 #define _(String) gettext(String)
18 #define gettext_noop(String) String
19 #define N_(String) gettext_noop (String)
26 class ShiftInterlaceWindow;
27 class ShiftInterlaceMain;
29 class ShiftInterlaceConfig
32 ShiftInterlaceConfig();
34 int equivalent(ShiftInterlaceConfig &that);
35 void copy_from(ShiftInterlaceConfig &that);
36 void interpolate(ShiftInterlaceConfig &prev,
37 ShiftInterlaceConfig &next,
48 class ShiftInterlaceOdd : public BC_ISlider
51 ShiftInterlaceOdd(ShiftInterlaceMain *plugin, int x, int y);
53 ShiftInterlaceMain *plugin;
56 class ShiftInterlaceEven : public BC_ISlider
59 ShiftInterlaceEven(ShiftInterlaceMain *plugin, int x, int y);
61 ShiftInterlaceMain *plugin;
64 class ShiftInterlaceWindow : public BC_Window
67 ShiftInterlaceWindow(ShiftInterlaceMain *plugin, int x, int y);
69 void create_objects();
72 ShiftInterlaceOdd *odd_offset;
73 ShiftInterlaceEven *even_offset;
74 ShiftInterlaceMain *plugin;
78 PLUGIN_THREAD_HEADER(ShiftInterlaceMain, ShiftInterlaceThread, ShiftInterlaceWindow)
83 class ShiftInterlaceMain : public PluginVClient
86 ShiftInterlaceMain(PluginServer *server);
87 ~ShiftInterlaceMain();
89 // required for all realtime plugins
90 int process_realtime(VFrame *input_ptr, VFrame *output_ptr);
98 void save_data(KeyFrame *keyframe);
99 void read_data(KeyFrame *keyframe);
100 int load_configuration();
105 void shift_row(VFrame *input_frame,
106 VFrame *output_frame,
113 ShiftInterlaceConfig config;
114 ShiftInterlaceThread *thread;
121 PluginClient* new_plugin(PluginServer *server)
123 return new ShiftInterlaceMain(server);
129 ShiftInterlaceConfig::ShiftInterlaceConfig()
136 int ShiftInterlaceConfig::equivalent(ShiftInterlaceConfig &that)
138 return (odd_offset == that.odd_offset &&
139 even_offset == that.even_offset);
142 void ShiftInterlaceConfig::copy_from(ShiftInterlaceConfig &that)
144 odd_offset = that.odd_offset;
145 even_offset = that.even_offset;
148 void ShiftInterlaceConfig::interpolate(ShiftInterlaceConfig &prev,
149 ShiftInterlaceConfig &next,
154 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
155 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
157 this->odd_offset = (int)(prev.odd_offset * prev_scale + next.odd_offset * next_scale);
158 this->even_offset = (int)(prev.even_offset * prev_scale + next.even_offset * next_scale);
166 ShiftInterlaceWindow::ShiftInterlaceWindow(ShiftInterlaceMain *plugin,
169 : BC_Window(plugin->gui_string,
180 this->plugin = plugin;
184 void ShiftInterlaceWindow::create_objects()
189 add_subwindow(new BC_Title(x, y, _("Odd offset:")));
190 add_subwindow(odd_offset = new ShiftInterlaceOdd(plugin, x + 90, y));
192 add_subwindow(new BC_Title(x, y, _("Even offset:")));
193 add_subwindow(even_offset = new ShiftInterlaceEven(plugin, x + 90, y));
199 WINDOW_CLOSE_EVENT(ShiftInterlaceWindow)
201 ShiftInterlaceOdd::ShiftInterlaceOdd(ShiftInterlaceMain *plugin, int x, int y)
209 plugin->config.odd_offset)
211 this->plugin = plugin;
213 int ShiftInterlaceOdd::handle_event()
215 plugin->config.odd_offset = get_value();
216 plugin->send_configure_change();
223 ShiftInterlaceEven::ShiftInterlaceEven(ShiftInterlaceMain *plugin, int x, int y)
231 plugin->config.even_offset)
233 this->plugin = plugin;
237 int ShiftInterlaceEven::handle_event()
239 plugin->config.even_offset = get_value();
240 plugin->send_configure_change();
251 PLUGIN_THREAD_OBJECT(ShiftInterlaceMain, ShiftInterlaceThread, ShiftInterlaceWindow)
255 ShiftInterlaceMain::ShiftInterlaceMain(PluginServer *server)
256 : PluginVClient(server)
258 PLUGIN_CONSTRUCTOR_MACRO
261 ShiftInterlaceMain::~ShiftInterlaceMain()
263 PLUGIN_DESTRUCTOR_MACRO
267 int ShiftInterlaceMain::is_realtime()
272 char* ShiftInterlaceMain::plugin_title()
274 return _("ShiftInterlace channels");
278 SHOW_GUI_MACRO(ShiftInterlaceMain, ShiftInterlaceThread)
280 NEW_PICON_MACRO(ShiftInterlaceMain)
282 SET_STRING_MACRO(ShiftInterlaceMain)
284 LOAD_CONFIGURATION_MACRO(ShiftInterlaceMain, ShiftInterlaceConfig)
286 RAISE_WINDOW_MACRO(ShiftInterlaceMain)
289 int ShiftInterlaceMain::load_defaults()
291 char directory[1024], string[1024];
292 // set the default directory
293 sprintf(directory, "%sshiftinterlace.rc", BCASTDIR);
296 defaults = new Defaults(directory);
299 config.odd_offset = defaults->get("ODD_OFFSET", config.odd_offset);
300 config.even_offset = defaults->get("EVEN_OFFSET", config.even_offset);
304 int ShiftInterlaceMain::save_defaults()
306 defaults->update("ODD_OFFSET", config.odd_offset);
307 defaults->update("EVEN_OFFSET", config.even_offset);
312 void ShiftInterlaceMain::save_data(KeyFrame *keyframe)
316 // cause data to be stored directly in text
317 output.set_shared_string(keyframe->data, MESSAGESIZE);
318 output.tag.set_title("SHIFTINTERLACE");
319 output.tag.set_property("ODD_OFFSET", config.odd_offset);
320 output.tag.set_property("EVEN_OFFSET", config.even_offset);
322 output.append_newline();
323 output.terminate_string();
324 // data is now in *text
327 void ShiftInterlaceMain::read_data(KeyFrame *keyframe)
331 input.set_shared_string(keyframe->data, strlen(keyframe->data));
337 result = input.read_tag();
341 if(input.tag.title_is("SHIFTINTERLACE"))
343 config.odd_offset = input.tag.get_property("ODD_OFFSET", config.odd_offset);
344 config.even_offset = input.tag.get_property("EVEN_OFFSET", config.even_offset);
350 void ShiftInterlaceMain::update_gui()
354 load_configuration();
355 thread->window->lock_window();
356 thread->window->odd_offset->update(config.odd_offset);
357 thread->window->even_offset->update(config.even_offset);
358 thread->window->unlock_window();
363 #define SHIFT_ROW_MACRO(components, type, chroma_offset) \
365 type *input_row = (type*)input_frame->get_rows()[row]; \
366 type *output_row = (type*)output_frame->get_rows()[row]; \
371 for(i = 0, j = -offset; \
375 output_row[i * components + 0] = input_row[j * components + 0]; \
376 output_row[i * components + 1] = input_row[j * components + 1]; \
377 output_row[i * components + 2] = input_row[j * components + 2]; \
378 if(components == 4) output_row[i * components + 3] = input_row[j * components + 3]; \
383 output_row[i * components + 0] = 0; \
384 output_row[i * components + 1] = chroma_offset; \
385 output_row[i * components + 2] = chroma_offset; \
386 if(components == 4) output_row[i * components + 3] = 0; \
392 for(i = w - offset - 1, j = w - 1; \
397 output_row[j * components + 0] = input_row[i * components + 0]; \
398 output_row[j * components + 1] = input_row[i * components + 1]; \
399 output_row[j * components + 2] = input_row[i * components + 2]; \
400 if(components == 4) output_row[j * components + 3] = input_row[i * components + 3]; \
403 for( ; j >= 0; j--) \
405 output_row[j * components + 0] = 0; \
406 output_row[j * components + 1] = chroma_offset; \
407 output_row[j * components + 2] = chroma_offset; \
408 if(components == 4) output_row[j * components + 3] = 0; \
414 void ShiftInterlaceMain::shift_row(VFrame *input_frame,
415 VFrame *output_frame,
419 int w = input_frame->get_w();
420 switch(input_frame->get_color_model())
423 SHIFT_ROW_MACRO(3, unsigned char, 0x0)
426 SHIFT_ROW_MACRO(3, unsigned char, 0x80)
429 SHIFT_ROW_MACRO(4, unsigned char, 0x0)
432 SHIFT_ROW_MACRO(4, unsigned char, 0x80)
435 SHIFT_ROW_MACRO(3, uint16_t, 0x0)
438 SHIFT_ROW_MACRO(3, uint16_t, 0x8000)
440 case BC_RGBA16161616:
441 SHIFT_ROW_MACRO(4, uint16_t, 0x0)
443 case BC_YUVA16161616:
444 SHIFT_ROW_MACRO(4, uint16_t, 0x8000)
449 int ShiftInterlaceMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
451 load_configuration();
453 int h = input_ptr->get_h();
454 for(int i = 0; i < h; i++)
457 shift_row(input_ptr, output_ptr, config.even_offset, i);
459 shift_row(input_ptr, output_ptr, config.odd_offset, i);