Fixed initialisation of tf in file_open(). Without setting the memory to 0,
[cinelerra_cv/mob.git] / plugins / reversevideo / reversevideo.C
blobe1817f207c45ec410142861a6466347d7b69e4e5
1 #include "bcdisplayinfo.h"
2 #include "bchash.h"
3 #include "filexml.h"
4 #include "guicast.h"
5 #include "language.h"
6 #include "pluginvclient.h"
7 #include "transportque.h"
9 #include <string.h>
11 class ReverseVideo;
13 class ReverseVideoConfig
15 public:
16         ReverseVideoConfig();
17         int enabled;
21 class ReverseVideoEnabled : public BC_CheckBox
23 public:
24         ReverseVideoEnabled(ReverseVideo *plugin,
25                 int x,
26                 int y);
27         int handle_event();
28         ReverseVideo *plugin;
31 class ReverseVideoWindow : public BC_Window
33 public:
34         ReverseVideoWindow(ReverseVideo *plugin, int x, int y);
35         ~ReverseVideoWindow();
36         void create_objects();
37         int close_event();
38         ReverseVideo *plugin;
39         ReverseVideoEnabled *enabled;
42 PLUGIN_THREAD_HEADER(ReverseVideo, ReverseVideoThread, ReverseVideoWindow)
44 class ReverseVideo : public PluginVClient
46 public:
47         ReverseVideo(PluginServer *server);
48         ~ReverseVideo();
50         PLUGIN_CLASS_MEMBERS(ReverseVideoConfig, ReverseVideoThread)
52         int load_defaults();
53         int save_defaults();
54         void save_data(KeyFrame *keyframe);
55         void read_data(KeyFrame *keyframe);
56         void update_gui();
57         int is_realtime();
58         int process_buffer(VFrame *frame,
59                         int64_t start_position,
60                         double frame_rate);
62         int64_t input_position;
71 REGISTER_PLUGIN(ReverseVideo);
75 ReverseVideoConfig::ReverseVideoConfig()
77         enabled = 1;
84 ReverseVideoWindow::ReverseVideoWindow(ReverseVideo *plugin, int x, int y)
85  : BC_Window(plugin->gui_string, 
86         x, 
87         y, 
88         210, 
89         160, 
90         200, 
91         160, 
92         0, 
93         0,
94         1)
96         this->plugin = plugin;
99 ReverseVideoWindow::~ReverseVideoWindow()
103 void ReverseVideoWindow::create_objects()
105         int x = 10, y = 10;
107         add_subwindow(enabled = new ReverseVideoEnabled(plugin, 
108                 x, 
109                 y));
110         show_window();
111         flush();
114 WINDOW_CLOSE_EVENT(ReverseVideoWindow)
117 PLUGIN_THREAD_OBJECT(ReverseVideo, ReverseVideoThread, ReverseVideoWindow)
124 ReverseVideoEnabled::ReverseVideoEnabled(ReverseVideo *plugin, 
125         int x, 
126         int y)
127  : BC_CheckBox(x, 
128         y, 
129         plugin->config.enabled,
130         _("Enabled"))
132         this->plugin = plugin;
135 int ReverseVideoEnabled::handle_event()
137         plugin->config.enabled = get_value();
138         plugin->send_configure_change();
139         return 1;
150 ReverseVideo::ReverseVideo(PluginServer *server)
151  : PluginVClient(server)
153         PLUGIN_CONSTRUCTOR_MACRO
157 ReverseVideo::~ReverseVideo()
159         PLUGIN_DESTRUCTOR_MACRO
162 char* ReverseVideo::plugin_title() { return N_("Reverse video"); }
163 int ReverseVideo::is_realtime() { return 1; }
165 #include "picon_png.h"
166 NEW_PICON_MACRO(ReverseVideo)
168 SHOW_GUI_MACRO(ReverseVideo, ReverseVideoThread)
170 RAISE_WINDOW_MACRO(ReverseVideo)
172 SET_STRING_MACRO(ReverseVideo);
175 int ReverseVideo::process_buffer(VFrame *frame,
176                 int64_t start_position,
177                 double frame_rate)
179         load_configuration();
181         if(config.enabled)
182                 read_frame(frame,
183                         0,
184                         input_position,
185                         frame_rate);
186         else
187                 read_frame(frame,
188                         0,
189                         start_position,
190                         frame_rate);
191         return 0;
197 int ReverseVideo::load_configuration()
199         KeyFrame *prev_keyframe, *next_keyframe;
200         next_keyframe = get_next_keyframe(get_source_position());
201         prev_keyframe = get_prev_keyframe(get_source_position());
202 // Previous keyframe stays in config object.
203         read_data(prev_keyframe);
205         int64_t prev_position = edl_to_local(prev_keyframe->position);
206         int64_t next_position = edl_to_local(next_keyframe->position);
208         if(prev_position == 0 && next_position == 0) 
209         {
210                 next_position = prev_position = get_source_start();
211         }
213 // Get range to flip in requested rate
214         int64_t range_start = prev_position;
215         int64_t range_end = next_position;
217 // Between keyframe and edge of range or no keyframes
218         if(range_start == range_end)
219         {
220 // Between first keyframe and start of effect
221                 if(get_source_position() >= get_source_start() &&
222                         get_source_position() < range_start)
223                 {
224                         range_start = get_source_start();
225                 }
226                 else
227 // Between last keyframe and end of effect
228                 if(get_source_position() >= range_start &&
229                         get_source_position() < get_source_start() + get_total_len())
230                 {
231                         range_end = get_source_start() + get_total_len();
232                 }
233                 else
234                 {
235 // Should never get here
236                         ;
237                 }
238         }
241 // Convert start position to new direction
242         if(get_direction() == PLAY_FORWARD)
243         {
244                 input_position = get_source_position() - range_start;
245                 input_position = range_end - input_position - 1;
246         }
247         else
248         {
249                 input_position = range_end - get_source_position();
250                 input_position = range_start + input_position + 1;
251         }
252 // printf("ReverseVideo::load_configuration 2 start=%lld end=%lld current=%lld input=%lld\n", 
253 // range_start, 
254 // range_end, 
255 // get_source_position(),
256 // input_position);
258         return 0;
261 int ReverseVideo::load_defaults()
263         char directory[BCTEXTLEN];
264 // set the default directory
265         sprintf(directory, "%sreversevideo.rc", BCASTDIR);
267 // load the defaults
268         defaults = new BC_Hash(directory);
269         defaults->load();
271         config.enabled = defaults->get("ENABLED", config.enabled);
272         return 0;
275 int ReverseVideo::save_defaults()
277         defaults->update("ENABLED", config.enabled);
278         defaults->save();
279         return 0;
282 void ReverseVideo::save_data(KeyFrame *keyframe)
284         FileXML output;
286 // cause data to be stored directly in text
287         output.set_shared_string(keyframe->data, MESSAGESIZE);
288         output.tag.set_title("REVERSEVIDEO");
289         output.tag.set_property("ENABLED", config.enabled);
290         output.append_tag();
291         output.terminate_string();
294 void ReverseVideo::read_data(KeyFrame *keyframe)
296         FileXML input;
298         input.set_shared_string(keyframe->data, strlen(keyframe->data));
300         int result = 0;
302         while(!input.read_tag())
303         {
304                 if(input.tag.title_is("REVERSEVIDEO"))
305                 {
306                         config.enabled = input.tag.get_property("ENABLED", config.enabled);
307                 }
308         }
311 void ReverseVideo::update_gui()
313         if(thread)
314         {
315                 load_configuration();
316                 thread->window->lock_window();
317                 thread->window->enabled->update(config.enabled);
318                 thread->window->unlock_window();
319         }