Credit Andrew - fix vorbis audio which was scratchy and ensure aging plugin does...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / pluginclient.C
index dcafd890cb73360f37bc07e854fdb01b7e469708..d31b4b002c787bfbee824f252d40e504ebc29ed6 100644 (file)
@@ -43,6 +43,7 @@
 #include "preferences.h"
 #include "renderengine.h"
 #include "track.h"
+#include "tracks.h"
 #include "transportque.h"
 
 #include <stdio.h>
@@ -73,7 +74,6 @@ PluginClientThread::PluginClientThread(PluginClient *client)
 
 PluginClientThread::~PluginClientThread()
 {
-       join();
        delete window;
        delete init_complete;
 }
@@ -102,11 +102,9 @@ void PluginClientThread::run()
                window->lock_window("PluginClientThread::run");
 //printf("PluginClientThread::run %p %d\n", this, __LINE__);
                window->hide_window(1);
+               client->save_defaults_xml(); // needs window lock
                window->unlock_window();
                window->done_event(result);
-// Can't save defaults in the destructor because it's not called immediately
-// after closing.
-               /* if(client->defaults) */ client->save_defaults_xml();
 /* This is needed when the GUI is closed from itself */
                if(result) client->client_side_close();
        }
@@ -135,7 +133,27 @@ PluginClientWindow::PluginClientWindow(PluginClient *client,
        client->window_x /* - w / 2 */, client->window_y /* - h / 2 */,
        w, h, min_w, min_h, allow_resize, 0, 1)
 {
+       char title[BCTEXTLEN];
+
        this->client = client;
+
+// *** CONTEXT_HELP ***
+       if(client) {
+               strcpy(title, client->plugin_title());
+               if(! strcmp(title, "Overlay")) {
+                       // "Overlay" plugin title is ambiguous
+                       if(client->is_audio()) strcat(title, " \\(Audio\\)");
+                       if(client->is_video()) strcat(title, " \\(Video\\)");
+               }
+               if(client->server->is_ffmpeg()) {
+                       // FFmpeg plugins can be audio or video
+                       if(client->is_audio())
+                               strcpy(title, "FFmpeg Audio Plugins");
+                       if(client->is_video())
+                               strcpy(title, "FFmpeg Video Plugins");
+               }
+               context_help_set_keyword(title);
+       }
 }
 
 PluginClientWindow::PluginClientWindow(const char *title,
@@ -143,6 +161,8 @@ PluginClientWindow::PluginClientWindow(const char *title,
  : BC_Window(title, x, y, w, h, min_w, min_h, allow_resize, 0, 1)
 {
        this->client = 0;
+// *** CONTEXT_HELP ***
+       context_help_set_keyword(title);
 }
 
 PluginClientWindow::~PluginClientWindow()
@@ -457,13 +477,8 @@ void PluginClient::hide_gui()
 {
        if(thread && thread->window)
        {
-//printf("PluginClient::delete_thread %d\n", __LINE__);
-/* This is needed when the GUI is closed from elsewhere than itself */
-/* Since we now use autodelete, this is all that has to be done, thread will take care of itself ... */
-/* Thread join will wait if this was not called from the thread itself or go on if it was */
                thread->window->lock_window("PluginClient::hide_gui");
                thread->window->set_done(0);
-//printf("PluginClient::hide_gui %d thread->window=%p\n", __LINE__, thread->window);
                thread->window->unlock_window();
        }
 }
@@ -653,11 +668,11 @@ PluginClientFrame* PluginClientFrames::get_gui_frame(double pos, int dir)
 
 PluginClientFrame* PluginClient::get_gui_frame(double pos, int dir)
 {
-       return frame_buffer.get_gui_frame(pos, dir);
+       return client_frames.get_gui_frame(pos, dir);
 }
 PluginClientFrame* PluginClient::next_gui_frame()
 {
-       return frame_buffer.first;
+       return client_frames.first;
 }
 
 
@@ -670,9 +685,9 @@ void PluginClient::update_gui()
 {
 }
 
-int PluginClient::pending_gui_frames()
+int PluginClient::pending_gui_frame()
 {
-       PluginClientFrame *frame = frame_buffer.first;
+       PluginClientFrame *frame = client_frames.first;
        if( !frame ) return 0;
        double tracking_position = get_tracking_position();
        int direction = get_tracking_direction();
@@ -682,9 +697,28 @@ int PluginClient::pending_gui_frames()
        return ret;
 }
 
+int PluginClient::pending_gui_frames()
+{
+       PluginClientFrame *frame = client_frames.first;
+       if( !frame ) return 0;
+       double tracking_position = get_tracking_position();
+       int direction = get_tracking_direction();
+       int count = 0;
+       while( frame && !(direction == PLAY_REVERSE ?
+           frame->position < tracking_position :
+           frame->position > tracking_position) ) {
+               ++count;  frame=frame->next;
+       }
+       return count;
+}
+
 void PluginClient::add_gui_frame(PluginClientFrame *frame)
 {
-       frame_buffer.add_gui_frame(frame);
+       client_frames.add_gui_frame(frame);
+}
+int PluginClient::get_gui_frames()
+{
+       return client_frames.total();
 }
 
 double PluginClient::get_tracking_position()
@@ -699,7 +733,7 @@ int PluginClient::get_tracking_direction()
 
 void PluginClient::send_render_gui()
 {
-       server->send_render_gui(&frame_buffer);
+       server->send_render_gui(&client_frames);
 }
 
 void PluginClient::send_render_gui(void *data)
@@ -719,7 +753,7 @@ void PluginClient::plugin_reset_gui_frames()
        BC_WindowBase *window = thread->get_window();
        if( !window ) return;
        window->lock_window("PluginClient::plugin_reset_gui_frames");
-       frame_buffer.reset();
+       client_frames.reset();
        window->unlock_window();
 }
 
@@ -729,11 +763,11 @@ void PluginClient::plugin_render_gui_frames(PluginClientFrames *frames)
        BC_WindowBase *window = thread->get_window();
        if( !window ) return;
        window->lock_window("PluginClient::render_gui");
-       while( frame_buffer.count > MAX_FRAME_BUFFER )
+       while( client_frames.count > MAX_FRAME_BUFFER )
                delete get_gui_frame(0, 0);
-// append client frames to gui frame_buffer, consumes frames
-       frame_buffer.concatenate(frames);
-       frame_buffer.sort_position(get_tracking_direction());
+// append client frames to gui client_frames, consumes frames
+       client_frames.concatenate(frames);
+       client_frames.sort_position(get_tracking_direction());
        update_timer->update();
        window->unlock_window();
 }
