add layout_scale preference, scaling cleanup, rework init bc_resources, init tip_info...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / delayvideo / delayvideo.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #include "bcdisplayinfo.h"
23 #include "clip.h"
24 #include "bchash.h"
25 #include "delayvideo.h"
26 #include "filexml.h"
27 #include "language.h"
28 #include "vframe.h"
29
30
31
32
33 #include <string.h>
34
35
36
37
38
39
40 REGISTER_PLUGIN(DelayVideo)
41
42
43
44
45
46 DelayVideoConfig::DelayVideoConfig()
47 {
48         length = 0;
49 }
50
51 int DelayVideoConfig::equivalent(DelayVideoConfig &that)
52 {
53         return EQUIV(length, that.length);
54 }
55
56 void DelayVideoConfig::copy_from(DelayVideoConfig &that)
57 {
58         length = that.length;
59 }
60
61 void DelayVideoConfig::interpolate(DelayVideoConfig &prev,
62                 DelayVideoConfig &next,
63                 int64_t prev_frame,
64                 int64_t next_frame,
65                 int64_t current_frame)
66 {
67         this->length = prev.length;
68 }
69
70
71
72 DelayVideoWindow::DelayVideoWindow(DelayVideo *plugin)
73  : PluginClientWindow(plugin,
74         xS(190),
75         yS(70),
76         xS(190),
77         yS(70),
78         0)
79 {
80         this->plugin = plugin;
81 }
82
83 DelayVideoWindow::~DelayVideoWindow()
84 {
85 }
86
87
88 void DelayVideoWindow::create_objects()
89 {
90         int xs10 = xS(10);
91         int ys10 = yS(10), ys20 = yS(20);
92         int x = xs10, y = ys10;
93
94         add_subwindow(new BC_Title(x, y, _("Delay seconds:")));
95         y += ys20;
96         slider = new DelayVideoSlider(this, plugin, x, y);
97         slider->create_objects();
98         show_window();
99 }
100
101
102 void DelayVideoWindow::update_gui()
103 {
104         char string[BCTEXTLEN];
105         sprintf(string, "%.04f", plugin->config.length);
106         slider->update(string);
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120 DelayVideoSlider::DelayVideoSlider(DelayVideoWindow *window,
121         DelayVideo *plugin,
122         int x,
123         int y)
124  : BC_TumbleTextBox(window,
125         (float)plugin->config.length,
126         (float)0,
127         (float)10,
128         x,
129         y,
130         xS(150))
131 {
132         this->plugin = plugin;
133         set_increment(0.1);
134 }
135
136 int DelayVideoSlider::handle_event()
137 {
138         plugin->config.length = atof(get_text());
139         plugin->send_configure_change();
140         return 1;
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 DelayVideo::DelayVideo(PluginServer *server)
160  : PluginVClient(server)
161 {
162         reset();
163 }
164
165 DelayVideo::~DelayVideo()
166 {
167         if(buffer)
168         {
169 //printf("DelayVideo::~DelayVideo 1\n");
170                 for(int i = 0; i < allocation; i++)
171                         delete buffer[i];
172 //printf("DelayVideo::~DelayVideo 1\n");
173
174                 delete [] buffer;
175 //printf("DelayVideo::~DelayVideo 1\n");
176         }
177 }
178
179 void DelayVideo::reset()
180 {
181         thread = 0;
182         need_reconfigure = 1;
183         buffer = 0;
184         allocation = 0;
185 }
186
187 void DelayVideo::reconfigure()
188 {
189         int new_allocation = 1 + (int)(config.length * PluginVClient::project_frame_rate);
190         VFrame **new_buffer = new VFrame*[new_allocation];
191         int reuse = MIN(new_allocation, allocation);
192
193         for(int i = 0; i < reuse; i++)
194         {
195                 new_buffer[i] = buffer[i];
196         }
197
198         for(int i = reuse; i < new_allocation; i++)
199         {
200                 new_buffer[i] = new VFrame(input->get_w(), input->get_h(),
201                         PluginVClient::project_color_model, 0);
202         }
203
204         for(int i = reuse; i < allocation; i++)
205         {
206                 delete buffer[i];
207         }
208
209         if(buffer) delete [] buffer;
210
211
212         buffer = new_buffer;
213         allocation = new_allocation;
214
215         need_reconfigure = 0;
216 }
217
218 int DelayVideo::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
219 {
220 //printf("DelayVideo::process_realtime 1 %d\n", config.length);
221         this->input = input_ptr;
222         this->output = output_ptr;
223         need_reconfigure += load_configuration();
224         CLAMP(config.length, 0, 10);
225
226 //printf("DelayVideo::process_realtime 2 %d\n", config.length);
227         if(need_reconfigure) reconfigure();
228 //printf("DelayVideo::process_realtime 3 %d %d\n", config.length, allocation);
229
230         buffer[allocation - 1]->copy_from(input_ptr);
231         output_ptr->copy_from(buffer[0]);
232
233         VFrame *temp = buffer[0];
234         for(int i = 0; i < allocation - 1; i++)
235         {
236                 buffer[i] = buffer[i + 1];
237         }
238
239         buffer[allocation - 1] = temp;
240 //printf("DelayVideo::process_realtime 4\n");
241
242
243         return 0;
244 }
245
246 int DelayVideo::is_realtime()
247 {
248         return 1;
249 }
250
251 const char* DelayVideo::plugin_title() { return N_("Delay Video"); }
252
253 LOAD_CONFIGURATION_MACRO(DelayVideo, DelayVideoConfig)
254 NEW_WINDOW_MACRO(DelayVideo, DelayVideoWindow)
255
256
257 void DelayVideo::save_data(KeyFrame *keyframe)
258 {
259         FileXML output;
260         output.set_shared_output(keyframe->xbuf);
261
262         output.tag.set_title("DELAYVIDEO");
263         output.tag.set_property("LENGTH", (double)config.length);
264         output.append_tag();
265         output.tag.set_title("/DELAYVIDEO");
266         output.append_tag();
267         output.append_newline();
268         output.terminate_string();
269 }
270
271 void DelayVideo::read_data(KeyFrame *keyframe)
272 {
273         FileXML input;
274         input.set_shared_input(keyframe->xbuf);
275
276         int result = 0;
277         while(!result)
278         {
279                 result = input.read_tag();
280
281                 if(!result)
282                 {
283                         if(input.tag.title_is("DELAYVIDEO"))
284                         {
285                                 config.length = input.tag.get_property("LENGTH", (double)config.length);
286                         }
287                 }
288         }
289 }
290
291 void DelayVideo::update_gui()
292 {
293         if(thread)
294         {
295                 load_configuration();
296                 ((DelayVideoWindow*)thread->window)->lock_window();
297                 ((DelayVideoWindow*)thread->window)->slider->update(config.length);
298                 ((DelayVideoWindow*)thread->window)->unlock_window();
299         }
300 }
301
302
303
304
305
306
307