1 #include "bcdisplayinfo.h"
6 #include "transportque.h"
8 #include "mainprogress.h"
10 #include "pluginvclient.h"
11 #include "transportque.inc"
17 #define TOP_FIELD_FIRST 0
18 #define BOTTOM_FIELD_FIRST 1
21 class FieldFrameWindow;
29 class FieldFrameConfig
33 int equivalent(FieldFrameConfig &src);
41 class FieldFrameTop : public BC_Radial
44 FieldFrameTop(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y);
47 FieldFrameWindow *gui;
51 class FieldFrameBottom : public BC_Radial
54 FieldFrameBottom(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y);
57 FieldFrameWindow *gui;
60 // class FieldFrameFirst : public BC_Radial
63 // FieldFrameFirst(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y);
64 // int handle_event();
65 // FieldFrame *plugin;
66 // FieldFrameWindow *gui;
69 // class FieldFrameSecond : public BC_Radial
72 // FieldFrameSecond(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y);
73 // int handle_event();
74 // FieldFrame *plugin;
75 // FieldFrameWindow *gui;
78 class FieldFrameWindow : public BC_Window
81 FieldFrameWindow(FieldFrame *plugin, int x, int y);
82 void create_objects();
86 FieldFrameBottom *bottom;
87 // FieldFrameFirst *first;
88 // FieldFrameSecond *second;
92 PLUGIN_THREAD_HEADER(FieldFrame, FieldFrameThread, FieldFrameWindow)
95 class FieldFrame : public PluginVClient
98 FieldFrame(PluginServer *server);
101 PLUGIN_CLASS_MEMBERS(FieldFrameConfig, FieldFrameThread);
103 int process_buffer(VFrame *frame,
104 int64_t start_position,
109 void save_data(KeyFrame *keyframe);
110 void read_data(KeyFrame *keyframe);
112 void apply_field(VFrame *output, VFrame *input, int field);
125 REGISTER_PLUGIN(FieldFrame)
130 FieldFrameConfig::FieldFrameConfig()
132 field_dominance = TOP_FIELD_FIRST;
136 int FieldFrameConfig::equivalent(FieldFrameConfig &src)
138 return src.field_dominance == field_dominance &&
139 src.first_frame == first_frame;
149 FieldFrameWindow::FieldFrameWindow(FieldFrame *plugin, int x, int y)
150 : BC_Window(plugin->gui_string,
161 this->plugin = plugin;
164 void FieldFrameWindow::create_objects()
167 add_subwindow(top = new FieldFrameTop(plugin, this, x, y));
169 add_subwindow(bottom = new FieldFrameBottom(plugin, this, x, y));
171 // add_subwindow(first = new FieldFrameFirst(plugin, this, x, y));
173 // add_subwindow(second = new FieldFrameSecond(plugin, this, x, y));
179 WINDOW_CLOSE_EVENT(FieldFrameWindow)
193 FieldFrameTop::FieldFrameTop(FieldFrame *plugin,
194 FieldFrameWindow *gui,
199 plugin->config.field_dominance == TOP_FIELD_FIRST,
200 _("Top field first"))
202 this->plugin = plugin;
206 int FieldFrameTop::handle_event()
208 plugin->config.field_dominance = TOP_FIELD_FIRST;
209 gui->bottom->update(0);
210 plugin->send_configure_change();
218 FieldFrameBottom::FieldFrameBottom(FieldFrame *plugin,
219 FieldFrameWindow *gui,
224 plugin->config.field_dominance == BOTTOM_FIELD_FIRST,
225 _("Bottom field first"))
227 this->plugin = plugin;
231 int FieldFrameBottom::handle_event()
233 plugin->config.field_dominance = BOTTOM_FIELD_FIRST;
235 plugin->send_configure_change();
243 // FieldFrameFirst::FieldFrameFirst(FieldFrame *plugin,
244 // FieldFrameWindow *gui,
249 // plugin->config.first_frame == 0,
250 // _("First frame is first field"))
252 // this->plugin = plugin;
256 // int FieldFrameFirst::handle_event()
258 // plugin->config.first_frame = 0;
259 // gui->second->update(0);
260 // plugin->send_configure_change();
267 // FieldFrameSecond::FieldFrameSecond(FieldFrame *plugin,
268 // FieldFrameWindow *gui,
273 // plugin->config.first_frame == 1,
274 // _("Second frame is first field"))
276 // this->plugin = plugin;
280 // int FieldFrameSecond::handle_event()
282 // plugin->config.first_frame = 1;
283 // gui->first->update(0);
284 // plugin->send_configure_change();
303 PLUGIN_THREAD_OBJECT(FieldFrame, FieldFrameThread, FieldFrameWindow)
309 FieldFrame::FieldFrame(PluginServer *server)
310 : PluginVClient(server)
312 PLUGIN_CONSTRUCTOR_MACRO
317 FieldFrame::~FieldFrame()
319 PLUGIN_DESTRUCTOR_MACRO
321 if(input) delete input;
324 char* FieldFrame::plugin_title() { return N_("Fields to frames"); }
325 int FieldFrame::is_realtime() { return 1; }
328 NEW_PICON_MACRO(FieldFrame)
330 SHOW_GUI_MACRO(FieldFrame, FieldFrameThread)
332 RAISE_WINDOW_MACRO(FieldFrame)
334 SET_STRING_MACRO(FieldFrame);
336 int FieldFrame::load_configuration()
338 KeyFrame *prev_keyframe;
339 FieldFrameConfig old_config = config;
341 prev_keyframe = get_prev_keyframe(get_source_position());
342 read_data(prev_keyframe);
344 return !old_config.equivalent(config);
348 int FieldFrame::load_defaults()
350 char directory[BCTEXTLEN];
351 // set the default directory
352 sprintf(directory, "%sfieldframe.rc", BCASTDIR);
355 defaults = new BC_Hash(directory);
358 config.field_dominance = defaults->get("DOMINANCE", config.field_dominance);
359 config.first_frame = defaults->get("FIRST_FRAME", config.first_frame);
363 int FieldFrame::save_defaults()
365 defaults->update("DOMINANCE", config.field_dominance);
366 defaults->update("FIRST_FRAME", config.first_frame);
371 void FieldFrame::save_data(KeyFrame *keyframe)
375 // cause data to be stored directly in text
376 output.set_shared_string(keyframe->data, MESSAGESIZE);
377 output.tag.set_title("FIELD_FRAME");
378 output.tag.set_property("DOMINANCE", config.field_dominance);
379 output.tag.set_property("FIRST_FRAME", config.first_frame);
381 output.tag.set_title("/FIELD_FRAME");
383 output.terminate_string();
386 void FieldFrame::read_data(KeyFrame *keyframe)
390 input.set_shared_string(keyframe->data, strlen(keyframe->data));
394 while(!input.read_tag())
396 if(input.tag.title_is("FIELD_FRAME"))
398 config.field_dominance = input.tag.get_property("DOMINANCE", config.field_dominance);
399 config.first_frame = input.tag.get_property("FIRST_FRAME", config.first_frame);
405 void FieldFrame::update_gui()
409 if(load_configuration())
411 thread->window->lock_window();
412 thread->window->top->update(config.field_dominance == TOP_FIELD_FIRST);
413 thread->window->bottom->update(config.field_dominance == BOTTOM_FIELD_FIRST);
414 // thread->window->first->update(config.first_frame == 0);
415 // thread->window->second->update(config.first_frame == 1);
416 thread->window->unlock_window();
422 int FieldFrame::process_buffer(VFrame *frame,
423 int64_t start_position,
427 load_configuration();
429 if(input && !input->equivalent(frame, 0))
437 input = new VFrame(0,
440 frame->get_color_model());
444 int64_t field1_position = start_position * 2;
445 int64_t field2_position = start_position * 2 + 1;
447 if (get_direction() == PLAY_REVERSE)
449 field1_position -= 1;
450 field2_position -= 1;
454 // printf("FieldFrame::process_buffer %d %lld %lld\n",
455 // config.field_dominance,
464 config.field_dominance == TOP_FIELD_FIRST ? 0 : 1);
471 config.field_dominance == TOP_FIELD_FIRST ? 1 : 0);
481 void FieldFrame::apply_field(VFrame *output, VFrame *input, int field)
483 unsigned char **input_rows = input->get_rows();
484 unsigned char **output_rows = output->get_rows();
485 int row_size = VFrame::calculate_bytes_per_pixel(output->get_color_model()) * output->get_w();
486 for(int i = field; i < output->get_h(); i += 2)
488 memcpy(output_rows[i], input_rows[i], row_size);