update internationalization data
[goodguy/history.git] / cinelerra-5.0 / plugins / reversevideo / reversevideo.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 "bchash.h"
24 #include "filexml.h"
25 #include "guicast.h"
26 #include "language.h"
27 #include "pluginvclient.h"
28 #include "transportque.h"
29
30 #include <string.h>
31
32 class ReverseVideo;
33
34 class ReverseVideoConfig
35 {
36 public:
37         ReverseVideoConfig();
38         int enabled;
39 };
40
41
42 class ReverseVideoEnabled : public BC_CheckBox
43 {
44 public:
45         ReverseVideoEnabled(ReverseVideo *plugin,
46                 int x,
47                 int y);
48         int handle_event();
49         ReverseVideo *plugin;
50 };
51
52 class ReverseVideoWindow : public PluginClientWindow
53 {
54 public:
55         ReverseVideoWindow(ReverseVideo *plugin);
56         ~ReverseVideoWindow();
57         void create_objects();
58
59         ReverseVideo *plugin;
60         ReverseVideoEnabled *enabled;
61 };
62
63
64 class ReverseVideo : public PluginVClient
65 {
66 public:
67         ReverseVideo(PluginServer *server);
68         ~ReverseVideo();
69
70         PLUGIN_CLASS_MEMBERS(ReverseVideoConfig)
71
72         void save_data(KeyFrame *keyframe);
73         void read_data(KeyFrame *keyframe);
74         void update_gui();
75         int is_realtime();
76         int process_buffer(VFrame *frame,
77                         int64_t start_position,
78                         double frame_rate);
79
80         int64_t input_position;
81 };
82
83
84
85
86
87
88
89 REGISTER_PLUGIN(ReverseVideo);
90
91
92
93 ReverseVideoConfig::ReverseVideoConfig()
94 {
95         enabled = 1;
96 }
97
98
99
100
101
102 ReverseVideoWindow::ReverseVideoWindow(ReverseVideo *plugin)
103  : PluginClientWindow(plugin, 
104         210, 
105         160, 
106         200, 
107         160, 
108         0)
109 {
110         this->plugin = plugin;
111 }
112
113 ReverseVideoWindow::~ReverseVideoWindow()
114 {
115 }
116
117 void ReverseVideoWindow::create_objects()
118 {
119         int x = 10, y = 10;
120
121         add_subwindow(enabled = new ReverseVideoEnabled(plugin, 
122                 x, 
123                 y));
124         show_window();
125         flush();
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139 ReverseVideoEnabled::ReverseVideoEnabled(ReverseVideo *plugin, 
140         int x, 
141         int y)
142  : BC_CheckBox(x, 
143         y, 
144         plugin->config.enabled,
145         _("Enabled"))
146 {
147         this->plugin = plugin;
148 }
149
150 int ReverseVideoEnabled::handle_event()
151 {
152         plugin->config.enabled = get_value();
153         plugin->send_configure_change();
154         return 1;
155 }
156
157
158
159
160
161
162
163
164
165 ReverseVideo::ReverseVideo(PluginServer *server)
166  : PluginVClient(server)
167 {
168         
169 }
170
171
172 ReverseVideo::~ReverseVideo()
173 {
174         
175 }
176
177 const char* ReverseVideo::plugin_title() { return _("Reverse video"); }
178 int ReverseVideo::is_realtime() { return 1; }
179
180
181 NEW_WINDOW_MACRO(ReverseVideo, ReverseVideoWindow)
182
183
184 int ReverseVideo::process_buffer(VFrame *frame,
185                 int64_t start_position,
186                 double frame_rate)
187 {
188         load_configuration();
189
190         if(config.enabled)
191                 read_frame(frame,
192                         0,
193                         input_position,
194                         frame_rate);
195         else
196                 read_frame(frame,
197                         0,
198                         start_position,
199                         frame_rate);
200         return 0;
201 }
202
203
204
205
206 int ReverseVideo::load_configuration()
207 {
208         KeyFrame *prev_keyframe, *next_keyframe;
209         next_keyframe = get_next_keyframe(get_source_position());
210         prev_keyframe = get_prev_keyframe(get_source_position());
211 // Previous keyframe stays in config object.
212         read_data(prev_keyframe);
213
214         int64_t prev_position = edl_to_local(prev_keyframe->position);
215         int64_t next_position = edl_to_local(next_keyframe->position);
216
217         if(prev_position == 0 && next_position == 0) 
218         {
219                 next_position = prev_position = get_source_start();
220         }
221
222 // Get range to flip in requested rate
223         int64_t range_start = prev_position;
224         int64_t range_end = next_position;
225
226 // Between keyframe and edge of range or no keyframes
227         if(range_start == range_end)
228         {
229 // Between first keyframe and start of effect
230                 if(get_source_position() >= get_source_start() &&
231                         get_source_position() < range_start)
232                 {
233                         range_start = get_source_start();
234                 }
235                 else
236 // Between last keyframe and end of effect
237                 if(get_source_position() >= range_start &&
238                         get_source_position() < get_source_start() + get_total_len())
239                 {
240                         range_end = get_source_start() + get_total_len();
241                 }
242                 else
243                 {
244 // Should never get here
245                         ;
246                 }
247         }
248
249
250 // Convert start position to new direction
251         if(get_direction() == PLAY_FORWARD)
252         {
253                 input_position = get_source_position() - range_start;
254                 input_position = range_end - input_position - 1;
255         }
256         else
257         {
258                 input_position = range_end - get_source_position();
259                 input_position = range_start + input_position + 1;
260         }
261 // printf("ReverseVideo::load_configuration 2 start=%lld end=%lld current=%lld input=%lld\n", 
262 // range_start, 
263 // range_end, 
264 // get_source_position(),
265 // input_position);
266
267         return 0;
268 }
269
270
271 void ReverseVideo::save_data(KeyFrame *keyframe)
272 {
273         FileXML output;
274
275 // cause data to be stored directly in text
276         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
277         output.tag.set_title("REVERSEVIDEO");
278         output.tag.set_property("ENABLED", config.enabled);
279         output.append_tag();
280         output.terminate_string();
281 }
282
283 void ReverseVideo::read_data(KeyFrame *keyframe)
284 {
285         FileXML input;
286
287         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
288
289         while(!input.read_tag())
290         {
291                 if(input.tag.title_is("REVERSEVIDEO"))
292                 {
293                         config.enabled = input.tag.get_property("ENABLED", config.enabled);
294                 }
295         }
296 }
297
298 void ReverseVideo::update_gui()
299 {
300         if(thread)
301         {
302                 load_configuration();
303                 thread->window->lock_window();
304                 ((ReverseVideoWindow*)thread->window)->enabled->update(config.enabled);
305                 thread->window->unlock_window();
306         }
307 }
308
309
310
311
312