X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Freroute%2Freroute.C;fp=cinelerra-5.1%2Fplugins%2Freroute%2Freroute.C;h=d4ac373b0c9d5ee8a08a762b4b4d165ddea6441a;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/reroute/reroute.C b/cinelerra-5.1/plugins/reroute/reroute.C new file mode 100644 index 00000000..d4ac373b --- /dev/null +++ b/cinelerra-5.1/plugins/reroute/reroute.C @@ -0,0 +1,530 @@ + +/* + * CINELERRA + * Copyright (C) 2007 Hermann Vosseler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "bcdisplayinfo.h" +#include "clip.h" +#include "bchash.h" +#include "filexml.h" +#include "guicast.h" +#include "keyframe.h" +#include "language.h" +#include "overlayframe.h" +#include "pluginvclient.h" +#include "vframe.h" + +#include +#include + + +class Reroute; +class RerouteWindow; + + +class RerouteConfig +{ +public: + RerouteConfig(); + + + + static const char* operation_to_text(int operation); + int operation; + enum + { + REPLACE, + REPLACE_COMPONENTS, + REPLACE_ALPHA + }; + + static const char* output_to_text(int output_track); + int output_track; + enum + { + TOP, + BOTTOM + }; +}; + + + + + + +class RerouteOperation : public BC_PopupMenu +{ +public: + RerouteOperation(Reroute *plugin, + int x, + int y); + void create_objects(); + int handle_event(); + Reroute *plugin; +}; + +class RerouteOutput : public BC_PopupMenu +{ +public: + RerouteOutput(Reroute *plugin, + int x, + int y); + void create_objects(); + int handle_event(); + Reroute *plugin; +}; + + +class RerouteWindow : public PluginClientWindow +{ +public: + RerouteWindow(Reroute *plugin); + ~RerouteWindow(); + + void create_objects(); + + Reroute *plugin; + RerouteOperation *operation; + RerouteOutput *output; +}; + + + + + +class Reroute : public PluginVClient +{ +public: + Reroute(PluginServer *server); + ~Reroute(); + + + PLUGIN_CLASS_MEMBERS(RerouteConfig); + + int process_buffer(VFrame **frame, int64_t start_position, double frame_rate); + int is_realtime(); + int is_multichannel(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + void update_gui(); + + int output_track; + int input_track; +}; + + + + + + + + + + + + +RerouteConfig::RerouteConfig() +{ + operation = RerouteConfig::REPLACE; + output_track = RerouteConfig::TOP; +} + + +const char* RerouteConfig::operation_to_text(int operation) +{ + switch(operation) + { + case RerouteConfig::REPLACE: return _("replace Target"); + case RerouteConfig::REPLACE_COMPONENTS: return _("Components only"); + case RerouteConfig::REPLACE_ALPHA: return _("Alpha replace"); + } + return ""; +} + +const char* RerouteConfig::output_to_text(int output_track) +{ + switch(output_track) + { + case RerouteConfig::TOP: return _("Top"); + case RerouteConfig::BOTTOM: return _("Bottom"); + } + return ""; +} + + + + + + + + + +RerouteWindow::RerouteWindow(Reroute *plugin) + : PluginClientWindow(plugin, 300, 160, 0, 0, 1) +{ + this->plugin = plugin; +} + +RerouteWindow::~RerouteWindow() +{ +} + +void RerouteWindow::create_objects() +{ + int x = 10, y = 10; + + BC_Title *title; + add_subwindow(title = new BC_Title(x, y, _("Target track:"))); + + int col2 = title->get_w() + 5; + add_subwindow(output = new RerouteOutput(plugin, + x + col2, + y)); + output->create_objects(); + + y += 30; + add_subwindow(title = new BC_Title(x, y, _("Operation:"))); + add_subwindow(operation = new RerouteOperation(plugin, + x + col2, + y)); + operation->create_objects(); + + show_window(); + flush(); +} + + + + + + + + +RerouteOperation::RerouteOperation(Reroute *plugin, + int x, + int y) + : BC_PopupMenu(x, + y, + 150, + RerouteConfig::operation_to_text(plugin->config.operation), + 1) +{ + this->plugin = plugin; +} + +void RerouteOperation::create_objects() +{ + add_item(new BC_MenuItem( + RerouteConfig::operation_to_text( + RerouteConfig::REPLACE))); + add_item(new BC_MenuItem( + RerouteConfig::operation_to_text( + RerouteConfig::REPLACE_COMPONENTS))); + add_item(new BC_MenuItem( + RerouteConfig::operation_to_text( + RerouteConfig::REPLACE_ALPHA))); +} + +int RerouteOperation::handle_event() +{ + char *text = get_text(); + + if(!strcmp(text, + RerouteConfig::operation_to_text( + RerouteConfig::REPLACE))) + plugin->config.operation = RerouteConfig::REPLACE; + else + if(!strcmp(text, + RerouteConfig::operation_to_text( + RerouteConfig::REPLACE_COMPONENTS))) + plugin->config.operation = RerouteConfig::REPLACE_COMPONENTS; + else + if(!strcmp(text, + RerouteConfig::operation_to_text( + RerouteConfig::REPLACE_ALPHA))) + plugin->config.operation = RerouteConfig::REPLACE_ALPHA; + + plugin->send_configure_change(); + return 1; +} + + +RerouteOutput::RerouteOutput(Reroute *plugin, + int x, + int y) + : BC_PopupMenu(x, + y, + 100, + RerouteConfig::output_to_text(plugin->config.output_track), + 1) +{ + this->plugin = plugin; +} + +void RerouteOutput::create_objects() +{ + add_item(new BC_MenuItem( + RerouteConfig::output_to_text( + RerouteConfig::TOP))); + add_item(new BC_MenuItem( + RerouteConfig::output_to_text( + RerouteConfig::BOTTOM))); +} + +int RerouteOutput::handle_event() +{ + char *text = get_text(); + + if(!strcmp(text, + RerouteConfig::output_to_text( + RerouteConfig::TOP))) + plugin->config.output_track = RerouteConfig::TOP; + else + if(!strcmp(text, + RerouteConfig::output_to_text( + RerouteConfig::BOTTOM))) + plugin->config.output_track = RerouteConfig::BOTTOM; + + plugin->send_configure_change(); + return 1; +} + + + + + +/***** Register Plugin ***********************************/ + + +REGISTER_PLUGIN(Reroute) + + + + + + + +Reroute::Reroute(PluginServer *server) + : PluginVClient(server) +{ +} + + +Reroute::~Reroute() +{ +} + + + +/* + * Main operation + * + *****************************************/ +template +struct px_type +{ + static inline + void transfer(VFrame*, VFrame*, bool, bool) ; +}; + +template +void px_type::transfer(VFrame *source, VFrame *target, bool do_components, bool do_alpha) +//partially overwrite target data buffer +{ + int w = target->get_w(); + int h = source->get_h(); + do_alpha = do_alpha && (COMPONENTS > 3); // only possible if we have alpha + + for(int i = 0; i < h; i++) + { + TYPE *inpx = (TYPE*)source->get_rows()[i]; + TYPE *outpx = (TYPE*)target->get_rows()[i]; + + for(int j = 0; j < w; j++) + { + if(do_components) + { + outpx[0] = inpx[0]; + outpx[1] = inpx[1]; + outpx[2] = inpx[2]; + } + if(do_alpha) + outpx[3] = inpx[3]; + + inpx += COMPONENTS; + outpx += COMPONENTS; + } + } +} + + + +int Reroute::process_buffer(VFrame **frame, + int64_t start_position, + double frame_rate) +{ + load_configuration(); + + bool do_components = true, do_alpha = true; + switch(config.operation) + { + case RerouteConfig::REPLACE: break; + case RerouteConfig::REPLACE_ALPHA: do_components = false; break; + case RerouteConfig::REPLACE_COMPONENTS: do_alpha = false; break; + } + + if(config.output_track == RerouteConfig::TOP) + { + input_track = get_total_buffers() - 1; + output_track = 0; + } + else + { + input_track = 0; + output_track = get_total_buffers() - 1; + } + + + // output buffers for source and target track + VFrame *source = frame[input_track]; + VFrame *target = frame[output_track]; + + // input track always passed through unaltered + read_frame(source, + input_track, + start_position, + frame_rate, + false ); // no OpenGL support + + // no real operation necessary + // unless applied to multiple tracks.... + if(get_total_buffers() <= 1) + return 0; + + if(config.operation == RerouteConfig::REPLACE) + { + target->copy_from(source); + return 0; + } + + + // prepare data for output track + // (to be overidden partially) + read_frame(target, + output_track, + start_position, + frame_rate, + 0); + + switch(source->get_color_model()) + { + case BC_RGB_FLOAT: + px_type::transfer(source,target, do_components,do_alpha); + break; + case BC_RGBA_FLOAT: + px_type::transfer(source,target, do_components,do_alpha); + break; + case BC_RGB888: + case BC_YUV888: + px_type::transfer(source,target, do_components,do_alpha); + break; + case BC_RGBA8888: + case BC_YUVA8888: + px_type::transfer(source,target, do_components,do_alpha); + break; + case BC_RGB161616: + case BC_YUV161616: + px_type::transfer(source,target, do_components,do_alpha); + break; + case BC_RGBA16161616: + case BC_YUVA16161616: + px_type::transfer(source,target, do_components,do_alpha); + break; + } + + return 0; +} + + + + + + + + +const char* Reroute::plugin_title() { return _("Reroute"); } +int Reroute::is_realtime() { return 1; } +int Reroute::is_multichannel() { return 1; } + + + + + +NEW_WINDOW_MACRO(Reroute,RerouteWindow) + +int Reroute::load_configuration() +{ + KeyFrame *prev_keyframe; + prev_keyframe = get_prev_keyframe(get_source_position()); + read_data(prev_keyframe); + return 0; +} + + +void Reroute::save_data(KeyFrame *keyframe) +{ + FileXML output; + +// write configuration data as XML text + output.set_shared_output(keyframe->get_data(), MESSAGESIZE); + output.tag.set_title("REROUTE"); + output.tag.set_property("OPERATION", config.operation); + output.tag.set_property("OUTPUT_TRACK", config.output_track); + output.append_tag(); + output.tag.set_title("/REROUTE"); + output.append_tag(); + output.terminate_string(); +} + +void Reroute::read_data(KeyFrame *keyframe) +{ + FileXML input; + input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); + + while(!input.read_tag()) + { + if(input.tag.title_is("REROUTE")) + { + config.operation = input.tag.get_property("OPERATION", config.operation); + config.output_track = input.tag.get_property("OUTPUT_TRACK", config.output_track); + } + } +} + +void Reroute::update_gui() +{ + if(thread) + { + RerouteWindow *window = (RerouteWindow *)thread->window; + window->lock_window("Reroute::update_gui"); + window->operation->set_text(RerouteConfig::operation_to_text(config.operation)); + window->output->set_text(RerouteConfig::output_to_text(config.output_track)); + window->unlock_window(); + } +}