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, xS(300), yS(70), 0, 0, 1)
181 this->plugin = plugin;
184 RerouteWindow::~RerouteWindow()
188 void RerouteWindow::create_objects()
190 int xs5 = xS(5), xs10 = xS(10);
191 int ys10 = yS(10), ys30 = yS(30);
192 int x = xs10, y = ys10;
195 add_subwindow(title = new BC_Title(x, y, _("Target track:")));
197 int col2 = title->get_w() + xs5;
198 add_subwindow(output = new RerouteOutput(plugin,
201 output->create_objects();
204 add_subwindow(title = new BC_Title(x, y, _("Operation:")));
205 add_subwindow(operation = new RerouteOperation(plugin,
208 operation->create_objects();
221 RerouteOperation::RerouteOperation(Reroute *plugin,
227 RerouteConfig::operation_to_text(plugin->config.operation),
230 this->plugin = plugin;
233 void RerouteOperation::create_objects()
235 add_item(new BC_MenuItem(
236 RerouteConfig::operation_to_text(
237 RerouteConfig::REPLACE)));
238 add_item(new BC_MenuItem(
239 RerouteConfig::operation_to_text(
240 RerouteConfig::REPLACE_COMPONENTS)));
241 add_item(new BC_MenuItem(
242 RerouteConfig::operation_to_text(
243 RerouteConfig::REPLACE_ALPHA)));
246 int RerouteOperation::handle_event()
248 char *text = get_text();
251 RerouteConfig::operation_to_text(
252 RerouteConfig::REPLACE)))
253 plugin->config.operation = RerouteConfig::REPLACE;
256 RerouteConfig::operation_to_text(
257 RerouteConfig::REPLACE_COMPONENTS)))
258 plugin->config.operation = RerouteConfig::REPLACE_COMPONENTS;
261 RerouteConfig::operation_to_text(
262 RerouteConfig::REPLACE_ALPHA)))
263 plugin->config.operation = RerouteConfig::REPLACE_ALPHA;
265 plugin->send_configure_change();
270 RerouteOutput::RerouteOutput(Reroute *plugin,
276 RerouteConfig::output_to_text(plugin->config.output_track),
279 this->plugin = plugin;
282 void RerouteOutput::create_objects()
284 add_item(new BC_MenuItem(
285 RerouteConfig::output_to_text(
286 RerouteConfig::TOP)));
287 add_item(new BC_MenuItem(
288 RerouteConfig::output_to_text(
289 RerouteConfig::BOTTOM)));
292 int RerouteOutput::handle_event()
294 char *text = get_text();
297 RerouteConfig::output_to_text(
298 RerouteConfig::TOP)))
299 plugin->config.output_track = RerouteConfig::TOP;
302 RerouteConfig::output_to_text(
303 RerouteConfig::BOTTOM)))
304 plugin->config.output_track = RerouteConfig::BOTTOM;
306 plugin->send_configure_change();
314 /***** Register Plugin ***********************************/
317 REGISTER_PLUGIN(Reroute)
325 Reroute::Reroute(PluginServer *server)
326 : PluginVClient(server)
340 *****************************************/
341 template<class TYPE, int COMPONENTS>
345 void transfer(VFrame*, VFrame*, bool, bool) ;
348 template<class TYPE, int COMPONENTS>
349 void px_type<TYPE,COMPONENTS>::transfer(VFrame *source, VFrame *target, bool do_components, bool do_alpha)
350 //partially overwrite target data buffer
352 int w = target->get_w();
353 int h = source->get_h();
354 do_alpha = do_alpha && (COMPONENTS > 3); // only possible if we have alpha
356 for(int i = 0; i < h; i++)
358 TYPE *inpx = (TYPE*)source->get_rows()[i];
359 TYPE *outpx = (TYPE*)target->get_rows()[i];
361 for(int j = 0; j < w; j++)
380 int Reroute::process_buffer(VFrame **frame,
381 int64_t start_position,
384 load_configuration();
386 bool do_components = true, do_alpha = true;
387 switch(config.operation)
389 case RerouteConfig::REPLACE: break;
390 case RerouteConfig::REPLACE_ALPHA: do_components = false; break;
391 case RerouteConfig::REPLACE_COMPONENTS: do_alpha = false; break;
394 if(config.output_track == RerouteConfig::TOP)
396 input_track = get_total_buffers() - 1;
402 output_track = get_total_buffers() - 1;
406 // output buffers for source and target track
407 VFrame *source = frame[input_track];
408 VFrame *target = frame[output_track];
410 // input track always passed through unaltered
415 false ); // no OpenGL support
417 // no real operation necessary
418 // unless applied to multiple tracks....
419 if(get_total_buffers() <= 1)
422 if(config.operation == RerouteConfig::REPLACE)
424 target->copy_from(source);
429 // prepare data for output track
430 // (to be overidden partially)
437 switch(source->get_color_model())
440 px_type<float,3>::transfer(source,target, do_components,do_alpha);
443 px_type<float,4>::transfer(source,target, do_components,do_alpha);
447 px_type<unsigned char,3>::transfer(source,target, do_components,do_alpha);
451 px_type<unsigned char,4>::transfer(source,target, do_components,do_alpha);
455 px_type<uint16_t,3>::transfer(source,target, do_components,do_alpha);
457 case BC_RGBA16161616:
458 case BC_YUVA16161616:
459 px_type<uint16_t,4>::transfer(source,target, do_components,do_alpha);
473 const char* Reroute::plugin_title() { return N_("Reroute"); }
474 int Reroute::is_realtime() { return 1; }
475 int Reroute::is_multichannel() { return 1; }
481 NEW_WINDOW_MACRO(Reroute,RerouteWindow)
483 int Reroute::load_configuration()
485 KeyFrame *prev_keyframe;
486 prev_keyframe = get_prev_keyframe(get_source_position());
487 read_data(prev_keyframe);
492 void Reroute::save_data(KeyFrame *keyframe)
496 // write configuration data as XML text
497 output.set_shared_output(keyframe->xbuf);
498 output.tag.set_title("REROUTE");
499 output.tag.set_property("OPERATION", config.operation);
500 output.tag.set_property("OUTPUT_TRACK", config.output_track);
502 output.tag.set_title("/REROUTE");
504 output.terminate_string();
507 void Reroute::read_data(KeyFrame *keyframe)
510 input.set_shared_input(keyframe->xbuf);
512 while(!input.read_tag())
514 if(input.tag.title_is("REROUTE"))
516 config.operation = input.tag.get_property("OPERATION", config.operation);
517 config.output_track = input.tag.get_property("OUTPUT_TRACK", config.output_track);
522 void Reroute::update_gui()
526 RerouteWindow *window = (RerouteWindow *)thread->window;
527 window->lock_window("Reroute::update_gui");
528 window->operation->set_text(RerouteConfig::operation_to_text(config.operation));
529 window->output->set_text(RerouteConfig::output_to_text(config.output_track));
530 window->unlock_window();