@@ -927,9 +961,9 @@ double PluginClient::get_project_framerate()
 
 const char *PluginClient::get_source_path()
 {
-       if( server->plugin ) return 0;
-       int64_t source_position = server->plugin->startproject;
-       Edit *edit = server->plugin->track->edits->editof(source_position,PLAY_FORWARD,0);
+       Plugin *plugin = server->edl->tracks->plugin_exists(server->plugin_id);
+       int64_t source_position = plugin->startproject;
+       Edit *edit = plugin->track->edits->editof(source_position,PLAY_FORWARD,0);
        Indexable *indexable = edit ? edit->get_source() : 0;
        return indexable ? indexable->path : 0;
 }
@@ -1031,6 +1065,11 @@ int PluginClient::get_use_opengl()
        return server->get_use_opengl();
 }
 
+int PluginClient::to_ram(VFrame *vframe)
+{
+       return server->to_ram(vframe);
+}
+
 int PluginClient::get_total_buffers()
 {
        return total_in_buffers;
@@ -1065,9 +1104,12 @@ int PluginClient::send_configure_change()
        if(server->mwindow)
                server->mwindow->undo->update_undo_before(_("tweek"), this);
 #ifdef USE_KEYFRAME_SPANNING
-       KeyFrame keyframe;
+       EDL *edl = server->edl;
+        Plugin *plugin = edl->tracks->plugin_exists(server->plugin_id);
+       KeyFrames *keyframes = plugin ? plugin->keyframes : 0;
+       KeyFrame keyframe(edl, keyframes);
        save_data(&keyframe);
-       server->apply_keyframe(&keyframe);
+       server->apply_keyframe(plugin, &keyframe);
 #else
        KeyFrame* keyframe = server->get_keyframe();
 // Call save routine in plugin
@@ -1079,6 +1121,14 @@ int PluginClient::send_configure_change()
        return 0;
 }
 
+// virtual default spanning keyframe update.  If a range is selected,
+// then changed parameters are copied to (prev + selected) keyframes.
+// redefine per client for custom keyframe updates, see tracer, sketcher, crikey
+void PluginClient::span_keyframes(KeyFrame *src, int64_t start, int64_t end)
+{
+       src->span_keyframes(start, end);
+}
+
 
 KeyFrame* PluginClient::get_prev_keyframe(int64_t position, int is_local)
 {
@@ -1111,7 +1161,8 @@ void PluginClient::output_to_track(float ox, float oy, float &tx, float &ty)
        EDL *edl = get_edl();
        projector_x += edl->session->output_w / 2;
        projector_y += edl->session->output_h / 2;
-       Track *track = server->plugin ? server->plugin->track : 0;
+       Plugin *plugin = edl->tracks->plugin_exists(server->plugin_id);
+       Track *track = plugin ? plugin->track : 0;
        int track_w = track ? track->track_w : edl->session->output_w;
        int track_h = track ? track->track_h : edl->session->output_h;
        tx = (ox - projector_x) / projector_z + track_w / 2;
@@ -1126,7 +1177,8 @@ void PluginClient::track_to_output(float tx, float ty, float &ox, float &oy)
        EDL *edl = get_edl();
        projector_x += edl->session->output_w / 2;
        projector_y += edl->session->output_h / 2;
-       Track *track = server->plugin ? server->plugin->track : 0;
+       Plugin *plugin = edl->tracks->plugin_exists(server->plugin_id);
+       Track *track = plugin ? plugin->track : 0;
        int track_w = track ? track->track_w : edl->session->output_w;
        int track_h = track ? track->track_h : edl->session->output_h;
        ox = (tx - track_w / 2) * projector_z + projector_x;
@@ -1144,3 +1196,4 @@ int PluginClient::gui_open()
        return server->gui_open();
 }
 
+