1 #include "bcdisplayinfo.h"
7 #include "plugincolors.h"
8 #include "pluginvclient.h"
15 #define _(String) gettext(String)
16 #define gettext_noop(String) String
17 #define N_(String) gettext_noop (String)
28 void copy_from(YUVConfig &src);
29 int equivalent(YUVConfig &src);
30 void interpolate(YUVConfig &prev,
39 class YUVLevel : public BC_FSlider
42 YUVLevel(YUVEffect *plugin, float *output, int x, int y);
48 class YUVWindow : public BC_Window
51 YUVWindow(YUVEffect *plugin, int x, int y);
52 void create_objects();
58 PLUGIN_THREAD_HEADER(YUVEffect, YUVThread, YUVWindow)
60 class YUVEffect : public PluginVClient
63 YUVEffect(PluginServer *server);
65 int process_realtime(VFrame *input, VFrame *output);
71 void save_data(KeyFrame *keyframe);
72 void read_data(KeyFrame *keyframe);
77 int load_configuration();
88 REGISTER_PLUGIN(YUVEffect)
96 YUVConfig::YUVConfig()
103 void YUVConfig::copy_from(YUVConfig &src)
110 int YUVConfig::equivalent(YUVConfig &src)
112 return EQUIV(y, src.y) && EQUIV(u, src.u) && EQUIV(v, src.v);
115 void YUVConfig::interpolate(YUVConfig &prev,
121 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
122 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
124 y = prev.y * prev_scale + next.y * next_scale;
125 u = prev.u * prev_scale + next.u * next_scale;
126 v = prev.v * prev_scale + next.v * next_scale;
136 YUVLevel::YUVLevel(YUVEffect *plugin, float *output, int x, int y)
146 this->plugin = plugin;
147 this->output = output;
150 int YUVLevel::handle_event()
152 *output = get_value();
153 plugin->send_configure_change();
158 YUVWindow::YUVWindow(YUVEffect *plugin, int x, int y)
159 : BC_Window(plugin->gui_string,
170 this->plugin = plugin;
173 void YUVWindow::create_objects()
175 int x = 10, y = 10, x1 = 50;
176 add_subwindow(new BC_Title(x, y, _("Y:")));
177 add_subwindow(this->y = new YUVLevel(plugin, &plugin->config.y, x1, y));
179 add_subwindow(new BC_Title(x, y, _("U:")));
180 add_subwindow(u = new YUVLevel(plugin, &plugin->config.u, x1, y));
182 add_subwindow(new BC_Title(x, y, _("V:")));
183 add_subwindow(v = new YUVLevel(plugin, &plugin->config.v, x1, y));
189 int YUVWindow::close_event()
191 // Set result to 1 to indicate a client side close
200 PLUGIN_THREAD_OBJECT(YUVEffect, YUVThread, YUVWindow)
207 YUVEffect::YUVEffect(PluginServer *server)
208 : PluginVClient(server)
210 PLUGIN_CONSTRUCTOR_MACRO
212 YUVEffect::~YUVEffect()
214 PLUGIN_DESTRUCTOR_MACRO
216 int YUVEffect::is_realtime()
221 char* YUVEffect::plugin_title()
226 NEW_PICON_MACRO(YUVEffect)
227 SHOW_GUI_MACRO(YUVEffect, YUVThread)
228 RAISE_WINDOW_MACRO(YUVEffect)
229 SET_STRING_MACRO(YUVEffect)
230 LOAD_CONFIGURATION_MACRO(YUVEffect, YUVConfig)
232 void YUVEffect::update_gui()
236 thread->window->lock_window();
237 load_configuration();
238 thread->window->y->update(config.y);
239 thread->window->u->update(config.u);
240 thread->window->v->update(config.v);
241 thread->window->unlock_window();
245 int YUVEffect::load_defaults()
247 char directory[BCTEXTLEN];
248 sprintf(directory, "%syuv.rc", BCASTDIR);
249 defaults = new Defaults(directory);
251 config.y = defaults->get("Y", config.y);
252 config.u = defaults->get("U", config.u);
253 config.v = defaults->get("V", config.v);
257 int YUVEffect::save_defaults()
259 defaults->update("Y", config.y);
260 defaults->update("U", config.u);
261 defaults->update("V", config.v);
266 void YUVEffect::save_data(KeyFrame *keyframe)
269 output.set_shared_string(keyframe->data, MESSAGESIZE);
270 output.tag.set_title("YUV");
271 output.tag.set_property("Y", config.y);
272 output.tag.set_property("U", config.u);
273 output.tag.set_property("V", config.v);
275 output.terminate_string();
278 void YUVEffect::read_data(KeyFrame *keyframe)
281 input.set_shared_string(keyframe->data, strlen(keyframe->data));
282 while(!input.read_tag())
284 if(input.tag.title_is("YUV"))
286 config.y = input.tag.get_property("Y", config.y);
287 config.u = input.tag.get_property("U", config.u);
288 config.v = input.tag.get_property("V", config.v);
294 static YUV yuv_static;
296 #define YUV_MACRO(type, max, components, use_yuv) \
298 for(int i = 0; i < input->get_h(); i++) \
300 type *in_row = (type*)input->get_rows()[i]; \
301 type *out_row = (type*)output->get_rows()[i]; \
303 for(int j = 0; j < w; j++) \
307 int y = (int)((float)in_row[0] * y_scale + 0.5); \
308 int u = (int)((float)(in_row[1] - (max / 2 + 1)) * u_scale + 0.5) + (max / 2 + 1); \
309 int v = (int)((float)(in_row[2] - (max / 2 + 1)) * v_scale + 0.5) + (max / 2 + 1); \
310 out_row[0] = CLIP(y, 0, max); \
311 out_row[1] = CLIP(u, 0, max); \
312 out_row[2] = CLIP(v, 0, max); \
316 int y, u, v, r, g, b; \
318 yuv_static.rgb_to_yuv_8(in_row[0], in_row[1], in_row[2], y, u, v); \
320 yuv_static.rgb_to_yuv_16(in_row[0], in_row[1], in_row[2], y, u, v); \
322 y = (int)((float)y * y_scale + 0.5); \
323 u = (int)((float)(u - (max / 2 + 1)) * u_scale + 0.5) + (max / 2 + 1); \
324 v = (int)((float)(v - (max / 2 + 1)) * v_scale + 0.5) + (max / 2 + 1); \
331 yuv_static.yuv_to_rgb_8(r, g, b, y, u, v); \
333 yuv_static.yuv_to_rgb_16(r, g, b, y, u, v); \
340 if(components == 4) \
341 out_row[3] = in_row[3]; \
342 in_row += components; \
343 out_row += components; \
348 int YUVEffect::process_realtime(VFrame *input, VFrame *output)
350 load_configuration();
352 if(EQUIV(config.y, 0) && EQUIV(config.u, 0) && EQUIV(config.v, 0))
354 if(input->get_rows()[0] != output->get_rows()[0])
355 output->copy_from(input);
359 int w = input->get_w();
361 float y_scale = (float)(config.y + MAXVALUE) / MAXVALUE;
362 float u_scale = (float)(config.u + MAXVALUE) / MAXVALUE;
363 float v_scale = (float)(config.v + MAXVALUE) / MAXVALUE;
365 if(u_scale > 1) u_scale = 1 + (u_scale - 1) * 4;
366 if(v_scale > 1) v_scale = 1 + (v_scale - 1) * 4;
368 switch(input->get_color_model())
371 YUV_MACRO(unsigned char, 0xff, 3, 0)
375 YUV_MACRO(unsigned char, 0xff, 3, 1)
379 YUV_MACRO(uint16_t, 0xffff, 3, 0)
383 YUV_MACRO(uint16_t, 0xffff, 3, 1)
387 YUV_MACRO(unsigned char, 0xff, 4, 0)
391 YUV_MACRO(unsigned char, 0xff, 4, 1)
394 case BC_RGBA16161616:
395 YUV_MACRO(uint16_t, 0xffff, 4, 0)
398 case BC_YUVA16161616:
399 YUV_MACRO(uint16_t, 0xffff, 4, 1)