From 01ddcf0724ca51d3e0cb40fd3bfa3836e09b3cd8 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Thu, 11 Aug 2005 19:34:44 +0000 Subject: [PATCH] r617: This enables undo of plugin parameter tweaks. Fixes Bug 154. --- cinelerra/mainundo.C | 9 +- cinelerra/mainundo.h | 3 + cinelerra/pluginclient.C | 126 ++++++++++------- cinelerra/pluginserver.C | 360 +++++++++++++++++++++++++++++++++++++---------- cinelerra/pluginserver.h | 112 +++++++++++---- 5 files changed, 459 insertions(+), 151 deletions(-) diff --git a/cinelerra/mainundo.C b/cinelerra/mainundo.C index dc504dd3..7f52be0a 100644 --- a/cinelerra/mainundo.C +++ b/cinelerra/mainundo.C @@ -103,13 +103,20 @@ void MainUndo::update_undo_after() { // the old data_after is the state before the change new_entry->set_data_before(data_after); - data_after = 0; push_undo_item(new_entry); new_entry = 0; } } +void MainUndo::push_state(char *description, uint32_t load_flags) +{ + MainUndoStackItem* new_entry = new MainUndoStackItem(this, description, load_flags); +// the old data_after is the state before the change + new_entry->set_data_before(data_after); + push_undo_item(new_entry); +} + diff --git a/cinelerra/mainundo.h b/cinelerra/mainundo.h index 59bcf655..47afbfc8 100644 --- a/cinelerra/mainundo.h +++ b/cinelerra/mainundo.h @@ -27,6 +27,9 @@ public: void update_undo_before(char *description, uint32_t load_flags); void update_undo_after(); +// alternatively, call this one after the change + void push_state(char *description, uint32_t load_flags); + int undo(); int redo(); diff --git a/cinelerra/pluginclient.C b/cinelerra/pluginclient.C index b3d0f422..f164113a 100644 --- a/cinelerra/pluginclient.C +++ b/cinelerra/pluginclient.C @@ -1,14 +1,12 @@ #include "edl.h" #include "edlsession.h" +#include "language.h" #include "pluginclient.h" #include "pluginserver.h" #include "preferences.h" +#include "transportque.inc" #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) PluginClient::PluginClient(PluginServer *server) { @@ -27,15 +25,14 @@ int PluginClient::reset() wr = rd = 0; master_gui_on = 0; client_gui_on = 0; - sample_rate = 0; - frame_rate = 0; realtime_priority = 0; gui_string[0] = 0; total_in_buffers = 0; total_out_buffers = 0; - source_len = 0; source_position = 0; + source_start = 0; total_len = 0; + direction = PLAY_FORWARD; } @@ -45,31 +42,29 @@ int PluginClient::plugin_init_realtime(int realtime_priority, int total_in_buffers, int buffer_size) { -//printf("PluginClient::plugin_init_realtime 1\n"); // Get parameters for all master_gui_on = get_gui_status(); -//printf("PluginClient::plugin_init_realtime 1\n"); // get parameters depending on video or audio init_realtime_parameters(); -//printf("PluginClient::plugin_init_realtime 1\n"); smp = server->preferences->processors - 1; this->realtime_priority = realtime_priority; this->total_in_buffers = this->total_out_buffers = total_in_buffers; this->out_buffer_size = this->in_buffer_size = buffer_size; -//printf("PluginClient::plugin_init_realtime 1\n"); return 0; } -int PluginClient::plugin_start_loop(int64_t start, int64_t end, int64_t buffer_size, int total_buffers) +int PluginClient::plugin_start_loop(int64_t start, + int64_t end, + int64_t buffer_size, + int total_buffers) { + this->source_start = start; + this->total_len = end - start; this->start = start; this->end = end; this->in_buffer_size = this->out_buffer_size = buffer_size; -//printf("PluginClient::plugin_start_loop 1 %d\n", in_buffer_size); this->total_in_buffers = this->total_out_buffers = total_buffers; - sample_rate = get_project_samplerate(); - frame_rate = get_project_framerate(); start_loop(); return 0; } @@ -93,8 +88,6 @@ MainProgressBar* PluginClient::start_progress(char *string, int64_t length) int PluginClient::plugin_get_parameters() { - sample_rate = get_project_samplerate(); - frame_rate = get_project_framerate(); int result = get_parameters(); return result; } @@ -109,6 +102,17 @@ int PluginClient::delete_buffer_ptrs() { return 0; } char* PluginClient::plugin_title() { return _("Untitled"); } VFrame* PluginClient::new_picon() { return 0; } Theme* PluginClient::new_theme() { return 0; } + + + + +Theme* PluginClient::get_theme() +{ + return server->get_theme(); +} + + + int PluginClient::is_audio() { return 0; } int PluginClient::is_video() { return 0; } int PluginClient::is_theme() { return 0; } @@ -116,10 +120,7 @@ int PluginClient::uses_gui() { return 1; } int PluginClient::is_transition() { return 0; } int PluginClient::load_defaults() { return 0; } int PluginClient::save_defaults() { return 0; } -//int PluginClient::start_gui() { return 0; } -//int PluginClient::stop_gui() { return 0; } int PluginClient::show_gui() { return 0; } -//int PluginClient::hide_gui() { return 0; } int PluginClient::set_string() { return 0; } int PluginClient::get_parameters() { return 0; } int PluginClient::get_samplerate() { return get_project_samplerate(); } @@ -167,7 +168,6 @@ int PluginClient::stop_gui_client() { if(!client_gui_on) return 0; client_gui_on = 0; -// stop_gui(); // give to plugin return 0; } @@ -207,62 +207,72 @@ int PluginClient::set_string_client(char *string) } -KeyFrame* PluginClient::get_prev_keyframe(int64_t position) +int PluginClient::get_interpolation_type() { - return server->get_prev_keyframe(position); + return server->get_interpolation_type(); } -KeyFrame* PluginClient::get_next_keyframe(int64_t position) + +// int PluginClient::automation_used() // If automation is used +// { +// return 0; +// } +// +// float PluginClient::get_automation_value(int64_t position) // Get the automation value for the position in the current fragment +// { +// int i; +// for(i = automation.total - 1; i >= 0; i--) +// { +// if(automation.values[i].position <= position) +// { +// return automation.values[i].intercept + automation.values[i].slope * (position - automation.values[i].position); +// } +// } +// return 0; +// } + + +int64_t PluginClient::get_source_position() { - return server->get_next_keyframe(position); + return source_position; } -int PluginClient::get_interpolation_type() +int64_t PluginClient::get_source_start() { - return server->get_interpolation_type(); + return source_start; } - -int PluginClient::automation_used() // If automation is used +int64_t PluginClient::get_total_len() { - return 0; + return total_len; } -float PluginClient::get_automation_value(int64_t position) // Get the automation value for the position in the current fragment +int PluginClient::get_direction() { - int i; - for(i = automation.total - 1; i >= 0; i--) - { - if(automation.values[i].position <= position) - { - return automation.values[i].intercept + automation.values[i].slope * (position - automation.values[i].position); - } - } - return 0; + return direction; } -int64_t PluginClient::get_source_len() + +int64_t PluginClient::local_to_edl(int64_t position) { - return source_len; + return position; } -int64_t PluginClient::get_source_position() +int64_t PluginClient::edl_to_local(int64_t position) { - return source_position; + return position; } -int64_t PluginClient::get_source_start() +int PluginClient::get_total_buffers() { - return server->get_source_start(); + return total_in_buffers; } -int64_t PluginClient::get_total_len() +int PluginClient::get_buffer_size() { - return total_len; + return in_buffer_size; } - - int PluginClient::get_project_smp() { return smp; @@ -283,10 +293,22 @@ int PluginClient::send_hide_gui() int PluginClient::send_configure_change() { -// handle everything using the gui messages KeyFrame* keyframe = server->get_keyframe(); save_data(keyframe); - server->sync_parameters(); + server->sync_parameters(get_gui_string()); return 0; } + +KeyFrame* PluginClient::get_prev_keyframe(int64_t position, int is_local) +{ + if(is_local) position = local_to_edl(position); + return server->get_prev_keyframe(position); +} + +KeyFrame* PluginClient::get_next_keyframe(int64_t position, int is_local) +{ + if(is_local) position = local_to_edl(position); + return server->get_next_keyframe(position); +} + diff --git a/cinelerra/pluginserver.C b/cinelerra/pluginserver.C index c2f71c97..6a7cabe5 100644 --- a/cinelerra/pluginserver.C +++ b/cinelerra/pluginserver.C @@ -10,21 +10,26 @@ #include "floatautos.h" #include "localsession.h" #include "mainprogress.h" +#include "mainundo.h" #include "menueffects.h" #include "mwindow.h" #include "mwindowgui.h" #include "playbackengine.h" #include "plugin.h" +#include "pluginaclient.h" #include "pluginaclientlad.h" #include "pluginclient.h" #include "plugincommands.h" #include "pluginserver.h" +#include "pluginvclient.h" #include "preferences.h" #include "sema.h" #include "mainsession.h" #include "trackcanvas.h" #include "transportque.h" #include "vframe.h" +#include "virtualanode.h" +#include "virtualvnode.h" #include "vmodule.h" #include "vtrack.h" @@ -38,6 +43,7 @@ PluginServer::PluginServer() { reset_parameters(); modules = new ArrayList; + nodes = new ArrayList; } PluginServer::PluginServer(char *path) @@ -45,7 +51,7 @@ PluginServer::PluginServer(char *path) reset_parameters(); set_path(path); modules = new ArrayList; -//if(path) printf("PluginServer::PluginServer %s\n", path); + nodes = new ArrayList; } PluginServer::PluginServer(PluginServer &that) @@ -65,6 +71,7 @@ PluginServer::PluginServer(PluginServer &that) } modules = new ArrayList; + nodes = new ArrayList; attachment = that.attachment; realtime = that.realtime; @@ -92,6 +99,7 @@ PluginServer::~PluginServer() if(path) delete [] path; if(title) delete [] title; if(modules) delete modules; + if(nodes) delete nodes; if(picon) delete picon; } @@ -177,8 +185,7 @@ void PluginServer::set_title(char *string) void PluginServer::generate_display_title(char *string) { -//printf("PluginServer::generate_display_title %s %s\n", plugin->track->title, title); - if(plugin) + if(plugin && plugin->track) sprintf(string, "%s: %s", plugin->track->title, title); else strcpy(string, title); @@ -193,16 +200,15 @@ int PluginServer::open_plugin(int master, { if(plugin_open) return 0; - if(!plugin_fd) plugin_fd = dlopen(path, RTLD_NOW); this->preferences = preferences; this->plugin = plugin; this->edl = edl; -//printf("PluginServer::open_plugin %s %p %p\n", path, this->plugin, plugin_fd); + if(!new_plugin && !plugin_fd) plugin_fd = dlopen(path, RTLD_NOW); - if(!plugin_fd) + if(!new_plugin && !plugin_fd) { // If the dlopen failed it may still be an executable tool for a specific // file format, in which case we just store the path. @@ -219,7 +225,6 @@ int PluginServer::open_plugin(int master, if(!new_plugin && !lad_descriptor) { -//printf("%p %p\n", dlsym(RTLD_NEXT, "open"), dlsym(RTLD_NEXT, "open64")); new_plugin = (PluginClient* (*)(PluginServer*))dlsym(plugin_fd, "new_plugin"); // Probably a LAD plugin but we're not going to instantiate it here anyway. @@ -228,7 +233,6 @@ int PluginServer::open_plugin(int master, lad_descriptor_function = (LADSPA_Descriptor_Function)dlsym( plugin_fd, "ladspa_descriptor"); -//printf("PluginServer::open_plugin 2 %p\n", lad_descriptor_function); if(!lad_descriptor_function) { @@ -253,7 +257,6 @@ int PluginServer::open_plugin(int master, { dlclose(plugin_fd); plugin_fd = 0; -//printf("PluginServer::open_plugin 1 %s\n", path); return PLUGINSERVER_IS_LAD; } } @@ -300,11 +303,9 @@ int PluginServer::close_plugin() // shared object is persistent since plugin deletion would unlink its own object // dlclose(plugin_fd); -//printf("PluginServer::close_plugin 1\n"); plugin_open = 0; cleanup_plugin(); -//printf("PluginServer::close_plugin 2\n"); return 0; } @@ -331,40 +332,110 @@ int PluginServer::init_realtime(int realtime_sched, // set for realtime priority // initialize plugin // Call start_realtime - client->plugin_init_realtime(realtime_sched, total_in_buffers, buffer_size); + client->plugin_init_realtime(realtime_sched, + total_in_buffers, + buffer_size); } -void PluginServer::process_realtime(VFrame **input, - VFrame **output, +// Replaced by pull method but still needed for transitions +void PluginServer::process_transition(VFrame *input, + VFrame *output, int64_t current_position, int64_t total_len) { -//printf("PluginServer::process_realtime 1 %d\n", plugin_open); if(!plugin_open) return; + PluginVClient *vclient = (PluginVClient*)client; - client->plugin_process_realtime(input, - output, - current_position, - total_len); -//printf("PluginServer::process_realtime 2 %d\n", plugin_open); + vclient->source_position = current_position; + vclient->source_start = 0; + vclient->total_len = total_len; + vclient->process_realtime(input, output); + vclient->age_temp(); } -void PluginServer::process_realtime(double **input, - double **output, +void PluginServer::process_transition(double *input, + double *output, int64_t current_position, int64_t fragment_size, int64_t total_len) { if(!plugin_open) return; + PluginAClient *aclient = (PluginAClient*)client; - client->plugin_process_realtime(input, - output, - current_position, - fragment_size, - total_len); + aclient->source_position = current_position; + aclient->total_len = total_len; + aclient->source_start = 0; + aclient->process_realtime(fragment_size, + input, + output); } + +void PluginServer::process_buffer(VFrame **frame, + int64_t current_position, + double frame_rate, + int64_t total_len, + int direction) +{ + if(!plugin_open) return; + PluginVClient *vclient = (PluginVClient*)client; + + vclient->source_position = current_position; + vclient->total_len = total_len; + vclient->frame_rate = frame_rate; + vclient->source_start = (int64_t)(plugin ? + plugin->startproject * + frame_rate / + vclient->project_frame_rate : + 0); + vclient->direction = direction; + + if(multichannel) + { + vclient->process_buffer(frame, current_position, frame_rate); + } + else + { + vclient->process_buffer(frame[0], current_position, frame_rate); + } + + + vclient->age_temp(); +} + +void PluginServer::process_buffer(double **buffer, + int64_t current_position, + int64_t fragment_size, + int64_t sample_rate, + int64_t total_len, + int direction) +{ + if(!plugin_open) return; + PluginAClient *aclient = (PluginAClient*)client; + aclient->source_position = current_position; + aclient->total_len = total_len; + aclient->sample_rate = sample_rate; + if(plugin) + aclient->source_start = plugin->startproject * + sample_rate / + aclient->project_sample_rate; + aclient->direction = direction; + if(multichannel) + aclient->process_buffer(fragment_size, + buffer, + current_position, + sample_rate); + else + { + aclient->process_buffer(fragment_size, + buffer[0], + current_position, + sample_rate); + } +} + + void PluginServer::send_render_gui(void *data) { //printf("PluginServer::send_render_gui 1 %p\n", attachmentpoint); @@ -412,18 +483,24 @@ int64_t PluginServer::get_written_frames() -int PluginServer::get_parameters() // waits for plugin to finish and returns a result -{ - if(!plugin_open) return 0; - return client->plugin_get_parameters(); -} - // ======================= Non-realtime plugin +int PluginServer::get_parameters(int64_t start, int64_t end, int channels) +{ + if(!plugin_open) return 0; + + client->start = start; + client->end = end; + client->source_start = start; + client->total_len = end - start; + client->total_in_buffers = channels; + return client->plugin_get_parameters(); +} + int PluginServer::set_interactive() { if(!plugin_open) return 0; @@ -431,10 +508,19 @@ int PluginServer::set_interactive() return 0; } -int PluginServer::set_module(Module *module) +void PluginServer::append_module(Module *module) { modules->append(module); - return 0; +} + +void PluginServer::append_node(VirtualNode *node) +{ + nodes->append(node); +} + +void PluginServer::reset_nodes() +{ + nodes->remove_all(); } int PluginServer::set_error() @@ -463,7 +549,11 @@ int PluginServer::process_loop(double **buffers, int64_t &write_length) return client->plugin_process_loop(buffers, write_length); } -int PluginServer::start_loop(int64_t start, int64_t end, int64_t buffer_size, int total_buffers) + +int PluginServer::start_loop(int64_t start, + int64_t end, + int64_t buffer_size, + int total_buffers) { if(!plugin_open) return 0; client->plugin_start_loop(start, end, buffer_size, total_buffers); @@ -476,41 +566,127 @@ int PluginServer::stop_loop() return client->plugin_stop_loop(); } -int PluginServer::read_frame(VFrame *buffer, int channel, int64_t start_position) +int PluginServer::read_frame(VFrame *buffer, + int channel, + int64_t start_position) { ((VModule*)modules->values[channel])->render(buffer, start_position, PLAY_FORWARD, + mwindow->edl->session->frame_rate, + 0, 0); return 0; } -int PluginServer::read_samples(double *buffer, int channel, int64_t start_position, int64_t total_samples) +int PluginServer::read_samples(double *buffer, + int channel, + int64_t start_position, + int64_t total_samples) { ((AModule*)modules->values[channel])->render(buffer, - total_samples, start_position, + total_samples, PLAY_FORWARD, + mwindow->edl->session->sample_rate, 0); return 0; } -int PluginServer::read_samples(double *buffer, int64_t start_position, int64_t total_samples) +int PluginServer::read_frame(VFrame *buffer, + int channel, + int64_t start_position, + double frame_rate) { - ((AModule*)modules->values[0])->render(buffer, - total_samples, - start_position, - PLAY_FORWARD, - 0); - return 0; +// Data source depends on whether we're part of a virtual console or a +// plugin array. +// VirtualNode +// Module +// If we're a VirtualNode, read_data in the virtual plugin node handles +// backward propogation and produces the data. +// If we're a Module, render in the module produces the data. + + if(!multichannel) channel = 0; + + + if(nodes->total > channel) + { + return ((VirtualVNode*)nodes->values[channel])->read_data(buffer, + start_position, + frame_rate); + } + else + if(modules->total > channel) + { + return ((VModule*)modules->values[channel])->render(buffer, + start_position, + PLAY_FORWARD, + frame_rate, + 0, + 0); + } + else + { + printf("PluginServer::read_frame no object available for channel=%d\n", + channel); + } +//printf("PluginServer::read_frame 10\n"); + + return -1; } +int PluginServer::read_samples(double *buffer, + int channel, + int64_t sample_rate, + int64_t start_position, + int64_t len) +{ + if(!multichannel) channel = 0; + + if(nodes->total > channel) + return ((VirtualANode*)nodes->values[channel])->read_data(buffer, + start_position, + len, + sample_rate); + else + if(modules->total > channel) + return ((AModule*)modules->values[channel])->render(buffer, + start_position, + len, + PLAY_FORWARD, + sample_rate, + 0); + else + { + printf("PluginServer::read_samples no object available for channel=%d\n", + channel); + } + + return -1; +} + + + + + + + + + + + + + + + + + + // Called by client int PluginServer::get_gui_status() { -//printf("PluginServer::get_gui_status %p %p\n", this, plugin); if(plugin) return plugin->show ? GUI_ON : GUI_OFF; else @@ -527,23 +703,44 @@ void PluginServer::show_gui() { if(!plugin_open) return; client->smp = preferences->processors - 1; + if(plugin) client->total_len = plugin->length; + if(plugin) client->source_start = plugin->startproject; + if(video) + { + client->source_position = Units::to_int64( + mwindow->edl->local_session->selectionstart * + mwindow->edl->session->frame_rate); + } + else + if(audio) + { + client->source_position = Units::to_int64( + mwindow->edl->local_session->selectionstart * + mwindow->edl->session->sample_rate); + } client->update_display_title(); client->show_gui(); } void PluginServer::update_gui() { -//printf("PluginServer::update_gui 1\n"); - if(!plugin_open) return; -//printf("PluginServer::update_gui 2\n"); + if(!plugin_open || !plugin) return; + client->total_len = plugin->length; + client->source_start = plugin->startproject; if(video) + { client->source_position = Units::to_int64( - mwindow->edl->local_session->selectionstart * mwindow->edl->session->frame_rate); + mwindow->edl->local_session->selectionstart * + mwindow->edl->session->frame_rate); + } else if(audio) + { client->source_position = Units::to_int64( - mwindow->edl->local_session->selectionstart * mwindow->edl->session->sample_rate); + mwindow->edl->local_session->selectionstart * + mwindow->edl->session->sample_rate); + } client->update_gui(); } @@ -603,12 +800,30 @@ double PluginServer::get_framerate() int PluginServer::get_project_samplerate() { - return mwindow->edl->session->sample_rate; + if(mwindow) + return mwindow->edl->session->sample_rate; + else + if(edl) + return edl->session->sample_rate; + else + { + printf("PluginServer::get_project_samplerate mwindow and edl are NULL.\n"); + return 1; + } } double PluginServer::get_project_framerate() { - return mwindow->edl->session->frame_rate; + if(mwindow) + return mwindow->edl->session->frame_rate; + else + if(edl) + return edl->session->frame_rate; + else + { + printf("PluginServer::get_project_framerate mwindow and edl are NULL.\n"); + return 1; + } } @@ -666,7 +881,7 @@ KeyFrame* PluginServer::get_prev_keyframe(int64_t position) { KeyFrame *result = 0; if(plugin) - result = plugin->get_prev_keyframe(position); + result = plugin->get_prev_keyframe(position, client->direction); else result = keyframe; return result; @@ -676,34 +891,26 @@ KeyFrame* PluginServer::get_next_keyframe(int64_t position) { KeyFrame *result = 0; if(plugin) - result = plugin->get_next_keyframe(position); + result = plugin->get_next_keyframe(position, client->direction); else result = keyframe; return result; } -int64_t PluginServer::get_source_start() +KeyFrame* PluginServer::get_keyframe() { if(plugin) - return plugin->startproject; + return plugin->get_keyframe(); else - return 0; + return keyframe; } + int PluginServer::get_interpolation_type() { return plugin->edl->session->interpolation_type; } -KeyFrame* PluginServer::get_keyframe() -{ -//printf("PluginServer::get_keyframe %p\n", plugin); - if(plugin) - return plugin->get_keyframe(); - else - return keyframe; -} - Theme* PluginServer::new_theme() { if(theme) @@ -714,15 +921,23 @@ Theme* PluginServer::new_theme() return 0; } +Theme* PluginServer::get_theme() +{ + if(mwindow) return mwindow->theme; + printf("PluginServer::get_theme mwindow not set\n"); + return 0; +} + // Called when plugin interface is tweeked -void PluginServer::sync_parameters() +void PluginServer::sync_parameters(const char *plugin_string) { -TRACE("PluginServer::sync_parameters 1\n"); + char s[BCTEXTLEN]; + sprintf(s, _("tweak %s"), plugin_string); + if(video) mwindow->restart_brender(); -TRACE("PluginServer::sync_parameters 10\n"); + mwindow->undo->push_state(s, LOAD_AUTOMATION | LOAD_TIMEBAR); mwindow->sync_parameters(); -TRACE("PluginServer::sync_parameters 20\n"); if(mwindow->edl->session->auto_conf->plugins) { mwindow->gui->lock_window("PluginServer::sync_parameters"); @@ -730,7 +945,6 @@ TRACE("PluginServer::sync_parameters 20\n"); mwindow->gui->canvas->flash(); mwindow->gui->unlock_window(); } -TRACE("PluginServer::sync_parameters 30\n"); } diff --git a/cinelerra/pluginserver.h b/cinelerra/pluginserver.h index 51df0e14..e66fda49 100644 --- a/cinelerra/pluginserver.h +++ b/cinelerra/pluginserver.h @@ -15,7 +15,6 @@ #include "maxbuffers.h" #include "menueffects.inc" #include "module.inc" -#include "mutex.h" #include "mwindow.inc" #include "plugin.inc" #include "pluginaclientlad.inc" @@ -26,6 +25,7 @@ #include "thread.h" #include "track.inc" #include "vframe.inc" +#include "virtualnode.inc" #include #include @@ -68,16 +68,18 @@ public: void set_title(char *string); // Generate title for display void generate_display_title(char *string); -// Get keyframes for configuration +// Get keyframes for configuration. Position is always relative to EDL rate. KeyFrame* get_prev_keyframe(int64_t position); KeyFrame* get_next_keyframe(int64_t position); - int64_t get_source_start(); // Get interpolation used by EDL int get_interpolation_type(); -// Get or create keyframe for writing, depending on editing status +// Get or create keyframe for writing, depending on whether auto keyframes +// is enabled. Called by PluginClient::send_configure_change KeyFrame* get_keyframe(); -// Create new theme object +// Create new theme object. Used by theme plugins. Theme* new_theme(); +// Get theme being used by Cinelerra currently. Used by all plugins. + Theme* get_theme(); @@ -86,13 +88,14 @@ public: // save configuration of plugin void save_data(KeyFrame *keyframe); // Update EDL and playback engines to reflect changes - void sync_parameters(); + void sync_parameters(const char *plugin_string); // set for realtime processor usage int set_realtime_sched(); int get_gui_status(); // Raise the GUI void raise_window(); // cause the plugin to show the GUI +// Called by MWindow::show_plugin void show_gui(); // Update GUI with keyframe settings void update_gui(); @@ -100,21 +103,50 @@ public: void client_side_close(); - int set_string(char *string); // set the string that appears on the plugin title +// set the string that appears on the plugin title + int set_string(char *string); // give the buffers and sizes and prepare processing realtime data int init_realtime(int realtime_sched, int total_in_buffers, int buffer_size); // process the data in the buffers - void process_realtime(VFrame **input, - VFrame **output, - int64_t current_position, - int64_t total_len); // Total len for transitions - void process_realtime(double **input, - double **output, - int64_t current_position, - int64_t fragment_size, - int64_t total_len); +// Really process_realtime replaced by pull method but still needed for transitions +// input - the current edit's data +// output - the previous edit's data and the destination of the transition output +// current_position - Position from start of the transition and +// relative to the transition. +// total_len - total len for transition + void process_transition(VFrame *input, + VFrame *output, + int64_t current_position, + int64_t total_len); + void process_transition(double *input, + double *output, + int64_t current_position, + int64_t fragment_size, + int64_t total_len); + +// Process using pull method. +// current_position - start of region if forward, end of region if reverse +// relative to requested rate +// fragment_size - amount of data to put in buffer relative to requested rate +// sample_rate - sample rate of requested output +// frame_rate - frame rate of requested output +// total_len - length of plugin in track units relative to the EDL rate +// Units are kept relative to the EDL rate so plugins don't need to convert rates +// to get the keyframes. + void process_buffer(VFrame **frame, + int64_t current_position, + double frame_rate, + int64_t total_len, + int direction); + void process_buffer(double **buffer, + int64_t current_position, + int64_t fragment_size, + int64_t sample_rate, + int64_t total_len, + int direction); + // Called by rendering client to cause the GUI to display something with the data. void send_render_gui(void *data); void send_render_gui(void *data, int size); @@ -151,13 +183,32 @@ public: int process_loop(VFrame **buffers, int64_t &write_length); int process_loop(double **buffers, int64_t &write_length); int stop_loop(); -// Called by non-realtime plugin to read data during rendered effect. - int read_frame(VFrame *buffer, int channel, int64_t start_position); - int read_samples(double *buffer, int channel, int64_t start_position, int64_t total_samples); - int read_samples(double *buffer, int64_t start_position, int64_t total_samples); + + +// Called by client to read data in non-realtime effect + int read_frame(VFrame *buffer, + int channel, + int64_t start_position); + int read_samples(double *buffer, + int channel, + int64_t start_position, + int64_t total_samples); + + +// Called by client to read data in realtime effect. Returns -1 if error or 0 +// if success. + int read_frame(VFrame *buffer, + int channel, + int64_t start_position, + double frame_rate); + int read_samples(double *buffer, + int channel, + int64_t sample_rate, + int64_t start_position, + int64_t len); // For non realtime, prompt user for parameters, waits for plugin to finish and returns a result - int get_parameters(); + int get_parameters(int64_t start, int64_t end, int channels); int get_samplerate(); // get samplerate produced by plugin double get_framerate(); // get framerate produced by plugin int get_project_samplerate(); // get samplerate of project data before processing @@ -174,11 +225,16 @@ public: // Set pointer to menueffect window void set_prompt(MenuEffectPrompt *prompt); int set_interactive(); // make this the master plugin for progress bars -// add track to the list of affected tracks for a non realtime plugin - int set_module(Module *module); int set_error(); // flag to send plugin an error on next request MainProgressBar* start_progress(char *string, int64_t length); +// add track to the list of affected tracks for a non realtime plugin + void append_module(Module *module); +// add node for realtime plugin + void append_node(VirtualNode *node); +// reset node table after virtual console reconfiguration + void reset_nodes(); + int64_t get_written_samples(); // after samples are written, get the number written int64_t get_written_frames(); // after frames are written, get the number written @@ -233,7 +289,12 @@ public: char *args[4]; int total_args; int error_flag; // send plugin an error code on next request - ArrayList *modules; // tracks affected by this plugin during a non realtime operation +// Pointers to tracks affected by this plugin during a non realtime operation. +// Allows read functions to read data. + ArrayList *modules; +// Used by realtime read functions to get data. Corresponds to the buffer table in the +// attachment point. + ArrayList *nodes; AttachmentPoint *attachmentpoint; MWindow *mwindow; // Pointer to keyframe when plugin is not available @@ -262,7 +323,8 @@ private: // Handle from dlopen. Plugins are opened once at startup and stored in the master // plugindb. void *plugin_fd; -// Pointers to C functions +// If no path, this is going to be set to a function which +// instantiates the plugin. PluginClient* (*new_plugin)(PluginServer*); // LAD support -- 2.11.4.GIT