4 * Copyright (C) 2007 Hermann Vosseler
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcdisplayinfo.h"
29 #include "overlayframe.h"
30 #include "pluginvclient.h"
48 static const char* operation_to_text(int operation);
57 static const char* output_to_text(int output_track);
71 class RerouteOperation : public BC_PopupMenu
74 RerouteOperation(Reroute *plugin,
77 void create_objects();
82 class RerouteOutput : public BC_PopupMenu
85 RerouteOutput(Reroute *plugin,
88 void create_objects();
94 class RerouteWindow : public PluginClientWindow
97 RerouteWindow(Reroute *plugin);
100 void create_objects();
103 RerouteOperation *operation;
104 RerouteOutput *output;
111 class Reroute : public PluginVClient
114 Reroute(PluginServer *server);
118 PLUGIN_CLASS_MEMBERS(RerouteConfig);
120 int process_buffer(VFrame **frame, int64_t start_position, double frame_rate);
122 int is_multichannel();
123 void save_data(KeyFrame *keyframe);
124 void read_data(KeyFrame *keyframe);
142 RerouteConfig::RerouteConfig()
144 operation = RerouteConfig::REPLACE;
145 output_track = RerouteConfig::TOP;
149 const char* RerouteConfig::operation_to_text(int operation)
153 case RerouteConfig::REPLACE: return _("replace Target");
154 case RerouteConfig::REPLACE_COMPONENTS: return _("Components only");
155 case RerouteConfig::REPLACE_ALPHA: return _("Alpha replace");
160 const char* RerouteConfig::output_to_text(int output_track)
164 case RerouteConfig::TOP: return _("Top");
165 case RerouteConfig::BOTTOM: return _("Bottom");
178 RerouteWindow::RerouteWindow(Reroute *plugin)
179 : PluginClientWindow(plugin, 300, 160, 0, 0, 1)
181 this->plugin = plugin;
184 RerouteWindow::~RerouteWindow()
188 void RerouteWindow::create_objects()
193 add_subwindow(title = new BC_Title(x, y, _("Target track:")));
195 int col2 = title->get_w() + 5;
196 add_subwindow(output = new RerouteOutput(plugin,
199 output->create_objects();
202 add_subwindow(title = new BC_Title(x, y, _("Operation:")));
203 add_subwindow(operation = new RerouteOperation(plugin,
206 operation->create_objects();
219 RerouteOperation::RerouteOperation(Reroute *plugin,
225 RerouteConfig::operation_to_text(plugin->config.operation),
228 this->plugin = plugin;
231 void RerouteOperation::create_objects()
233 add_item(new BC_MenuItem(
234 RerouteConfig::operation_to_text(
235 RerouteConfig::REPLACE)));
236 add_item(new BC_MenuItem(
237 RerouteConfig::operation_to_text(
238 RerouteConfig::REPLACE_COMPONENTS)));
239 add_item(new BC_MenuItem(
240 RerouteConfig::operation_to_text(
241 RerouteConfig::REPLACE_ALPHA)));
244 int RerouteOperation::handle_event()
246 char *text = get_text();
249 RerouteConfig::operation_to_text(
250 RerouteConfig::REPLACE)))
251 plugin->config.operation = RerouteConfig::REPLACE;
254 RerouteConfig::operation_to_text(
255 RerouteConfig::REPLACE_COMPONENTS)))
256 plugin->config.operation = RerouteConfig::REPLACE_COMPONENTS;
259 RerouteConfig::operation_to_text(
260 RerouteConfig::REPLACE_ALPHA)))
261 plugin->config.operation = RerouteConfig::REPLACE_ALPHA;
263 plugin->send_configure_change();
268 RerouteOutput::RerouteOutput(Reroute *plugin,
274 RerouteConfig::output_to_text(plugin->config.output_track),
277 this->plugin = plugin;
280 void RerouteOutput::create_objects()
282 add_item(new BC_MenuItem(
283 RerouteConfig::output_to_text(
284 RerouteConfig::TOP)));
285 add_item(new BC_MenuItem(
286 RerouteConfig::output_to_text(
287 RerouteConfig::BOTTOM)));
290 int RerouteOutput::handle_event()
292 char *text = get_text();
295 RerouteConfig::output_to_text(
296 RerouteConfig::TOP)))
297 plugin->config.output_track = RerouteConfig::TOP;
300 RerouteConfig::output_to_text(
301 RerouteConfig::BOTTOM)))
302 plugin->config.output_track = RerouteConfig::BOTTOM;
304 plugin->send_configure_change();
312 /***** Register Plugin ***********************************/
315 REGISTER_PLUGIN(Reroute)
323 Reroute::Reroute(PluginServer *server)
324 : PluginVClient(server)
338 *****************************************/
339 template<class TYPE, int COMPONENTS>
343 void transfer(VFrame*, VFrame*, bool, bool) ;
346 template<class TYPE, int COMPONENTS>
347 void px_type<TYPE,COMPONENTS>::transfer(VFrame *source, VFrame *target, bool do_components, bool do_alpha)
348 //partially overwrite target data buffer
350 int w = target->get_w();
351 int h = source->get_h();
352 do_alpha = do_alpha && (COMPONENTS > 3); // only possible if we have alpha
354 for(int i = 0; i < h; i++)
356 TYPE *inpx = (TYPE*)source->get_rows()[i];
357 TYPE *outpx = (TYPE*)target->get_rows()[i];
359 for(int j = 0; j < w; j++)
378 int Reroute::process_buffer(VFrame **frame,
379 int64_t start_position,
382 load_configuration();
384 bool do_components = true, do_alpha = true;
385 switch(config.operation)
387 case RerouteConfig::REPLACE: break;
388 case RerouteConfig::REPLACE_ALPHA: do_components = false; break;
389 case RerouteConfig::REPLACE_COMPONENTS: do_alpha = false; break;
392 if(config.output_track == RerouteConfig::TOP)
394 input_track = get_total_buffers() - 1;
400 output_track = get_total_buffers() - 1;
404 // output buffers for source and target track
405 VFrame *source = frame[input_track];
406 VFrame *target = frame[output_track];
408 // input track always passed through unaltered
413 false ); // no OpenGL support
415 // no real operation necessary
416 // unless applied to multiple tracks....
417 if(get_total_buffers() <= 1)
420 if(config.operation == RerouteConfig::REPLACE)
422 target->copy_from(source);
427 // prepare data for output track
428 // (to be overidden partially)
435 switch(source->get_color_model())
438 px_type<float,3>::transfer(source,target, do_components,do_alpha);
441 px_type<float,4>::transfer(source,target, do_components,do_alpha);
445 px_type<unsigned char,3>::transfer(source,target, do_components,do_alpha);
449 px_type<unsigned char,4>::transfer(source,target, do_components,do_alpha);
453 px_type<uint16_t,3>::transfer(source,target, do_components,do_alpha);
455 case BC_RGBA16161616:
456 case BC_YUVA16161616:
457 px_type<uint16_t,4>::transfer(source,target, do_components,do_alpha);
471 const char* Reroute::plugin_title() { return _("Reroute"); }
472 int Reroute::is_realtime() { return 1; }
473 int Reroute::is_multichannel() { return 1; }
479 NEW_WINDOW_MACRO(Reroute,RerouteWindow)
481 int Reroute::load_configuration()
483 KeyFrame *prev_keyframe;
484 prev_keyframe = get_prev_keyframe(get_source_position());
485 read_data(prev_keyframe);
490 void Reroute::save_data(KeyFrame *keyframe)
494 // write configuration data as XML text
495 output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
496 output.tag.set_title("REROUTE");
497 output.tag.set_property("OPERATION", config.operation);
498 output.tag.set_property("OUTPUT_TRACK", config.output_track);
500 output.tag.set_title("/REROUTE");
502 output.terminate_string();
505 void Reroute::read_data(KeyFrame *keyframe)
508 input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
510 while(!input.read_tag())
512 if(input.tag.title_is("REROUTE"))
514 config.operation = input.tag.get_property("OPERATION", config.operation);
515 config.output_track = input.tag.get_property("OUTPUT_TRACK", config.output_track);
520 void Reroute::update_gui()
524 RerouteWindow *window = (RerouteWindow *)thread->window;
525 window->lock_window("Reroute::update_gui");
526 window->operation->set_text(RerouteConfig::operation_to_text(config.operation));
527 window->output->set_text(RerouteConfig::output_to_text(config.output_track));
528 window->unlock_window();