X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fmotion%2Fmotion.C;h=63d02302bbb9ae0d154c9da9d35b27b53357eb30;hb=5a1b2bb96f2bd6b7ef4f8031763683726c02219d;hp=447ed2d6a55ba29a5b5177bf6f180fd6df48647b;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/motion/motion.C b/cinelerra-5.1/plugins/motion/motion.C index 447ed2d6..63d02302 100644 --- a/cinelerra-5.1/plugins/motion/motion.C +++ b/cinelerra-5.1/plugins/motion/motion.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2012 Adam Williams + * Copyright (C) 2016 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ #include "mutex.h" #include "overlayframe.h" #include "rotateframe.h" +#include "rotatescan.h" #include "transportque.h" @@ -41,7 +42,6 @@ REGISTER_PLUGIN(MotionMain) - #undef DEBUG // #ifndef DEBUG @@ -63,16 +63,15 @@ MotionConfig::MotionConfig() // rotation_block_h = MIN_BLOCK; block_x = 50; block_y = 50; - global_positions = 256; - rotate_positions = 4; +// global_positions = 256; +// rotate_positions = 4; magnitude = 100; rotate_magnitude = 90; return_speed = 0; rotate_return_speed = 0; action_type = MotionScan::STABILIZE; - global = 1; +// global = 1; rotate = 1; - addtrackedframeoffset = 0; tracking_type = MotionScan::NO_CALCULATE; draw_vectors = 1; tracking_object = MotionScan::TRACK_SINGLE; @@ -102,9 +101,8 @@ int MotionConfig::equivalent(MotionConfig &that) rotation_range == that.rotation_range && rotation_center == that.rotation_center && action_type == that.action_type && - global == that.global && +// global == that.global && rotate == that.rotate && - addtrackedframeoffset == that.addtrackedframeoffset && draw_vectors == that.draw_vectors && block_count == that.block_count && global_block_w == that.global_block_w && @@ -113,8 +111,8 @@ int MotionConfig::equivalent(MotionConfig &that) // rotation_block_h == that.rotation_block_h && EQUIV(block_x, that.block_x) && EQUIV(block_y, that.block_y) && - global_positions == that.global_positions && - rotate_positions == that.rotate_positions && +// global_positions == that.global_positions && +// rotate_positions == that.rotate_positions && magnitude == that.magnitude && return_speed == that.return_speed && rotate_return_speed == that.rotate_return_speed && @@ -133,16 +131,15 @@ void MotionConfig::copy_from(MotionConfig &that) rotation_range = that.rotation_range; rotation_center = that.rotation_center; action_type = that.action_type; - global = that.global; +// global = that.global; rotate = that.rotate; - addtrackedframeoffset = that.addtrackedframeoffset; tracking_type = that.tracking_type; draw_vectors = that.draw_vectors; block_count = that.block_count; block_x = that.block_x; block_y = that.block_y; - global_positions = that.global_positions; - rotate_positions = that.rotate_positions; +// global_positions = that.global_positions; +// rotate_positions = that.rotate_positions; global_block_w = that.global_block_w; global_block_h = that.global_block_h; // rotation_block_w = that.rotation_block_w; @@ -173,14 +170,13 @@ void MotionConfig::interpolate(MotionConfig &prev, rotation_range = prev.rotation_range; rotation_center = prev.rotation_center; action_type = prev.action_type; - global = prev.global; +// global = prev.global; rotate = prev.rotate; - addtrackedframeoffset = prev.addtrackedframeoffset; tracking_type = prev.tracking_type; draw_vectors = prev.draw_vectors; block_count = prev.block_count; - global_positions = prev.global_positions; - rotate_positions = prev.rotate_positions; +// global_positions = prev.global_positions; +// rotate_positions = prev.rotate_positions; global_block_w = prev.global_block_w; global_block_h = prev.global_block_h; // rotation_block_w = prev.rotation_block_w; @@ -219,7 +215,7 @@ MotionMain::MotionMain(PluginServer *server) { engine = 0; rotate_engine = 0; - motion_rotate = 0; +// motion_rotate = 0; total_dx = 0; total_dy = 0; total_angle = 0; @@ -248,7 +244,7 @@ MotionMain::~MotionMain() delete [] search_area; delete temp_frame; delete rotate_engine; - delete motion_rotate; +// delete motion_rotate; delete prev_global_ref; @@ -281,11 +277,11 @@ void MotionMain::update_gui() { thread->window->lock_window("MotionMain::update_gui"); - char string[BCTEXTLEN]; - sprintf(string, "%d", config.global_positions); - ((MotionWindow*)thread->window)->global_search_positions->set_text(string); - sprintf(string, "%d", config.rotate_positions); - ((MotionWindow*)thread->window)->rotation_search_positions->set_text(string); +// char string[BCTEXTLEN]; +// sprintf(string, "%d", config.global_positions); +// ((MotionWindow*)thread->window)->global_search_positions->set_text(string); +// sprintf(string, "%d", config.rotate_positions); +// ((MotionWindow*)thread->window)->rotation_search_positions->set_text(string); ((MotionWindow*)thread->window)->global_block_w->update(config.global_block_w); ((MotionWindow*)thread->window)->global_block_h->update(config.global_block_h); @@ -340,8 +336,8 @@ void MotionMain::save_data(KeyFrame *keyframe) output.tag.set_title("MOTION"); output.tag.set_property("BLOCK_COUNT", config.block_count); - output.tag.set_property("GLOBAL_POSITIONS", config.global_positions); - output.tag.set_property("ROTATE_POSITIONS", config.rotate_positions); +// output.tag.set_property("GLOBAL_POSITIONS", config.global_positions); +// output.tag.set_property("ROTATE_POSITIONS", config.rotate_positions); output.tag.set_property("GLOBAL_BLOCK_W", config.global_block_w); output.tag.set_property("GLOBAL_BLOCK_H", config.global_block_h); // output.tag.set_property("ROTATION_BLOCK_W", config.rotation_block_w); @@ -357,9 +353,8 @@ void MotionMain::save_data(KeyFrame *keyframe) output.tag.set_property("ROTATE_MAGNITUDE", config.rotate_magnitude); output.tag.set_property("ROTATE_RETURN_SPEED", config.rotate_return_speed); output.tag.set_property("ACTION_TYPE", config.action_type); - output.tag.set_property("GLOBAL", config.global); +// output.tag.set_property("GLOBAL", config.global); output.tag.set_property("ROTATE", config.rotate); - output.tag.set_property("ADDTRACKEDFRAMEOFFSET", config.addtrackedframeoffset); output.tag.set_property("TRACKING_TYPE", config.tracking_type); output.tag.set_property("DRAW_VECTORS", config.draw_vectors); output.tag.set_property("TRACKING_OBJECT", config.tracking_object); @@ -390,8 +385,8 @@ void MotionMain::read_data(KeyFrame *keyframe) if(input.tag.title_is("MOTION")) { config.block_count = input.tag.get_property("BLOCK_COUNT", config.block_count); - config.global_positions = input.tag.get_property("GLOBAL_POSITIONS", config.global_positions); - config.rotate_positions = input.tag.get_property("ROTATE_POSITIONS", config.rotate_positions); +// config.global_positions = input.tag.get_property("GLOBAL_POSITIONS", config.global_positions); +// config.rotate_positions = input.tag.get_property("ROTATE_POSITIONS", config.rotate_positions); config.global_block_w = input.tag.get_property("GLOBAL_BLOCK_W", config.global_block_w); config.global_block_h = input.tag.get_property("GLOBAL_BLOCK_H", config.global_block_h); // config.rotation_block_w = input.tag.get_property("ROTATION_BLOCK_W", config.rotation_block_w); @@ -407,9 +402,8 @@ void MotionMain::read_data(KeyFrame *keyframe) config.rotate_magnitude = input.tag.get_property("ROTATE_MAGNITUDE", config.rotate_magnitude); config.rotate_return_speed = input.tag.get_property("ROTATE_RETURN_SPEED", config.rotate_return_speed); config.action_type = input.tag.get_property("ACTION_TYPE", config.action_type); - config.global = input.tag.get_property("GLOBAL", config.global); +// config.global = input.tag.get_property("GLOBAL", config.global); config.rotate = input.tag.get_property("ROTATE", config.rotate); - config.addtrackedframeoffset = input.tag.get_property("ADDTRACKEDFRAMEOFFSET", config.addtrackedframeoffset); config.tracking_type = input.tag.get_property("TRACKING_TYPE", config.tracking_type); config.draw_vectors = input.tag.get_property("DRAW_VECTORS", config.draw_vectors); config.tracking_object = input.tag.get_property("TRACKING_OBJECT", config.tracking_object); @@ -447,30 +441,39 @@ void MotionMain::allocate_temp(int w, int h, int color_model) void MotionMain::process_global() { + int w = current_global_ref->get_w(); + int h = current_global_ref->get_h(); + if(!engine) engine = new MotionScan(PluginClient::get_project_smp() + 1, PluginClient::get_project_smp() + 1); // Determine if frames changed +// printf("MotionMain::process_global %d block_y=%f total_dy=%d\n", +// __LINE__, config.block_y * h / 100, total_dy); engine->scan_frame(current_global_ref, prev_global_ref, - config.global_range_w, - config.global_range_h, - config.global_block_w, - config.global_block_h, - config.block_x, - config.block_y, + config.global_range_w * w / 100, + config.global_range_h * h / 100, + config.global_block_w * w / 100, + config.global_block_h * h / 100, + config.block_x * w / 100, + config.block_y * h / 100, config.tracking_object, config.tracking_type, config.action_type, config.horizontal_only, config.vertical_only, get_source_position(), - config.global_positions, total_dx, total_dy, 0, - 0); + 0, + 1, // do_motion + config.rotate, // do_rotate + config.rotation_center, + config.rotation_range); + current_dx = engine->dx_result; current_dy = engine->dy_result; @@ -482,9 +485,8 @@ void MotionMain::process_global() total_dy = (int64_t)total_dy * (100 - config.return_speed) / 100; total_dx += engine->dx_result; total_dy += engine->dy_result; -// printf("MotionMain::process_global total_dx=%d engine->dx_result=%d\n", -// total_dx, -// engine->dx_result); +// printf("MotionMain::process_global %d total_dy=%d engine->dy_result=%d\n", +// __LINE__, total_dy, engine->dy_result); } else // Make accumulation vector current @@ -496,43 +498,27 @@ void MotionMain::process_global() // Clamp accumulation vector if(config.magnitude < 100) { - //int block_w = (int64_t)config.global_block_w * - // current_global_ref->get_w() / 100; - //int block_h = (int64_t)config.global_block_h * - // current_global_ref->get_h() / 100; - int block_x_orig = (int64_t)(config.block_x * - current_global_ref->get_w() / - 100); + //int block_w = (int64_t)config.global_block_w * w / 100; + //int block_h = (int64_t)config.global_block_h * h / 100; + int block_x_orig = (int64_t)(config.block_x * w / 100); int block_y_orig = (int64_t)(config.block_y * - current_global_ref->get_h() / - 100); + current_global_ref->get_h() / h / 100); - int max_block_x = (int64_t)(current_global_ref->get_w() - block_x_orig) * - OVERSAMPLE * - config.magnitude / - 100; - int max_block_y = (int64_t)(current_global_ref->get_h() - block_y_orig) * - OVERSAMPLE * - config.magnitude / - 100; + int max_block_x = (int64_t)(w - block_x_orig) * + OVERSAMPLE * config.magnitude / 100; + int max_block_y = (int64_t)(h - block_y_orig) * + OVERSAMPLE * config.magnitude / 100; int min_block_x = (int64_t)-block_x_orig * - OVERSAMPLE * - config.magnitude / - 100; + OVERSAMPLE * config.magnitude / 100; int min_block_y = (int64_t)-block_y_orig * - OVERSAMPLE * - config.magnitude / - 100; + OVERSAMPLE * config.magnitude / 100; CLAMP(total_dx, min_block_x, max_block_x); CLAMP(total_dy, min_block_y, max_block_y); } -#ifdef DEBUG -printf("MotionMain::process_global 2 total_dx=%.02f total_dy=%.02f\n", -(float)total_dx / OVERSAMPLE, -(float)total_dy / OVERSAMPLE); -#endif +// printf("MotionMain::process_global %d total_dx=%d total_dy=%d\n", +// __LINE__, total_dx, total_dy); if(config.tracking_object != MotionScan::TRACK_SINGLE && !config.rotate) { @@ -561,7 +547,6 @@ printf("MotionMain::process_global 2 total_dx=%.02f total_dy=%.02f\n", dx = -(int)(total_dx / OVERSAMPLE); dy = -(int)(total_dy / OVERSAMPLE); break; - break; case MotionScan::TRACK: interpolation = CUBIC_LINEAR; dx = (float)total_dx / OVERSAMPLE; @@ -603,9 +588,11 @@ void MotionMain::process_rotation() int block_x; int block_y; +// Always require global // Convert the previous global reference into the previous rotation reference. // Convert global target destination into rotation target source. - if(config.global) +// if(config.global) + if(1) { if(!overlayer) overlayer = new OverlayFrame(PluginClient::get_project_smp() + 1); @@ -670,17 +657,17 @@ void MotionMain::process_rotation() // Get rotation - if(!motion_rotate) - motion_rotate = new RotateScan(this, - get_project_smp() + 1, - get_project_smp() + 1); - - current_angle = motion_rotate->scan_frame(prev_rotate_ref, - current_rotate_ref, - block_x, - block_y); - - +// if(!motion_rotate) +// motion_rotate = new RotateScan(this, +// get_project_smp() + 1, +// get_project_smp() + 1); +// +// current_angle = motion_rotate->scan_frame(prev_rotate_ref, +// current_rotate_ref, +// block_x, +// block_y); + + current_angle = engine->dr_result; // Add current rotation to accumulation if(config.tracking_object != MotionScan::TRACK_SINGLE) @@ -696,13 +683,13 @@ void MotionMain::process_rotation() CLAMP(total_angle, -config.rotate_magnitude, config.rotate_magnitude); } - if(!config.global) - { +// if(!config.global) +// { // Transfer current reference frame to previous reference frame and update // counter. - prev_rotate_ref->copy_from(current_rotate_ref); - previous_frame_number = get_source_position(); - } +// prev_rotate_ref->copy_from(current_rotate_ref); +// previous_frame_number = get_source_position(); +// } } else { @@ -754,7 +741,8 @@ printf("MotionMain::process_rotation total_angle=%f\n", total_angle); case MotionScan::STABILIZE: case MotionScan::STABILIZE_PIXEL: - if(config.global) +// if(config.global) + if(1) { // Use origin of global stabilize operation // rotate_engine->set_pivot((int)(rotate_target_dst->get_w() * @@ -788,6 +776,7 @@ printf("MotionMain::process_rotation total_angle=%f\n", total_angle); } +printf("MotionMain::process_rotation angle=%f\n", angle); rotate_engine->rotate(rotate_target_dst, rotate_target_src, angle); // overlayer->overlay(rotate_target_dst, // prev_rotate_ref, @@ -909,7 +898,7 @@ printf("MotionMain::process_buffer %d start_position=%lld\n", __LINE__, start_po } - if(!config.global && !config.rotate) skip_current = 1; +// if(!config.global && !config.rotate) skip_current = 1; @@ -945,7 +934,8 @@ printf("MotionMain::process_buffer %d start_position=%lld\n", __LINE__, start_po // Get the global pointers. Here we walk through the sequence of events. - if(config.global) +// if(config.global) + if(1) { // Assume global only. Global reads previous frame and compares // with current frame to get the current translation. @@ -1058,13 +1048,14 @@ printf("MotionMain::process_buffer %d start_position=%lld\n", __LINE__, start_po - +//PRINT_TRACE +//printf("skip_current=%d config.global=%d\n", skip_current, config.global); if(!skip_current) { // Get position change from previous frame to current frame - if(config.global) process_global(); + /* if(config.global) */ process_global(); // Get rotation change from previous frame to current frame if(config.rotate) process_rotation(); //frame[target_layer]->copy_from(prev_rotate_ref); @@ -1128,18 +1119,20 @@ void MotionMain::draw_vectors(VFrame *frame) int search_x2, search_y2; - if(config.global) +// always processing global +// if(config.global) + if(1) { // Get vector // Start of vector is center of previous block. // End of vector is total accumulation. if(config.tracking_object == MotionScan::TRACK_SINGLE) { - global_x1 = (int64_t)(config.block_x * - w / + global_x1 = (int64_t)(config.block_x * + w / 100); global_y1 = (int64_t)(config.block_y * - h / + h / 100); global_x2 = global_x1 + total_dx / OVERSAMPLE; global_y2 = global_y1 + total_dy / OVERSAMPLE; @@ -1150,34 +1143,34 @@ void MotionMain::draw_vectors(VFrame *frame) // End of vector is current change. if(config.tracking_object == MotionScan::PREVIOUS_SAME_BLOCK) { - global_x1 = (int64_t)(config.block_x * - w / + global_x1 = (int64_t)(config.block_x * + w / 100); global_y1 = (int64_t)(config.block_y * - h / + h / 100); global_x2 = global_x1 + current_dx / OVERSAMPLE; global_y2 = global_y1 + current_dy / OVERSAMPLE; } else { - global_x1 = (int64_t)(config.block_x * - w / - 100 + - (total_dx - current_dx) / + global_x1 = (int64_t)(config.block_x * + w / + 100 + + (total_dx - current_dx) / OVERSAMPLE); global_y1 = (int64_t)(config.block_y * - h / + h / 100 + (total_dy - current_dy) / OVERSAMPLE); - global_x2 = (int64_t)(config.block_x * - w / - 100 + - total_dx / + global_x2 = (int64_t)(config.block_x * + w / + 100 + + total_dx / OVERSAMPLE); global_y2 = (int64_t)(config.block_y * - h / + h / 100 + total_dy / OVERSAMPLE); @@ -1212,8 +1205,8 @@ void MotionMain::draw_vectors(VFrame *frame) // search_x2, // search_y2); - MotionScan::clamp_scan(w, - h, + MotionScan::clamp_scan(w, + h, &block_x1, &block_y1, &block_x2, @@ -1445,440 +1438,3 @@ void MotionMain::draw_arrow(VFrame *frame, int x1, int y1, int x2, int y2) - - - - - - - - - -RotateScanPackage::RotateScanPackage() -{ -} - - -RotateScanUnit::RotateScanUnit(RotateScan *server, MotionMain *plugin) - : LoadClient(server) -{ - this->server = server; - this->plugin = plugin; - rotater = 0; - temp = 0; -} - -RotateScanUnit::~RotateScanUnit() -{ - delete rotater; - delete temp; -} - -void RotateScanUnit::process_package(LoadPackage *package) -{ - if(server->skip) return; - RotateScanPackage *pkg = (RotateScanPackage*)package; - - if((pkg->difference = server->get_cache(pkg->angle)) < 0) - { -//printf("RotateScanUnit::process_package %d\n", __LINE__); - int color_model = server->previous_frame->get_color_model(); - int pixel_size = BC_CModels::calculate_pixelsize(color_model); - int row_bytes = server->previous_frame->get_bytes_per_line(); - - if(!rotater) - rotater = new AffineEngine(1, 1); - if(!temp) temp = new VFrame(0, - -1, - server->previous_frame->get_w(), - server->previous_frame->get_h(), - color_model, - -1); -//printf("RotateScanUnit::process_package %d\n", __LINE__); - - -// Rotate original block size -// rotater->set_viewport(server->block_x1, -// server->block_y1, -// server->block_x2 - server->block_x1, -// server->block_y2 - server->block_y1); - rotater->set_in_viewport(server->block_x1, - server->block_y1, - server->block_x2 - server->block_x1, - server->block_y2 - server->block_y1); - rotater->set_out_viewport(server->block_x1, - server->block_y1, - server->block_x2 - server->block_x1, - server->block_y2 - server->block_y1); -// rotater->set_pivot(server->block_x, server->block_y); - rotater->set_in_pivot(server->block_x, server->block_y); - rotater->set_out_pivot(server->block_x, server->block_y); -//printf("RotateScanUnit::process_package %d\n", __LINE__); - rotater->rotate(temp, - server->previous_frame, - pkg->angle); - -// Scan reduced block size -//plugin->output_frame->copy_from(server->current_frame); -//plugin->output_frame->copy_from(temp); -// printf("RotateScanUnit::process_package %d %d %d %d %d\n", -// __LINE__, -// server->scan_x, -// server->scan_y, -// server->scan_w, -// server->scan_h); -// Clamp coordinates - int x1 = server->scan_x; - int y1 = server->scan_y; - int x2 = x1 + server->scan_w; - int y2 = y1 + server->scan_h; - x2 = MIN(temp->get_w(), x2); - y2 = MIN(temp->get_h(), y2); - x2 = MIN(server->current_frame->get_w(), x2); - y2 = MIN(server->current_frame->get_h(), y2); - x1 = MAX(0, x1); - y1 = MAX(0, y1); - - if(x2 > x1 && y2 > y1) - { - pkg->difference = MotionScan::abs_diff( - temp->get_rows()[y1] + x1 * pixel_size, - server->current_frame->get_rows()[y1] + x1 * pixel_size, - row_bytes, - x2 - x1, - y2 - y1, - color_model); -//printf("RotateScanUnit::process_package %d\n", __LINE__); - server->put_cache(pkg->angle, pkg->difference); - } - -// printf("RotateScanUnit::process_package 10 x=%d y=%d w=%d h=%d block_x=%d block_y=%d angle=%f scan_w=%d scan_h=%d diff=%lld\n", -// server->block_x1, -// server->block_y1, -// server->block_x2 - server->block_x1, -// server->block_y2 - server->block_y1, -// server->block_x, -// server->block_y, -// pkg->angle, -// server->scan_w, -// server->scan_h, -// pkg->difference); - } -} - - - - - - - - - - - - - - - - - - - - - - -RotateScan::RotateScan(MotionMain *plugin, - int total_clients, - int total_packages) - : LoadServer( -//1, 1 -total_clients, total_packages -) -{ - this->plugin = plugin; - cache_lock = new Mutex("RotateScan::cache_lock"); -} - - -RotateScan::~RotateScan() -{ - delete cache_lock; -} - -void RotateScan::init_packages() -{ - for(int i = 0; i < get_total_packages(); i++) - { - RotateScanPackage *pkg = (RotateScanPackage*)get_package(i); - pkg->angle = i * - (scan_angle2 - scan_angle1) / - (total_steps - 1) + - scan_angle1; - } -} - -LoadClient* RotateScan::new_client() -{ - return new RotateScanUnit(this, plugin); -} - -LoadPackage* RotateScan::new_package() -{ - return new RotateScanPackage; -} - - -float RotateScan::scan_frame(VFrame *previous_frame, - VFrame *current_frame, - int block_x, - int block_y) -{ - skip = 0; - this->block_x = block_x; - this->block_y = block_y; - -//printf("RotateScan::scan_frame %d\n", __LINE__); - switch(plugin->config.tracking_type) - { - case MotionScan::NO_CALCULATE: - result = plugin->config.rotation_center; - skip = 1; - break; - - case MotionScan::LOAD: - { - char string[BCTEXTLEN]; - sprintf(string, "%s%06jd", - ROTATION_FILE, plugin->get_source_position()); - FILE *input = fopen(string, "r"); - if(input) - { - fscanf(input, "%f", &result); - fclose(input); - skip = 1; - } - else - { - perror("RotateScan::scan_frame LOAD"); - } - break; - } - } - - - - - - - - - this->previous_frame = previous_frame; - this->current_frame = current_frame; - int w = current_frame->get_w(); - int h = current_frame->get_h(); - int block_w = w * plugin->config.global_block_w / 100; - int block_h = h * plugin->config.global_block_h / 100; - - if(this->block_x - block_w / 2 < 0) block_w = this->block_x * 2; - if(this->block_y - block_h / 2 < 0) block_h = this->block_y * 2; - if(this->block_x + block_w / 2 > w) block_w = (w - this->block_x) * 2; - if(this->block_y + block_h / 2 > h) block_h = (h - this->block_y) * 2; - - block_x1 = this->block_x - block_w / 2; - block_x2 = this->block_x + block_w / 2; - block_y1 = this->block_y - block_h / 2; - block_y2 = this->block_y + block_h / 2; - -// Calculate the maximum area available to scan after rotation. -// Must be calculated from the starting range because of cache. -// Get coords of rectangle after rotation. - double center_x = this->block_x; - double center_y = this->block_y; - double max_angle = plugin->config.rotation_range; - double base_angle1 = atan((float)block_h / block_w); - double base_angle2 = atan((float)block_w / block_h); - double target_angle1 = base_angle1 + max_angle * 2 * M_PI / 360; - double target_angle2 = base_angle2 + max_angle * 2 * M_PI / 360; - double radius = sqrt(block_w * block_w + block_h * block_h) / 2; - double x1 = center_x - cos(target_angle1) * radius; - double y1 = center_y - sin(target_angle1) * radius; - double x2 = center_x + sin(target_angle2) * radius; - double y2 = center_y - cos(target_angle2) * radius; - double x3 = center_x - sin(target_angle2) * radius; - double y3 = center_y + cos(target_angle2) * radius; - -// Track top edge to find greatest area. - double max_area1 = 0; - //double max_x1 = 0; - double max_y1 = 0; - for(double x = x1; x < x2; x++) - { - double y = y1 + (y2 - y1) * (x - x1) / (x2 - x1); - if(x >= center_x && x < block_x2 && y >= block_y1 && y < center_y) - { - double area = fabs(x - center_x) * fabs(y - center_y); - if(area > max_area1) - { - max_area1 = area; - //max_x1 = x; - max_y1 = y; - } - } - } - -// Track left edge to find greatest area. - double max_area2 = 0; - double max_x2 = 0; - //double max_y2 = 0; - for(double y = y1; y < y3; y++) - { - double x = x1 + (x3 - x1) * (y - y1) / (y3 - y1); - if(x >= block_x1 && x < center_x && y >= block_y1 && y < center_y) - { - double area = fabs(x - center_x) * fabs(y - center_y); - if(area > max_area2) - { - max_area2 = area; - max_x2 = x; - //max_y2 = y; - } - } - } - - double max_x, max_y; - max_x = max_x2; - max_y = max_y1; - -// Get reduced scan coords - scan_w = (int)(fabs(max_x - center_x) * 2); - scan_h = (int)(fabs(max_y - center_y) * 2); - scan_x = (int)(center_x - scan_w / 2); - scan_y = (int)(center_y - scan_h / 2); -// printf("RotateScan::scan_frame center=%d,%d scan=%d,%d %dx%d\n", -// this->block_x, this->block_y, scan_x, scan_y, scan_w, scan_h); -// printf(" angle_range=%f block= %d,%d,%d,%d\n", max_angle, block_x1, block_y1, block_x2, block_y2); - -// Determine min angle from size of block - double angle1 = atan((double)block_h / block_w); - double angle2 = atan((double)(block_h - 1) / (block_w + 1)); - double min_angle = fabs(angle2 - angle1) / OVERSAMPLE; - min_angle = MAX(min_angle, MIN_ANGLE); - -//printf("RotateScan::scan_frame %d min_angle=%f\n", __LINE__, min_angle * 360 / 2 / M_PI); - - cache.remove_all_objects(); - - - if(!skip) - { - if(previous_frame->data_matches(current_frame)) - { -//printf("RotateScan::scan_frame: frames match. Skipping.\n"); - result = plugin->config.rotation_center; - skip = 1; - } - } - - if(!skip) - { -// Initial search range - float angle_range = max_angle; - result = plugin->config.rotation_center; - total_steps = plugin->config.rotate_positions; - - - while(angle_range >= min_angle * total_steps) - { - scan_angle1 = result - angle_range; - scan_angle2 = result + angle_range; - - - set_package_count(total_steps); -//set_package_count(1); - process_packages(); - - int64_t min_difference = -1; - for(int i = 0; i < get_total_packages(); i++) - { - RotateScanPackage *pkg = (RotateScanPackage*)get_package(i); - if(pkg->difference < min_difference || min_difference == -1) - { - min_difference = pkg->difference; - result = pkg->angle; - } -//break; - } - - angle_range /= 2; - -//break; - } - } - -//printf("RotateScan::scan_frame %d\n", __LINE__); - - if(!skip && plugin->config.tracking_type == MotionScan::SAVE) - { - char string[BCTEXTLEN]; - sprintf(string, "%s%06jd", - ROTATION_FILE, plugin->get_source_position()); - FILE *output = fopen(string, "w"); - if(output) - { - fprintf(output, "%f\n", result); - fclose(output); - } - else - { - perror("RotateScan::scan_frame SAVE"); - } - } - -//printf("RotateScan::scan_frame %d angle=%f\n", __LINE__, result); - - - - return result; -} - -int64_t RotateScan::get_cache(float angle) -{ - int64_t result = -1; - cache_lock->lock("RotateScan::get_cache"); - for(int i = 0; i < cache.total; i++) - { - RotateScanCache *ptr = cache.values[i]; - if(fabs(ptr->angle - angle) <= MIN_ANGLE) - { - result = ptr->difference; - break; - } - } - cache_lock->unlock(); - return result; -} - -void RotateScan::put_cache(float angle, int64_t difference) -{ - RotateScanCache *ptr = new RotateScanCache(angle, difference); - cache_lock->lock("RotateScan::put_cache"); - cache.append(ptr); - cache_lock->unlock(); -} - - - - - - - - - -RotateScanCache::RotateScanCache(float angle, int64_t difference) -{ - this->angle = angle; - this->difference = difference; -} - - -