00001 #include "bcdisplayinfo.h"
00002 #include "clip.h"
00003 #include "bchash.h"
00004 #include "filexml.h"
00005 #include "guicast.h"
00006 #include "language.h"
00007 #include "pluginvclient.h"
00008 #include "transportque.h"
00009
00010 #include <string.h>
00011
00012 class LoopVideo;
00013
00014 class LoopVideoConfig
00015 {
00016 public:
00017 LoopVideoConfig();
00018 int64_t frames;
00019 };
00020
00021
00022 class LoopVideoFrames : public BC_TextBox
00023 {
00024 public:
00025 LoopVideoFrames(LoopVideo *plugin,
00026 int x,
00027 int y);
00028 int handle_event();
00029 LoopVideo *plugin;
00030 };
00031
00032 class LoopVideoWindow : public BC_Window
00033 {
00034 public:
00035 LoopVideoWindow(LoopVideo *plugin, int x, int y);
00036 ~LoopVideoWindow();
00037 void create_objects();
00038 int close_event();
00039 LoopVideo *plugin;
00040 LoopVideoFrames *frames;
00041 };
00042
00043 PLUGIN_THREAD_HEADER(LoopVideo, LoopVideoThread, LoopVideoWindow)
00044
00045 class LoopVideo : public PluginVClient
00046 {
00047 public:
00048 LoopVideo(PluginServer *server);
00049 ~LoopVideo();
00050
00051 PLUGIN_CLASS_MEMBERS(LoopVideoConfig, LoopVideoThread)
00052
00053 int load_defaults();
00054 int save_defaults();
00055 void save_data(KeyFrame *keyframe);
00056 void read_data(KeyFrame *keyframe);
00057 void update_gui();
00058 int is_realtime();
00059 int is_synthesis();
00060 int process_buffer(VFrame *frame,
00061 int64_t start_position,
00062 double frame_rate);
00063 };
00064
00065
00066
00067
00068
00069
00070
00071 REGISTER_PLUGIN(LoopVideo);
00072
00073
00074
00075 LoopVideoConfig::LoopVideoConfig()
00076 {
00077 frames = 30;
00078 }
00079
00080
00081
00082
00083
00084 LoopVideoWindow::LoopVideoWindow(LoopVideo *plugin, int x, int y)
00085 : BC_Window(plugin->gui_string,
00086 x,
00087 y,
00088 210,
00089 160,
00090 200,
00091 160,
00092 0,
00093 0,
00094 1)
00095 {
00096 this->plugin = plugin;
00097 }
00098
00099 LoopVideoWindow::~LoopVideoWindow()
00100 {
00101 }
00102
00103 void LoopVideoWindow::create_objects()
00104 {
00105 int x = 10, y = 10;
00106
00107 add_subwindow(new BC_Title(x, y, _("Frames to loop:")));
00108 y += 20;
00109 add_subwindow(frames = new LoopVideoFrames(plugin,
00110 x,
00111 y));
00112 show_window();
00113 flush();
00114 }
00115
00116 WINDOW_CLOSE_EVENT(LoopVideoWindow)
00117
00118
00119 PLUGIN_THREAD_OBJECT(LoopVideo, LoopVideoThread, LoopVideoWindow)
00120
00121
00122
00123
00124
00125
00126 LoopVideoFrames::LoopVideoFrames(LoopVideo *plugin,
00127 int x,
00128 int y)
00129 : BC_TextBox(x,
00130 y,
00131 100,
00132 1,
00133 plugin->config.frames)
00134 {
00135 this->plugin = plugin;
00136 }
00137
00138 int LoopVideoFrames::handle_event()
00139 {
00140 plugin->config.frames = atol(get_text());
00141 plugin->config.frames = MAX(1, plugin->config.frames);
00142 plugin->send_configure_change();
00143 return 1;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 LoopVideo::LoopVideo(PluginServer *server)
00155 : PluginVClient(server)
00156 {
00157 PLUGIN_CONSTRUCTOR_MACRO
00158 }
00159
00160
00161 LoopVideo::~LoopVideo()
00162 {
00163 PLUGIN_DESTRUCTOR_MACRO
00164 }
00165
00166 char* LoopVideo::plugin_title() { return N_("Loop video"); }
00167 int LoopVideo::is_realtime() { return 1; }
00168 int LoopVideo::is_synthesis() { return 1; }
00169
00170 #include "picon_png.h"
00171 NEW_PICON_MACRO(LoopVideo)
00172
00173 SHOW_GUI_MACRO(LoopVideo, LoopVideoThread)
00174
00175 RAISE_WINDOW_MACRO(LoopVideo)
00176
00177 SET_STRING_MACRO(LoopVideo);
00178
00179
00180 int LoopVideo::process_buffer(VFrame *frame,
00181 int64_t start_position,
00182 double frame_rate)
00183 {
00184 int64_t current_loop_position;
00185
00186
00187 if(get_direction() == PLAY_FORWARD)
00188 {
00189
00190 KeyFrame *prev_keyframe = get_prev_keyframe(start_position);
00191 int64_t prev_position = edl_to_local(prev_keyframe->position);
00192 if(prev_position == 0)
00193 prev_position = get_source_start();
00194 read_data(prev_keyframe);
00195
00196
00197 current_loop_position = prev_position +
00198 ((start_position - prev_position) %
00199 config.frames);
00200 while(current_loop_position < prev_position) current_loop_position += config.frames;
00201 while(current_loop_position >= prev_position + config.frames) current_loop_position -= config.frames;
00202 }
00203 else
00204 {
00205 KeyFrame *prev_keyframe = get_next_keyframe(start_position);
00206 int64_t prev_position = edl_to_local(prev_keyframe->position);
00207 if(prev_position == 0)
00208 prev_position = get_source_start() + get_total_len();
00209 read_data(prev_keyframe);
00210
00211 current_loop_position = prev_position -
00212 ((prev_position - start_position) %
00213 config.frames);
00214 while(current_loop_position <= prev_position - config.frames) current_loop_position += config.frames;
00215 while(current_loop_position > prev_position) current_loop_position -= config.frames;
00216 }
00217
00218
00219
00220
00221 read_frame(frame,
00222 0,
00223 current_loop_position,
00224 frame_rate);
00225
00226 return 0;
00227 }
00228
00229
00230
00231
00232 int LoopVideo::load_configuration()
00233 {
00234 KeyFrame *prev_keyframe;
00235 int64_t old_frames = config.frames;
00236 prev_keyframe = get_prev_keyframe(get_source_position());
00237 read_data(prev_keyframe);
00238 config.frames = MAX(config.frames, 1);
00239 return old_frames != config.frames;
00240 }
00241
00242 int LoopVideo::load_defaults()
00243 {
00244 char directory[BCTEXTLEN];
00245
00246 sprintf(directory, "%sloopaudio.rc", BCASTDIR);
00247
00248
00249 defaults = new BC_Hash(directory);
00250 defaults->load();
00251
00252 config.frames = defaults->get("FRAMES", config.frames);
00253 return 0;
00254 }
00255
00256 int LoopVideo::save_defaults()
00257 {
00258 defaults->update("FRAMES", config.frames);
00259 defaults->save();
00260 return 0;
00261 }
00262
00263 void LoopVideo::save_data(KeyFrame *keyframe)
00264 {
00265 FileXML output;
00266
00267
00268 output.set_shared_string(keyframe->data, MESSAGESIZE);
00269 output.tag.set_title("LOOPVIDEO");
00270 output.tag.set_property("FRAMES", config.frames);
00271 output.append_tag();
00272 output.tag.set_title("/LOOPVIDEO");
00273 output.append_tag();
00274 output.terminate_string();
00275 }
00276
00277 void LoopVideo::read_data(KeyFrame *keyframe)
00278 {
00279 FileXML input;
00280
00281 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00282
00283 int result = 0;
00284
00285 while(!input.read_tag())
00286 {
00287 if(input.tag.title_is("LOOPVIDEO"))
00288 {
00289 config.frames = input.tag.get_property("FRAMES", config.frames);
00290 }
00291 }
00292 }
00293
00294 void LoopVideo::update_gui()
00295 {
00296 if(thread)
00297 {
00298 load_configuration();
00299 thread->window->lock_window();
00300 thread->window->frames->update(config.frames);
00301 thread->window->unlock_window();
00302 }
00303 }
00304
00305
00306
00307
00308