d4270c46204f07d4e3f0a72a22bd5e2ec15014ce
[goodguy/history.git] / cinelerra-5.1 / plugins / swapframes / swapframes.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 "filexml.h"
26 #include "guicast.h"
27 #include "language.h"
28 #include "bccolors.h"
29 #include "pluginvclient.h"
30 #include "swapframes.h"
31 #include "vframe.h"
32
33 #include <stdint.h>
34 #include <string.h>
35
36
37
38
39 REGISTER_PLUGIN(SwapFrames)
40
41
42
43
44
45
46
47 SwapFramesConfig::SwapFramesConfig()
48 {
49         on = 1;
50         swap_even = 1;
51 }
52
53 void SwapFramesConfig::copy_from(SwapFramesConfig &src)
54 {
55         on = src.on;
56         swap_even = src.swap_even;
57 }
58
59 int SwapFramesConfig::equivalent(SwapFramesConfig &src)
60 {
61         return on == src.on &&
62                 swap_even == src.swap_even;
63 }
64
65 void SwapFramesConfig::interpolate(SwapFramesConfig &prev,
66         SwapFramesConfig &next,
67         int64_t prev_frame,
68         int64_t next_frame,
69         int64_t current_frame)
70 {
71         on = prev.on;
72         swap_even = prev.swap_even;
73 }
74
75
76
77
78
79
80
81
82
83
84 SwapFramesOn::SwapFramesOn(SwapFrames *plugin,
85         int x, int y)
86  : BC_CheckBox(x,
87         y,
88         plugin->config.on,
89         _("Enabled"))
90 {
91         this->plugin = plugin;
92 }
93
94 int SwapFramesOn::handle_event()
95 {
96         plugin->config.on = get_value();
97         plugin->send_configure_change();
98         return 1;
99 }
100
101
102
103
104
105
106 SwapFramesEven::SwapFramesEven(SwapFrames *plugin,
107         SwapFramesWindow *gui,
108         int x,
109         int y)
110  : BC_Radial(x,
111         y,
112         plugin->config.swap_even,
113         _("Swap 0-1, 2-3, 4-5..."))
114 {
115         this->plugin = plugin;
116         this->gui = gui;
117 }
118
119 int SwapFramesEven::handle_event()
120 {
121         plugin->config.swap_even = 1;
122         gui->swap_odd->update(0);
123         plugin->send_configure_change();
124         return 1;
125 }
126
127
128
129
130
131
132 SwapFramesOdd::SwapFramesOdd(SwapFrames *plugin,
133         SwapFramesWindow *gui,
134         int x,
135         int y)
136  : BC_Radial(x,
137         y,
138         !plugin->config.swap_even,
139         _("Swap 1-2, 3-4, 5-6..."))
140 {
141         this->plugin = plugin;
142         this->gui = gui;
143 }
144
145 int SwapFramesOdd::handle_event()
146 {
147         plugin->config.swap_even = 0;
148         gui->swap_even->update(0);
149         plugin->send_configure_change();
150         return 1;
151 }
152
153
154
155
156
157
158 SwapFramesWindow::SwapFramesWindow(SwapFrames *plugin)
159  : PluginClientWindow(plugin,
160         260,
161         130,
162         260,
163         130,
164         0)
165 {
166         this->plugin = plugin;
167 }
168
169 void SwapFramesWindow::create_objects()
170 {
171         int x = 10, y = 10;
172         add_subwindow(on = new SwapFramesOn(plugin, x, y));
173         y += on->get_h() + 5;
174         BC_Bar *bar;
175         add_subwindow(bar = new BC_Bar(x, y, get_w() - x * 2));
176         y += bar->get_h() + 5;
177         add_subwindow(swap_even = new SwapFramesEven(plugin,
178                 this,
179                 x,
180                 y));
181         y += swap_even->get_h() + 5;
182         add_subwindow(swap_odd = new SwapFramesOdd(plugin,
183                 this,
184                 x,
185                 y));
186         show_window();
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200
201 SwapFrames::SwapFrames(PluginServer *server)
202  : PluginVClient(server)
203 {
204
205         buffer = 0;
206         buffer_position = -1;
207         prev_frame = -1;
208 }
209
210 SwapFrames::~SwapFrames()
211 {
212
213         delete buffer;
214 }
215
216 const char* SwapFrames::plugin_title() { return N_("Swap Frames"); }
217 int SwapFrames::is_realtime() { return 1; }
218
219 NEW_WINDOW_MACRO(SwapFrames, SwapFramesWindow)
220 LOAD_CONFIGURATION_MACRO(SwapFrames, SwapFramesConfig)
221
222 void SwapFrames::update_gui()
223 {
224         if(thread)
225         {
226                 thread->window->lock_window();
227                 if(load_configuration())
228                 {
229                         ((SwapFramesWindow*)thread->window)->on->update(config.on);
230                         ((SwapFramesWindow*)thread->window)->swap_even->update(config.swap_even);
231                         ((SwapFramesWindow*)thread->window)->swap_odd->update(!config.swap_even);
232                 }
233                 thread->window->unlock_window();
234         }
235 }
236
237
238 void SwapFrames::save_data(KeyFrame *keyframe)
239 {
240         FileXML output;
241         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
242         output.tag.set_title("SWAPFRAMES");
243         output.tag.set_property("ON", config.on);
244         output.tag.set_property("SWAP_EVEN", config.swap_even);
245         output.append_tag();
246         output.tag.set_title("/SWAPFRAMES");
247         output.append_tag();
248         output.append_newline();
249         output.terminate_string();
250 }
251
252 void SwapFrames::read_data(KeyFrame *keyframe)
253 {
254         FileXML input;
255         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
256         while(!input.read_tag())
257         {
258                 if(input.tag.title_is("SWAPFRAMES"))
259                 {
260                         config.on = input.tag.get_property("ON", config.on);
261                         config.swap_even = input.tag.get_property("SWAP_EVEN", config.swap_even);
262                 }
263         }
264 }
265
266
267 int SwapFrames::process_buffer(VFrame *frame,
268         int64_t start_position,
269         double frame_rate)
270 {
271         load_configuration();
272         int64_t new_position = start_position;
273
274         if(config.on)
275         {
276                 if(config.swap_even)
277                 {
278                         if(new_position % 2)
279                                 new_position--;
280                         else
281                                 new_position++;
282                 }
283                 else
284                 {
285                         if(new_position % 2)
286                                 new_position++;
287                         else
288                                 new_position--;
289                 }
290         }
291
292 // Recall a frame
293 //printf("SwapFrames::process_buffer %d new_position=%lld\n", __LINE__, new_position);
294         if(buffer && buffer_position == new_position)
295         {
296 //printf("SwapFrames::process_buffer %d\n", __LINE__);
297                 frame->copy_from(buffer);
298         }
299         else
300 // Skipped a frame
301         if(new_position > prev_frame + 1)
302         {
303 //printf("SwapFrames::process_buffer %d\n", __LINE__);
304                 if(!buffer)
305                         buffer = new VFrame(frame->get_w(), frame->get_h(),
306                                 frame->get_color_model(), 0);
307                 buffer_position = new_position - 1;
308                 read_frame(buffer,
309                         0,
310                         buffer_position,
311                         frame_rate,
312                         0);
313                 read_frame(frame,
314                         0,
315                         new_position,
316                         frame_rate,
317                         get_use_opengl());
318                 prev_frame = new_position;
319         }
320 // Read new frame
321         else
322         {
323 //printf("SwapFrames::process_buffer %d\n", __LINE__);
324                 read_frame(frame,
325                         0,
326                         new_position,
327                         frame_rate,
328                         get_use_opengl());
329                 prev_frame = new_position;
330         }
331
332
333         return 0;
334 }
335