1 #include "bcdisplayinfo.h"
7 #include "pluginvclient.h"
8 #include "transportque.h"
22 class LoopVideoFrames : public BC_TextBox
25 LoopVideoFrames(LoopVideo *plugin,
32 class LoopVideoWindow : public BC_Window
35 LoopVideoWindow(LoopVideo *plugin, int x, int y);
37 void create_objects();
40 LoopVideoFrames *frames;
43 PLUGIN_THREAD_HEADER(LoopVideo, LoopVideoThread, LoopVideoWindow)
45 class LoopVideo : public PluginVClient
48 LoopVideo(PluginServer *server);
51 PLUGIN_CLASS_MEMBERS(LoopVideoConfig, LoopVideoThread)
55 void save_data(KeyFrame *keyframe);
56 void read_data(KeyFrame *keyframe);
60 int process_buffer(VFrame *frame,
61 int64_t start_position,
71 REGISTER_PLUGIN(LoopVideo);
75 LoopVideoConfig::LoopVideoConfig()
84 LoopVideoWindow::LoopVideoWindow(LoopVideo *plugin, int x, int y)
85 : BC_Window(plugin->gui_string,
96 this->plugin = plugin;
99 LoopVideoWindow::~LoopVideoWindow()
103 void LoopVideoWindow::create_objects()
107 add_subwindow(new BC_Title(x, y, _("Frames to loop:")));
109 add_subwindow(frames = new LoopVideoFrames(plugin,
116 WINDOW_CLOSE_EVENT(LoopVideoWindow)
119 PLUGIN_THREAD_OBJECT(LoopVideo, LoopVideoThread, LoopVideoWindow)
126 LoopVideoFrames::LoopVideoFrames(LoopVideo *plugin,
133 plugin->config.frames)
135 this->plugin = plugin;
138 int LoopVideoFrames::handle_event()
140 plugin->config.frames = atol(get_text());
141 plugin->config.frames = MAX(1, plugin->config.frames);
142 plugin->send_configure_change();
154 LoopVideo::LoopVideo(PluginServer *server)
155 : PluginVClient(server)
157 PLUGIN_CONSTRUCTOR_MACRO
161 LoopVideo::~LoopVideo()
163 PLUGIN_DESTRUCTOR_MACRO
166 char* LoopVideo::plugin_title() { return N_("Loop video"); }
167 int LoopVideo::is_realtime() { return 1; }
168 int LoopVideo::is_synthesis() { return 1; }
170 #include "picon_png.h"
171 NEW_PICON_MACRO(LoopVideo)
173 SHOW_GUI_MACRO(LoopVideo, LoopVideoThread)
175 RAISE_WINDOW_MACRO(LoopVideo)
177 SET_STRING_MACRO(LoopVideo);
180 int LoopVideo::process_buffer(VFrame *frame,
181 int64_t start_position,
184 int64_t current_loop_position;
186 // Truncate to next keyframe
187 if(get_direction() == PLAY_FORWARD)
189 // Get start of current loop
190 KeyFrame *prev_keyframe = get_prev_keyframe(start_position);
191 int64_t prev_position = edl_to_local(prev_keyframe->position);
192 if(prev_position == 0)
193 prev_position = get_source_start();
194 read_data(prev_keyframe);
196 // Get start of fragment in current loop
197 current_loop_position = prev_position +
198 ((start_position - prev_position) %
200 while(current_loop_position < prev_position) current_loop_position += config.frames;
201 while(current_loop_position >= prev_position + config.frames) current_loop_position -= config.frames;
205 KeyFrame *prev_keyframe = get_next_keyframe(start_position);
206 int64_t prev_position = edl_to_local(prev_keyframe->position);
207 if(prev_position == 0)
208 prev_position = get_source_start() + get_total_len();
209 read_data(prev_keyframe);
211 current_loop_position = prev_position -
212 ((prev_position - start_position) %
214 while(current_loop_position <= prev_position - config.frames) current_loop_position += config.frames;
215 while(current_loop_position > prev_position) current_loop_position -= config.frames;
219 // printf("LoopVideo::process_buffer 100 %lld %lld %lld %d\n",
220 // current_position, current_loop_position, current_loop_end, fragment_size);
223 current_loop_position,
232 int LoopVideo::load_configuration()
234 KeyFrame *prev_keyframe;
235 int64_t old_frames = config.frames;
236 prev_keyframe = get_prev_keyframe(get_source_position());
237 read_data(prev_keyframe);
238 config.frames = MAX(config.frames, 1);
239 return old_frames != config.frames;
242 int LoopVideo::load_defaults()
244 char directory[BCTEXTLEN];
245 // set the default directory
246 sprintf(directory, "%sloopaudio.rc", BCASTDIR);
249 defaults = new BC_Hash(directory);
252 config.frames = defaults->get("FRAMES", config.frames);
256 int LoopVideo::save_defaults()
258 defaults->update("FRAMES", config.frames);
263 void LoopVideo::save_data(KeyFrame *keyframe)
267 // cause data to be stored directly in text
268 output.set_shared_string(keyframe->data, MESSAGESIZE);
269 output.tag.set_title("LOOPVIDEO");
270 output.tag.set_property("FRAMES", config.frames);
272 output.tag.set_title("/LOOPVIDEO");
274 output.terminate_string();
277 void LoopVideo::read_data(KeyFrame *keyframe)
281 input.set_shared_string(keyframe->data, strlen(keyframe->data));
285 while(!input.read_tag())
287 if(input.tag.title_is("LOOPVIDEO"))
289 config.frames = input.tag.get_property("FRAMES", config.frames);
294 void LoopVideo::update_gui()
298 load_configuration();
299 thread->window->lock_window();
300 thread->window->frames->update(config.frames);
301 thread->window->unlock_window();