5 #include "bcdisplayinfo.h"
7 #include "overlayframe.h"
14 #define _(String) gettext(String)
15 #define gettext_noop(String) String
16 #define N_(String) gettext_noop (String)
26 REGISTER_PLUGIN(_1080to480Main)
31 _1080to480Config::_1080to480Config()
36 int _1080to480Config::equivalent(_1080to480Config &that)
38 return first_field == that.first_field;
41 void _1080to480Config::copy_from(_1080to480Config &that)
43 first_field = that.first_field;
46 void _1080to480Config::interpolate(_1080to480Config &prev,
47 _1080to480Config &next,
59 _1080to480Window::_1080to480Window(_1080to480Main *client, int x, int y)
60 : BC_Window(client->gui_string,
71 this->client = client;
75 _1080to480Window::~_1080to480Window()
79 int _1080to480Window::create_objects()
83 add_tool(odd_first = new _1080to480Option(client, this, 1, x, y, _("Odd field first")));
85 add_tool(even_first = new _1080to480Option(client, this, 0, x, y, _("Even field first")));
92 WINDOW_CLOSE_EVENT(_1080to480Window)
94 int _1080to480Window::set_first_field(int first_field, int send_event)
96 odd_first->update(first_field == 1);
97 even_first->update(first_field == 0);
102 client->config.first_field = first_field;
103 client->send_configure_change();
111 _1080to480Option::_1080to480Option(_1080to480Main *client,
112 _1080to480Window *window,
119 client->config.first_field == output,
122 this->client = client;
123 this->window = window;
124 this->output = output;
127 int _1080to480Option::handle_event()
129 window->set_first_field(output, 1);
135 PLUGIN_THREAD_OBJECT(_1080to480Main, _1080to480Thread, _1080to480Window)
143 _1080to480Main::_1080to480Main(PluginServer *server)
144 : PluginVClient(server)
146 PLUGIN_CONSTRUCTOR_MACRO
150 _1080to480Main::~_1080to480Main()
152 PLUGIN_DESTRUCTOR_MACRO
153 if(temp) delete temp;
156 char* _1080to480Main::plugin_title() { return _("1080 to 480"); }
157 int _1080to480Main::is_realtime() { return 1; }
159 SHOW_GUI_MACRO(_1080to480Main, _1080to480Thread)
160 RAISE_WINDOW_MACRO(_1080to480Main)
161 SET_STRING_MACRO(_1080to480Main)
162 NEW_PICON_MACRO(_1080to480Main)
163 LOAD_CONFIGURATION_MACRO(_1080to480Main, _1080to480Config)
170 void _1080to480Main::reduce_field(VFrame *output, VFrame *input, int src_field, int dst_field)
172 int w = input->get_w();
173 int h = input->get_h();
175 if(h > output->get_h()) h = output->get_h();
176 if(w > output->get_w()) h = output->get_w();
178 #define REDUCE_MACRO(type, components) \
179 for(int i = 0; i < OUT_ROWS; i++) \
181 int in_number1 = dst_field * 2 + src_field + (int)(i * 9 / 4) * 2; \
182 int in_number2 = in_number1 + 2; \
183 int in_number3 = in_number2 + 2; \
184 int in_number4 = in_number3 + 2; \
185 int out_number = dst_field + i * 2; \
187 if(in_number1 >= h) in_number1 = h - 1; \
188 if(in_number2 >= h) in_number2 = h - 1; \
189 if(in_number3 >= h) in_number3 = h - 1; \
190 if(in_number4 >= h) in_number4 = h - 1; \
191 if(out_number >= h) out_number = h - 1; \
193 type *in_row1 = (type*)input->get_rows()[in_number1]; \
194 type *in_row2 = (type*)input->get_rows()[in_number2]; \
195 type *in_row3 = (type*)input->get_rows()[in_number3]; \
196 type *in_row4 = (type*)input->get_rows()[in_number4]; \
197 type *out_row = (type*)output->get_rows()[out_number]; \
199 for(int j = 0; j < w * components; j++) \
201 *out_row++ = ((int64_t)*in_row1++ + \
202 (int64_t)*in_row2++ + \
203 (int64_t)*in_row3++ + \
204 (int64_t)*in_row4++) >> 2; \
208 switch(input->get_color_model())
212 REDUCE_MACRO(unsigned char, 3);
216 REDUCE_MACRO(unsigned char, 4);
220 REDUCE_MACRO(uint16_t, 3);
222 case BC_RGBA16161616:
223 case BC_YUVA16161616:
224 REDUCE_MACRO(uint16_t, 4);
230 int _1080to480Main::process_realtime(VFrame *input, VFrame *output)
232 load_configuration();
238 input->get_color_model());
242 reduce_field(temp, input, config.first_field == 0 ? 0 : 1, 0);
243 reduce_field(temp, input, config.first_field == 0 ? 1 : 0, 1);
245 output->copy_from(temp);
251 int _1080to480Main::load_defaults()
253 char directory[BCTEXTLEN], string[BCTEXTLEN];
254 sprintf(directory, "%s1080to480.rc", BCASTDIR);
256 defaults = new Defaults(directory);
258 config.first_field = defaults->get("FIRST_FIELD", config.first_field);
263 int _1080to480Main::save_defaults()
265 defaults->update("FIRST_FIELD", config.first_field);
270 void _1080to480Main::save_data(KeyFrame *keyframe)
273 output.set_shared_string(keyframe->data, MESSAGESIZE);
274 output.tag.set_title("1080TO480");
275 output.tag.set_property("FIRST_FIELD", config.first_field);
277 output.terminate_string();
280 void _1080to480Main::read_data(KeyFrame *keyframe)
283 input.set_shared_string(keyframe->data, strlen(keyframe->data));
285 while(!input.read_tag())
287 if(input.tag.title_is("1080TO480"))
289 config.first_field = input.tag.get_property("FIRST_FIELD", config.first_field);
294 void _1080to480Main::update_gui()
298 load_configuration();
299 thread->window->lock_window();
300 thread->window->set_first_field(config.first_field, 0);
301 thread->window->unlock_window();