1 #include "bcdisplayinfo.h"
6 #include "loadbalance.h"
8 #include "plugincolors.h"
9 #include "pluginvclient.h"
19 #define _(String) gettext(String)
20 #define gettext_noop(String) String
21 #define N_(String) gettext_noop (String)
26 class VideoScopeEffect;
27 class VideoScopeEngine;
30 class VideoScopeConfig
36 class VideoScopeWaveform : public BC_SubWindow
39 VideoScopeWaveform(VideoScopeEffect *plugin,
44 VideoScopeEffect *plugin;
48 class VideoScopeVectorscope : public BC_SubWindow
51 VideoScopeVectorscope(VideoScopeEffect *plugin,
56 VideoScopeEffect *plugin;
59 class VideoScopeWindow : public BC_Window
62 VideoScopeWindow(VideoScopeEffect *plugin, int x, int y);
65 void calculate_sizes(int w, int h);
66 void create_objects();
68 int resize_event(int w, int h);
69 void allocate_bitmaps();
72 VideoScopeEffect *plugin;
73 VideoScopeWaveform *waveform;
74 VideoScopeVectorscope *vectorscope;
75 BC_Bitmap *waveform_bitmap;
76 BC_Bitmap *vector_bitmap;
78 int vector_x, vector_y, vector_w, vector_h;
79 int wave_x, wave_y, wave_w, wave_h;
82 PLUGIN_THREAD_HEADER(VideoScopeEffect, VideoScopeThread, VideoScopeWindow)
87 class VideoScopePackage : public LoadPackage
95 class VideoScopeUnit : public LoadClient
98 VideoScopeUnit(VideoScopeEffect *plugin, VideoScopeEngine *server);
99 void process_package(LoadPackage *package);
100 VideoScopeEffect *plugin;
104 class VideoScopeEngine : public LoadServer
107 VideoScopeEngine(VideoScopeEffect *plugin, int cpus);
109 void init_packages();
110 LoadClient* new_client();
111 LoadPackage* new_package();
112 VideoScopeEffect *plugin;
115 class VideoScopeEffect : public PluginVClient
118 VideoScopeEffect(PluginServer *server);
121 int process_realtime(VFrame *input, VFrame *output);
123 char* plugin_title();
130 void render_gui(void *input);
131 int load_configuration();
135 VideoScopeConfig config;
136 VideoScopeEngine *engine;
138 VideoScopeThread *thread;
153 VideoScopeConfig::VideoScopeConfig()
166 VideoScopeWaveform::VideoScopeWaveform(VideoScopeEffect *plugin,
171 : BC_SubWindow(x, y, w, h, BLACK)
173 this->plugin = plugin;
177 VideoScopeVectorscope::VideoScopeVectorscope(VideoScopeEffect *plugin,
182 : BC_SubWindow(x, y, w, h, BLACK)
184 this->plugin = plugin;
193 VideoScopeWindow::VideoScopeWindow(VideoScopeEffect *plugin,
196 : BC_Window(plugin->gui_string,
208 this->plugin = plugin;
213 VideoScopeWindow::~VideoScopeWindow()
216 if(waveform_bitmap) delete waveform_bitmap;
217 if(vector_bitmap) delete vector_bitmap;
220 void VideoScopeWindow::calculate_sizes(int w, int h)
224 wave_w = w / 2 - 5 - wave_x;
225 wave_h = h - 20 - wave_y;
226 vector_x = w / 2 + 30;
228 vector_w = w - 10 - vector_x;
229 vector_h = h - 10 - vector_y;
232 void VideoScopeWindow::create_objects()
234 calculate_sizes(get_w(), get_h());
236 add_subwindow(waveform = new VideoScopeWaveform(plugin, wave_x, wave_y, wave_w, wave_h));
237 add_subwindow(vectorscope = new VideoScopeVectorscope(plugin, vector_x, vector_y, vector_w, vector_h));
246 WINDOW_CLOSE_EVENT(VideoScopeWindow)
248 int VideoScopeWindow::resize_event(int w, int h)
251 clear_box(0, 0, w, h);
254 calculate_sizes(w, h);
255 waveform->reposition_window(wave_x, wave_y, wave_w, wave_h);
256 vectorscope->reposition_window(vector_x, vector_y, vector_w, vector_h);
257 waveform->clear_box(0, 0, wave_w, wave_h);
258 vectorscope->clear_box(0, 0, wave_w, wave_h);
266 void VideoScopeWindow::allocate_bitmaps()
268 if(waveform_bitmap) delete waveform_bitmap;
269 if(vector_bitmap) delete vector_bitmap;
271 waveform_bitmap = new_bitmap(wave_w, wave_h);
272 vector_bitmap = new_bitmap(vector_w, vector_h);
275 void VideoScopeWindow::draw_overlays()
280 for(int i = 0; i <= 10; i++)
282 int y = wave_h * i / 10;
283 int text_y = y + wave_y + 10;
285 char string[BCTEXTLEN];
286 sprintf(string, "%d", 100 - i * 10);
287 draw_text(x, text_y, string);
289 if(i > 0) waveform->draw_line(0, y, wave_w, y);
293 int radius = MIN(vector_w / 2, vector_h / 2);
294 for(int i = 0; i <= DIVISIONS; i++)
296 int x = vector_w / 2 - radius * i / DIVISIONS;
297 int y = vector_h / 2 - radius * i / DIVISIONS;
299 int w = radius * i / DIVISIONS * 2;
300 int h = radius * i / DIVISIONS * 2;
301 char string[BCTEXTLEN];
303 sprintf(string, "%d", i * 100 / DIVISIONS);
304 draw_text(vector_x - 20, text_y, string);
305 if(i > 0) vectorscope->draw_circle(x, y, w, h);
307 set_font(MEDIUMFONT);
310 vectorscope->flash();
321 PLUGIN_THREAD_OBJECT(VideoScopeEffect, VideoScopeThread, VideoScopeWindow)
327 REGISTER_PLUGIN(VideoScopeEffect)
334 VideoScopeEffect::VideoScopeEffect(PluginServer *server)
335 : PluginVClient(server)
340 PLUGIN_CONSTRUCTOR_MACRO
343 VideoScopeEffect::~VideoScopeEffect()
345 PLUGIN_DESTRUCTOR_MACRO
347 if(engine) delete engine;
351 int VideoScopeEffect::is_realtime()
356 char* VideoScopeEffect::plugin_title()
358 return _("VideoScope");
361 int VideoScopeEffect::load_configuration()
366 NEW_PICON_MACRO(VideoScopeEffect)
368 SHOW_GUI_MACRO(VideoScopeEffect, VideoScopeThread)
370 RAISE_WINDOW_MACRO(VideoScopeEffect)
372 SET_STRING_MACRO(VideoScopeEffect)
374 int VideoScopeEffect::load_defaults()
376 char directory[BCTEXTLEN];
377 // set the default directory
378 sprintf(directory, "%svideoscope.rc", BCASTDIR);
381 defaults = new Defaults(directory);
384 w = defaults->get("W", w);
385 h = defaults->get("H", h);
389 int VideoScopeEffect::save_defaults()
391 defaults->update("W", w);
392 defaults->update("H", h);
397 int VideoScopeEffect::process_realtime(VFrame *input, VFrame *output)
400 send_render_gui(input);
401 //printf("VideoScopeEffect::process_realtime 1\n");
402 if(input->get_rows()[0] != output->get_rows()[0])
403 output->copy_from(input);
407 void VideoScopeEffect::render_gui(void *input)
411 VideoScopeWindow *window = thread->window;
412 window->lock_window();
414 //printf("VideoScopeEffect::process_realtime 1\n");
415 this->input = (VFrame*)input;
416 //printf("VideoScopeEffect::process_realtime 1\n");
421 engine = new VideoScopeEngine(this,
422 (PluginClient::smp + 1));
425 //printf("VideoScopeEffect::process_realtime 1 %d\n", PluginClient::smp);
427 bzero(window->waveform_bitmap->get_data(),
428 window->waveform_bitmap->get_h() *
429 window->waveform_bitmap->get_bytes_per_line());
430 bzero(window->vector_bitmap->get_data(),
431 window->vector_bitmap->get_h() *
432 window->vector_bitmap->get_bytes_per_line());
434 engine->process_packages();
435 //printf("VideoScopeEffect::process_realtime 2\n");
436 //printf("VideoScopeEffect::process_realtime 1\n");
438 window->waveform->draw_bitmap(window->waveform_bitmap,
443 //printf("VideoScopeEffect::process_realtime 1\n");
444 window->vectorscope->draw_bitmap(window->vector_bitmap,
450 window->draw_overlays();
453 window->unlock_window();
461 VideoScopePackage::VideoScopePackage()
471 VideoScopeUnit::VideoScopeUnit(VideoScopeEffect *plugin,
472 VideoScopeEngine *server)
475 this->plugin = plugin;
479 #define INTENSITY(p) ((unsigned int)(((p)[0]) * 77+ \
484 static void draw_point(unsigned char **rows, int color_model, int x, int y, int r, int g, int b)
490 unsigned char *pixel = rows[y] + x * 4;
500 unsigned char *pixel = rows[y] + x * 2;
501 pixel[0] = (r & 0xf8) | (g >> 5);
502 pixel[1] = ((g & 0xfc) << 5) | (b >> 3);
514 #define VIDEOSCOPE(type, max, components, use_yuv) \
516 for(int i = pkg->row1; i < pkg->row2; i++) \
518 type *in_row = (type*)plugin->input->get_rows()[i]; \
519 for(int j = 0; j < w; j++) \
521 type *in_pixel = in_row + j * components; \
524 /* Analyze pixel */ \
525 if(use_yuv) intensity = (float)*in_pixel / max; \
533 yuv.yuv_to_rgb_16(r, g, b, in_pixel[0], in_pixel[1], in_pixel[2]); \
537 yuv.yuv_to_rgb_8(r, g, b, in_pixel[0], in_pixel[1], in_pixel[2]); \
547 HSV::rgb_to_hsv((float)r / max, \
561 /* Calculate waveform */ \
562 if(!use_yuv) intensity = v; \
563 intensity = intensity * \
565 int y = waveform_h - (int)intensity; \
566 int x = j * waveform_w / w; \
567 if(x >= 0 && x < waveform_w && y >= 0 && y < waveform_h) \
568 draw_point(waveform_rows, waveform_cmodel, x, y, 0xff, 0xff, 0xff); \
570 /* Calculate vectorscope */ \
571 float adjacent = cos(h / 360 * 2 * M_PI); \
572 float opposite = sin(h / 360 * 2 * M_PI); \
573 x = (int)(vector_w / 2 + \
574 adjacent * s * radius); \
576 y = (int)(vector_h / 2 - \
577 opposite * s * radius); \
580 CLAMP(x, 0, vector_w - 1); \
581 CLAMP(y, 0, vector_h - 1); \
582 draw_point(vector_rows, vector_cmodel, x, y, r, g, b); \
588 void VideoScopeUnit::process_package(LoadPackage *package)
590 VideoScopeWindow *window = plugin->thread->window;
591 VideoScopePackage *pkg = (VideoScopePackage*)package;
592 int w = plugin->input->get_w();
593 int h = plugin->input->get_h();
594 int waveform_h = window->waveform_bitmap->get_h();
595 int waveform_w = window->waveform_bitmap->get_w();
596 int waveform_cmodel = window->waveform_bitmap->get_color_model();
597 unsigned char **waveform_rows = window->waveform_bitmap->get_row_pointers();
598 int vector_h = window->vector_bitmap->get_h();
599 int vector_w = window->vector_bitmap->get_w();
600 int vector_cmodel = window->vector_bitmap->get_color_model();
601 unsigned char **vector_rows = window->vector_bitmap->get_row_pointers();
602 float radius = MIN(vector_w / 2, vector_h / 2);
604 switch(plugin->input->get_color_model())
607 VIDEOSCOPE(unsigned char, 0xff, 3, 0)
611 VIDEOSCOPE(unsigned char, 0xff, 3, 1)
615 VIDEOSCOPE(uint16_t, 0xffff, 3, 0)
619 VIDEOSCOPE(uint16_t, 0xffff, 3, 1)
623 VIDEOSCOPE(unsigned char, 0xff, 4, 0)
627 VIDEOSCOPE(unsigned char, 0xff, 4, 1)
630 case BC_RGBA16161616:
631 VIDEOSCOPE(uint16_t, 0xffff, 4, 0)
634 case BC_YUVA16161616:
635 VIDEOSCOPE(uint16_t, 0xffff, 4, 1)
645 VideoScopeEngine::VideoScopeEngine(VideoScopeEffect *plugin, int cpus)
646 : LoadServer(cpus, cpus)
648 this->plugin = plugin;
651 VideoScopeEngine::~VideoScopeEngine()
655 void VideoScopeEngine::init_packages()
657 int increment = plugin->input->get_h() / LoadServer::total_packages + 1;
659 for(int i = 0; i < LoadServer::total_packages; i++)
661 VideoScopePackage *pkg = (VideoScopePackage*)packages[i];
663 pkg->row2 = y + increment;
665 if(pkg->row2 > plugin->input->get_h())
667 y = pkg->row2 = plugin->input->get_h();
673 LoadClient* VideoScopeEngine::new_client()
675 return new VideoScopeUnit(plugin, this);
678 LoadPackage* VideoScopeEngine::new_package()
680 return new VideoScopePackage;