X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fmotion%2Fmotionscan.C;h=0685b6562a9f51ebc15b7efb1d9de503b04f6ef3;hb=HEAD;hp=b1a533ef850477a9c7412d39e92c45d5d60c2a09;hpb=1e154071bd323f756625f8172ef67133a561450a;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/motion/motionscan.C b/cinelerra-5.1/plugins/motion/motionscan.C index b1a533ef..0685b656 100644 --- a/cinelerra-5.1/plugins/motion/motionscan.C +++ b/cinelerra-5.1/plugins/motion/motionscan.C @@ -2,21 +2,21 @@ /* * CINELERRA * Copyright (C) 2012 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #include "clip.h" @@ -30,21 +30,12 @@ // The module which does the actual scanning - - - - MotionScanPackage::MotionScanPackage() : LoadPackage() { valid = 1; } - - - - - MotionScanUnit::MotionScanUnit(MotionScan *server) : LoadClient(server) { @@ -57,8 +48,6 @@ MotionScanUnit::~MotionScanUnit() delete cache_lock; } - - void MotionScanUnit::process_package(LoadPackage *package) { MotionScanPackage *pkg = (MotionScanPackage*)package; @@ -68,40 +57,25 @@ void MotionScanUnit::process_package(LoadPackage *package) int pixel_size = BC_CModels::calculate_pixelsize(color_model); int row_bytes = server->current_frame->get_bytes_per_line(); - - - - - - - - - - - // Single pixel - if(!server->subpixel) - { + if( !server->subpixel ) { // Try cache pkg->difference1 = server->get_cache(pkg->search_x, pkg->search_y); - if(pkg->difference1 < 0) - { -//printf("MotionScanUnit::process_package 1 search_x=%d search_y=%d scan_x1=%d scan_y1=%d scan_x2=%d scan_y2=%d x_steps=%d y_steps=%d\n", -//pkg->search_x, pkg->search_y, pkg->scan_x1, pkg->scan_y1, pkg->scan_x2, pkg->scan_y2, server->x_steps, server->y_steps); + if( pkg->difference1 < 0 ) { +//printf("MotionScanUnit::process_package 1 search_x=%d search_y=%d" +// " scan_x1=%d scan_y1=%d scan_x2=%d scan_y2=%d x_steps=%d y_steps=%d\n", +// pkg->search_x, pkg->search_y, pkg->scan_x1, pkg->scan_y1, pkg->scan_x2, pkg->scan_y2, +// server->x_steps, server->y_steps); // Pointers to first pixel in each block - unsigned char *prev_ptr = server->previous_frame->get_rows()[ - pkg->search_y] + + unsigned char *prev_ptr = + server->previous_frame->get_rows()[pkg->search_y] + pkg->search_x * pixel_size; - unsigned char *current_ptr = server->current_frame->get_rows()[ - pkg->block_y1] + + unsigned char *current_ptr = + server->current_frame->get_rows()[pkg->block_y1] + pkg->block_x1 * pixel_size; - // Scan block - pkg->difference1 = MotionScan::abs_diff(prev_ptr, - current_ptr, - row_bytes, - pkg->block_x2 - pkg->block_x1, - pkg->block_y2 - pkg->block_y1, + pkg->difference1 = MotionScan::abs_diff(prev_ptr, current_ptr, row_bytes, + pkg->block_x2 - pkg->block_x1, pkg->block_y2 - pkg->block_y1, color_model); // printf("MotionScanUnit::process_package %d search_x=%d search_y=%d diff=%lld\n", @@ -109,81 +83,36 @@ void MotionScanUnit::process_package(LoadPackage *package) server->put_cache(pkg->search_x, pkg->search_y, pkg->difference1); } } - - - - - - - - else - - - - - - - - // Sub pixel - { - unsigned char *prev_ptr = server->previous_frame->get_rows()[ - pkg->search_y] + + else { + unsigned char *prev_ptr = + server->previous_frame->get_rows()[pkg->search_y] + pkg->search_x * pixel_size; - unsigned char *current_ptr = server->current_frame->get_rows()[ - pkg->block_y1] + + unsigned char *current_ptr = + server->current_frame->get_rows()[pkg->block_y1] + pkg->block_x1 * pixel_size; // With subpixel, there are two ways to compare each position, one by shifting // the previous frame and two by shifting the current frame. - pkg->difference1 = MotionScan::abs_diff_sub(prev_ptr, - current_ptr, - row_bytes, - pkg->block_x2 - pkg->block_x1, - pkg->block_y2 - pkg->block_y1, - color_model, - pkg->sub_x, - pkg->sub_y); - pkg->difference2 = MotionScan::abs_diff_sub(current_ptr, - prev_ptr, - row_bytes, - pkg->block_x2 - pkg->block_x1, - pkg->block_y2 - pkg->block_y1, - color_model, - pkg->sub_x, - pkg->sub_y); -// printf("MotionScanUnit::process_package sub_x=%d sub_y=%d search_x=%d search_y=%d diff1=%lld diff2=%lld\n", -// sub_x, -// sub_y, -// search_x, -// search_y, -// pkg->difference1, -// pkg->difference2); + pkg->difference1 = MotionScan::abs_diff_sub(prev_ptr, current_ptr, row_bytes, + pkg->block_x2 - pkg->block_x1, pkg->block_y2 - pkg->block_y1, + color_model, pkg->sub_x, pkg->sub_y); + pkg->difference2 = + MotionScan::abs_diff_sub(current_ptr, prev_ptr, row_bytes, + pkg->block_x2 - pkg->block_x1, pkg->block_y2 - pkg->block_y1, + color_model, pkg->sub_x, pkg->sub_y); +//printf("MotionScanUnit::process_package sub_x=%d sub_y=%d search_x=%d search_y=%d diff1=%lld diff2=%lld\n", +// sub_x, sub_y, search_x, search_y, pkg->difference1, pkg->difference2); } - - - - } - - - - - - - - - int64_t MotionScanUnit::get_cache(int x, int y) { int64_t result = -1; cache_lock->lock("MotionScanUnit::get_cache"); - for(int i = 0; i < cache.total; i++) - { + for( int i = 0; i < cache.total; i++ ) { MotionScanCache *ptr = cache.values[i]; - if(ptr->x == x && ptr->y == y) - { + if( ptr->x == x && ptr->y == y ) { result = ptr->difference; break; } @@ -200,22 +129,9 @@ void MotionScanUnit::put_cache(int x, int y, int64_t difference) cache_lock->unlock(); } - - - - - - - - - - -MotionScan::MotionScan(int total_clients, - int total_packages) - : LoadServer( -//1, 1 -total_clients, total_packages -) +MotionScan::MotionScan(int total_clients, int total_packages) + : LoadServer( //1, 1 + total_clients, total_packages) { test_match = 1; cache_lock = new Mutex("MotionScan::cache_lock"); @@ -232,78 +148,46 @@ MotionScan::~MotionScan() // delete downsample; } - void MotionScan::init_packages() { // Set package coords //printf("MotionScan::init_packages %d %d\n", __LINE__, get_total_packages()); - for(int i = 0; i < get_total_packages(); i++) - { + for( int i = 0; i < get_total_packages(); i++ ) { MotionScanPackage *pkg = (MotionScanPackage*)get_package(i); - pkg->block_x1 = block_x1; - pkg->block_x2 = block_x2; - pkg->block_y1 = block_y1; - pkg->block_y2 = block_y2; - pkg->scan_x1 = scan_x1; - pkg->scan_x2 = scan_x2; - pkg->scan_y1 = scan_y1; - pkg->scan_y2 = scan_y2; - pkg->step = i; - pkg->difference1 = 0; - pkg->difference2 = 0; - pkg->dx = 0; - pkg->dy = 0; - pkg->valid = 1; - - if(!subpixel) - { - pkg->search_x = pkg->scan_x1 + (pkg->step % x_steps) * - (scan_x2 - scan_x1) / x_steps; - pkg->search_y = pkg->scan_y1 + (pkg->step / x_steps) * - (scan_y2 - scan_y1) / y_steps; - pkg->sub_x = 0; - pkg->sub_y = 0; + pkg->block_x1 = block_x1; pkg->block_x2 = block_x2; + pkg->block_y1 = block_y1; pkg->block_y2 = block_y2; + pkg->scan_x1 = scan_x1; pkg->scan_x2 = scan_x2; + pkg->scan_y1 = scan_y1; pkg->scan_y2 = scan_y2; + pkg->difference1 = 0; pkg->difference2 = 0; + pkg->step = i; pkg->valid = 1; + pkg->dx = pkg->dy = 0; + + if( !subpixel ) { + pkg->search_x = pkg->scan_x1 + + (pkg->step % x_steps) * (scan_x2 - scan_x1) / x_steps; + pkg->search_y = pkg->scan_y1 + + (pkg->step / x_steps) * (scan_y2 - scan_y1) / y_steps; + pkg->sub_x = pkg->sub_y = 0; } - else - { + else { pkg->sub_x = pkg->step % (OVERSAMPLE * 2); pkg->sub_y = pkg->step / (OVERSAMPLE * 2); - if(horizontal_only) - { - pkg->sub_y = 0; - } - - if(vertical_only) - { - pkg->sub_x = 0; - } + if( horizontal_only ) pkg->sub_y = 0; + if( vertical_only ) pkg->sub_x = 0; pkg->search_x = pkg->scan_x1 + pkg->sub_x / OVERSAMPLE + 1; pkg->search_y = pkg->scan_y1 + pkg->sub_y / OVERSAMPLE + 1; pkg->sub_x %= OVERSAMPLE; pkg->sub_y %= OVERSAMPLE; - - -// printf("MotionScan::init_packages %d i=%d search_x=%d search_y=%d sub_x=%d sub_y=%d\n", -// __LINE__, -// i, -// pkg->search_x, -// pkg->search_y, -// pkg->sub_x, -// pkg->sub_y); +// printf("MotionScan::init_packages %d i=%d search_x=%d search_y=%d sub_x=%d sub_y=%d\n", +// __LINE__, i, pkg->search_x, pkg->search_y, pkg->sub_x, pkg->sub_y); } // printf("MotionScan::init_packages %d %d,%d %d,%d %d,%d\n", -// __LINE__, -// scan_x1, -// scan_x2, -// scan_y1, -// scan_y2, -// pkg->search_x, -// pkg->search_y); +// __LINE__, scan_x1, scan_x2, scan_y1, scan_y2, pkg->search_x, pkg->search_y); } } @@ -317,31 +201,20 @@ LoadPackage* MotionScan::new_package() return new MotionScanPackage; } - void MotionScan::set_test_match(int value) { this->test_match = value; } -void MotionScan::scan_frame(VFrame *previous_frame, - VFrame *current_frame, - int global_range_w, - int global_range_h, - int global_block_w, - int global_block_h, - double block_x, - double block_y, - int frame_type, - int tracking_type, - int action_type, - int horizontal_only, - int vertical_only, - int source_position, - int total_steps, - int total_dx, - int total_dy, - int global_origin_x, - int global_origin_y) +void MotionScan::scan_frame(VFrame *previous_frame, VFrame *current_frame, + int global_range_w, int global_range_h, + int global_block_w, int global_block_h, + double block_x, double block_y, int frame_type, + int tracking_type, int action_type, + int horizontal_only, int vertical_only, + int source_position, int total_steps, int total_dx, + int total_dy, int global_origin_x, int global_origin_y, + int load_ok, int load_dx, int load_dy) { this->previous_frame_arg = previous_frame; this->current_frame_arg = current_frame; @@ -373,8 +246,7 @@ void MotionScan::scan_frame(VFrame *previous_frame, // Offset to location of previous block. This offset needn't be very accurate // since it's the offset of the previous image and current image we want. - if(frame_type == MotionScan::TRACK_PREVIOUS) - { + if( frame_type == MotionScan::TRACK_PREVIOUS ) { block_x1 += total_dx / OVERSAMPLE; block_y1 += total_dy / OVERSAMPLE; block_x2 += total_dx / OVERSAMPLE; @@ -383,58 +255,37 @@ void MotionScan::scan_frame(VFrame *previous_frame, skip = 0; - switch(tracking_type) - { + switch( tracking_type ) { // Don't calculate - case MotionScan::NO_CALCULATE: - dx_result = 0; - dy_result = 0; + case MotionScan::NO_CALCULATE: + dx_result = dy_result = 0; + skip = 1; + break; + + case MotionScan::LOAD: + case MotionScan::SAVE: + if( load_ok ) { + dx_result = load_dx; + dy_result = load_dy; skip = 1; - break; - - case MotionScan::LOAD: - { -// Load result from disk - char string[BCTEXTLEN]; - sprintf(string, "%s%06d", - MOTION_FILE, - source_position); -//printf("MotionScan::scan_frame %d %s\n", __LINE__, string); - FILE *input = fopen(string, "r"); - if(input) - { - (void)fscanf(input, "%d %d", - &dx_result, &dy_result); -// HACK -//dx_result *= 2; -//dy_result *= 2; -//printf("MotionScan::scan_frame %d %d %d\n", __LINE__, dx_result, dy_result); - fclose(input); - skip = 1; - } - break; } + break; // Scan from scratch - default: - skip = 0; - break; + default: + skip = 0; + break; } - if(!skip && test_match) - { - if(previous_frame->data_matches(current_frame)) - { -printf("MotionScan::scan_frame: data matches. skipping.\n"); - dx_result = 0; - dy_result = 0; + if( !skip && test_match ) { + if( previous_frame->data_matches(current_frame) ) { + printf("MotionScan::scan_frame: data matches. skipping.\n"); + dx_result = dy_result = 0; skip = 1; } } - // Perform scan - if(!skip) - { + if( !skip ) { //printf("MotionScan::scan_frame %d\n", __LINE__); // Location of block in current frame int origin_offset_x = this->global_origin_x * w / 100; @@ -442,19 +293,12 @@ printf("MotionScan::scan_frame: data matches. skipping.\n"); int x_result = block_x1 + origin_offset_x; int y_result = block_y1 + origin_offset_y; -// printf("MotionScan::scan_frame 1 %d %d %d %d %d %d %d %d\n", -// block_x1 + block_w / 2, -// block_y1 + block_h / 2, -// block_w, -// block_h, -// block_x1, -// block_y1, -// block_x2, -// block_y2); - - while(1) - { -// Cache needs to be cleared if downsampling is used because the sums of +//printf("MotionScan::scan_frame 1 %d %d %d %d %d %d %d %d\n", +// block_x1 + block_w / 2, block_y1 + block_h / 2, +// block_w, block_h, block_x1, block_y1, block_x2, block_y2); + + while(1) { +// Cache needs to be cleared if downsampling is used because the sums of // different downsamplings can't be compared. // Subpixel never uses the cache. // cache.remove_all_objects(); @@ -463,65 +307,33 @@ printf("MotionScan::scan_frame: data matches. skipping.\n"); scan_x2 = x_result + scan_w / 2; scan_y2 = y_result + scan_h / 2; - - // Zero out requested values - if(horizontal_only) - { + if( horizontal_only ) { scan_y1 = block_y1; scan_y2 = block_y1 + 1; } - if(vertical_only) - { + if( vertical_only ) { scan_x1 = block_x1; scan_x2 = block_x1 + 1; } - -// printf("MotionScan::scan_frame 1 %d %d %d %d %d %d %d %d\n", -// block_x1, -// block_y1, -// block_x2, -// block_y2, -// scan_x1, -// scan_y1, -// scan_x2, -// scan_y2); +//printf("MotionScan::scan_frame 1 %d %d %d %d %d %d %d %d\n", +// block_x1, block_y1, block_x2, block_y2, scan_x1, scan_y1, scan_x2, scan_y2); // Clamp the block coords before the scan so we get useful scan coords. - clamp_scan(w, - h, - &block_x1, - &block_y1, - &block_x2, - &block_y2, - &scan_x1, - &scan_y1, - &scan_x2, - &scan_y2, - 0); -// printf("MotionScan::scan_frame 1 %d block_x1=%d block_y1=%d block_x2=%d block_y2=%d\n scan_x1=%d scan_y1=%d scan_x2=%d scan_y2=%d\n x_result=%d y_result=%d\n", -// __LINE__, -// block_x1, -// block_y1, -// block_x2, -// block_y2, -// scan_x1, -// scan_y1, -// scan_x2, -// scan_y2, -// x_result, -// y_result); - + clamp_scan(w, h, &block_x1, &block_y1, &block_x2, + &block_y2, &scan_x1, &scan_y1, &scan_x2, + &scan_y2, 0); +// printf("MotionScan::scan_frame 1 %d block_x1=%d block_y1=%d block_x2=%d block_y2=%d\n" +// " scan_x1=%d scan_y1=%d scan_x2=%d scan_y2=%d\n" +// " x_result=%d y_result=%d\n", __LINE__, block_x1, block_y1, block_x2, block_y2, +// scan_x1, scan_y1, scan_x2, scan_y2, x_result, y_result); // Give up if invalid coords. - if(scan_y2 <= scan_y1 || - scan_x2 <= scan_x1 || - block_x2 <= block_x1 || - block_y2 <= block_y1) + if (scan_y2 <= scan_y1 || scan_x2 <= scan_x1 || + block_x2 <= block_x1 || block_y2 <= block_y1 ) break; // For subpixel, the top row and left column are skipped - if(subpixel) - { + if( subpixel ) { //printf("MotionScan::scan_frame %d %d %d\n", __LINE__, x_result, y_result); // Scan every subpixel in a 2 pixel * 2 pixel square @@ -537,29 +349,25 @@ printf("MotionScan::scan_frame: data matches. skipping.\n"); // Get least difference int64_t min_difference = -1; - for(int i = 0; i < get_total_packages(); i++) - { - MotionScanPackage *pkg = (MotionScanPackage*)get_package(i); -//printf("MotionScan::scan_frame %d search_x=%d search_y=%d sub_x=%d sub_y=%d diff1=%lld diff2=%lld\n", + for( int i = 0; i < get_total_packages(); i++ ) { + MotionScanPackage *pkg = (MotionScanPackage *)get_package(i); +//printf("MotionScan::scan_frame %d search_x=%d search_y=%d sub_x=%d sub_y=%d diff1=%lld diff2=%lld\n", //__LINE__, pkg->search_x, pkg->search_y, pkg->sub_x, pkg->sub_y, pkg->difference1, pkg->difference2); - if(pkg->difference1 < min_difference || min_difference == -1) - { + if( pkg->difference1 < min_difference || + min_difference == -1 ) { min_difference = pkg->difference1; // The sub coords are 1 pixel up & left of the block coords x_result = pkg->search_x * OVERSAMPLE + pkg->sub_x; y_result = pkg->search_y * OVERSAMPLE + pkg->sub_y; - - // Fill in results dx_result = block_x1 * OVERSAMPLE - x_result; dy_result = block_y1 * OVERSAMPLE - y_result; -//printf("MotionScan::scan_frame %d dx_result=%d dy_result=%d diff=%lld\n", +//printf("MotionScan::scan_frame %d dx_result=%d dy_result=%d diff=%lld\n", //__LINE__, dx_result, dy_result, min_difference); } - if(pkg->difference2 < min_difference) - { + if( pkg->difference2 < min_difference ) { min_difference = pkg->difference2; x_result = pkg->search_x * OVERSAMPLE - pkg->sub_x; @@ -567,34 +375,33 @@ printf("MotionScan::scan_frame: data matches. skipping.\n"); dx_result = block_x1 * OVERSAMPLE - x_result; dy_result = block_y1 * OVERSAMPLE - y_result; -//printf("MotionScan::scan_frame %d dx_result=%d dy_result=%d diff=%lld\n", +//printf("MotionScan::scan_frame %d dx_result=%d dy_result=%d diff=%lld\n", //__LINE__, dx_result, dy_result, min_difference); } } break; } - else // Single pixel - { - total_pixels = (scan_x2 - scan_x1) * (scan_y2 - scan_y1); - this->total_steps = MIN(total_steps, total_pixels); + else { + total_pixels = + (scan_x2 - scan_x1) * (scan_y2 - scan_y1); + this->total_steps = + MIN(total_steps, total_pixels); - if(this->total_steps == total_pixels) - { + if( this->total_steps == total_pixels ) { x_steps = scan_x2 - scan_x1; y_steps = scan_y2 - scan_y1; } - else - { + else { x_steps = (int)sqrt(this->total_steps); y_steps = (int)sqrt(this->total_steps); } // Use downsampled images -// if(scan_x2 - scan_x1 > x_steps * 4 || -// scan_y2 - scan_y1 > y_steps * 4) -// { +// if( scan_x2 - scan_x1 > x_steps * 4 || +// scan_y2 - scan_y1 > y_steps * 4 ) +// { // printf("MotionScan::scan_frame %d total_pixels=%d total_steps=%d x_steps=%d y_steps=%d x y steps=%d\n", // __LINE__, // total_pixels, @@ -602,108 +409,85 @@ printf("MotionScan::scan_frame: data matches. skipping.\n"); // x_steps, // y_steps, // x_steps * y_steps); -// -// if(!downsampled_previous || -// !downsampled_previous->equivalent(previous_frame_arg)) -// { +// +// if( !downsampled_previous || +// !downsampled_previous->equivalent(previous_frame_arg) ) +// { // delete downsampled_previous; // downsampled_previous = new VFrame(*previous_frame_arg); // } -// -// if(!downsampled_current || -// !downsampled_current->equivalent(current_frame_arg)) -// { +// +// if( !downsampled_current || +// !downsampled_current->equivalent(current_frame_arg) ) +// { // delete downsampled_current; // downsampled_current = new VFrame(*current_frame_arg); // } -// -// -// if(!downsample) -// downsample = new DownSampleServer(get_total_clients(), +// +// +// if( !downsample ) +// downsample = new DownSampleServer(get_total_clients(), // get_total_clients()); -// downsample->process_frame(downsampled_previous, -// previous_frame_arg, -// 1, -// 1, -// 1, -// 1, +// downsample->process_frame(downsampled_previous, +// previous_frame_arg, 1, 1, 1, 1, // (scan_y2 - scan_y1) / y_steps, // (scan_x2 - scan_x1) / x_steps, -// 0, -// 0); -// downsample->process_frame(downsampled_current, -// current_frame_arg, -// 1, -// 1, -// 1, -// 1, +// 0, 0); +// downsample->process_frame(downsampled_current, +// current_frame_arg, 1, 1, 1, 1, // (scan_y2 - scan_y1) / y_steps, // (scan_x2 - scan_x1) / x_steps, -// 0, -// 0); +// 0, 0); // this->previous_frame = downsampled_previous; // this->current_frame = downsampled_current; // } - - - - -// printf("MotionScan::scan_frame %d this->total_steps=%d\n", -// __LINE__, -// this->total_steps); - +// printf("MotionScan::scan_frame %d this->total_steps=%d\n", +// __LINE__, this->total_steps); set_package_count(this->total_steps); process_packages(); // Get least difference int64_t min_difference = -1; - for(int i = 0; i < get_total_packages(); i++) - { - MotionScanPackage *pkg = (MotionScanPackage*)get_package(i); -//printf("MotionScan::scan_frame %d search_x=%d search_y=%d sub_x=%d sub_y=%d diff1=%lld diff2=%lld\n", -//__LINE__, pkg->search_x, pkg->search_y, pkg->sub_x, pkg->sub_y, pkg->difference1, pkg->difference2); - if(pkg->difference1 < min_difference || min_difference == -1) - { + for( int i = 0; i < get_total_packages(); i++ ) { + MotionScanPackage *pkg = (MotionScanPackage *) get_package(i); +//printf("MotionScan::scan_frame %d search_x=%d search_y=%d sub_x=%d sub_y=%d diff1=%lld diff2=%lld\n", +// __LINE__, pkg->search_x, pkg->search_y, pkg->sub_x, pkg->sub_y, pkg->difference1, pkg->difference2); + if (pkg->difference1 < min_difference + || min_difference == -1) { min_difference = pkg->difference1; x_result = pkg->search_x; y_result = pkg->search_y; x_result *= OVERSAMPLE; y_result *= OVERSAMPLE; -//printf("MotionScan::scan_frame %d x_result=%d y_result=%d diff=%lld\n", +//printf("MotionScan::scan_frame %d x_result=%d y_result=%d diff=%lld\n", //__LINE__, block_x1 * OVERSAMPLE - x_result, block_y1 * OVERSAMPLE - y_result, pkg->difference1); } } - // If a new search is required, rescale results back to pixels. - if(this->total_steps >= total_pixels) - { + if( this->total_steps >= total_pixels ) { // Single pixel accuracy reached. Now do exhaustive subpixel search. - if(action_type == MotionScan::STABILIZE || + if( action_type == MotionScan::STABILIZE || action_type == MotionScan::TRACK || - action_type == MotionScan::NOTHING) - { + action_type == MotionScan::NOTHING ) { //printf("MotionScan::scan_frame %d %d %d\n", __LINE__, x_result, y_result); x_result /= OVERSAMPLE; y_result /= OVERSAMPLE; - scan_w = 2; - scan_h = 2; + scan_w = scan_h = 2; subpixel = 1; } - else - { // Fill in results and quit + else { dx_result = block_x1 * OVERSAMPLE - x_result; dy_result = block_y1 * OVERSAMPLE - y_result; //printf("MotionScan::scan_frame %d %d %d\n", __LINE__, dx_result, dy_result); break; } } - else // Reduce scan area and try again - { + else { scan_w = (scan_x2 - scan_x1) / 2; scan_h = (scan_y2 - scan_y1) / 2; x_result /= OVERSAMPLE; @@ -711,72 +495,25 @@ printf("MotionScan::scan_frame: data matches. skipping.\n"); } } } - - dx_result *= -1; - dy_result *= -1; + dx_result = -dx_result; + dy_result = -dy_result; } //printf("MotionScan::scan_frame %d\n", __LINE__); + if( vertical_only ) dx_result = 0; + if( horizontal_only ) dy_result = 0; - if(vertical_only) dx_result = 0; - if(horizontal_only) dy_result = 0; - - - -// Write results - if(tracking_type == MotionScan::SAVE) - { - char string[BCTEXTLEN]; - sprintf(string, - "%s%06d", - MOTION_FILE, - source_position); - FILE *output = fopen(string, "w"); - if(output) - { - fprintf(output, - "%d %d\n", - dx_result, - dy_result); - fclose(output); - } - else - { - printf("MotionScan::scan_frame %d: save coordinate failed", __LINE__); - } - } - -// printf("MotionScan::scan_frame %d dx=%.2f dy=%.2f\n", -// __LINE__, -// (float)this->dx_result / OVERSAMPLE, -// (float)this->dy_result / OVERSAMPLE); +//printf("MotionScan::scan_frame %d dx=%.2f dy=%.2f\n", +// __LINE__, (float)this->dx_result / OVERSAMPLE, (float)this->dy_result / OVERSAMPLE); } - - - - - - - - - - - - - - - - int64_t MotionScan::get_cache(int x, int y) { int64_t result = -1; cache_lock->lock("MotionScan::get_cache"); - for(int i = 0; i < cache.total; i++) - { + for( int i = 0; i < cache.total; i++ ) { MotionScanCache *ptr = cache.values[i]; - if(ptr->x == x && ptr->y == y) - { + if( ptr->x == x && ptr->y == y ) { result = ptr->difference; break; } @@ -793,28 +530,21 @@ void MotionScan::put_cache(int x, int y, int64_t difference) cache_lock->unlock(); } - - -#define ABS_DIFF(type, temp_type, multiplier, components) \ -{ \ +#define ABS_DIFF(model, type, temp_type, multiplier, components) case model: { \ temp_type result_temp = 0; \ - for(int i = 0; i < h; i++) \ - { \ + for( int i = 0; i < h; i++ ) { \ type *prev_row = (type*)prev_ptr; \ type *current_row = (type*)current_ptr; \ - for(int j = 0; j < w; j++) \ - { \ - for(int k = 0; k < 3; k++) \ - { \ + for( int j = 0; j < w; j++ ) { \ + for( int k = 0; k < 3; k++ ) { \ temp_type difference; \ difference = *prev_row++ - *current_row++; \ - if(difference < 0) \ + if( difference < 0 ) \ result_temp -= difference; \ else \ result_temp += difference; \ } \ - if(components == 4) \ - { \ + if( components == 4 ) { \ prev_row++; \ current_row++; \ } \ @@ -823,67 +553,41 @@ void MotionScan::put_cache(int x, int y, int64_t difference) current_ptr += row_bytes; \ } \ result = (int64_t)(result_temp * multiplier); \ -} +} break int64_t MotionScan::abs_diff(unsigned char *prev_ptr, - unsigned char *current_ptr, - int row_bytes, - int w, - int h, - int color_model) + unsigned char *current_ptr, int row_bytes, int w, + int h, int color_model) { int64_t result = 0; - switch(color_model) - { - case BC_RGB888: - ABS_DIFF(unsigned char, int64_t, 1, 3) - break; - case BC_RGBA8888: - ABS_DIFF(unsigned char, int64_t, 1, 4) - break; - case BC_RGB_FLOAT: - ABS_DIFF(float, double, 0x10000, 3) - break; - case BC_RGBA_FLOAT: - ABS_DIFF(float, double, 0x10000, 4) - break; - case BC_YUV888: - ABS_DIFF(unsigned char, int64_t, 1, 3) - break; - case BC_YUVA8888: - ABS_DIFF(unsigned char, int64_t, 1, 4) - break; - case BC_YUV161616: - ABS_DIFF(uint16_t, int64_t, 1, 3) - break; - case BC_YUVA16161616: - ABS_DIFF(uint16_t, int64_t, 1, 4) - break; + switch( color_model ) { + ABS_DIFF(BC_RGB888, unsigned char, int64_t, 1, 3); + ABS_DIFF(BC_RGBA8888, unsigned char, int64_t, 1, 4); + ABS_DIFF(BC_RGB_FLOAT, float, double, 0x10000, 3); + ABS_DIFF(BC_RGBA_FLOAT, float, double, 0x10000, 4); + ABS_DIFF(BC_YUV888, unsigned char, int64_t, 1, 3); + ABS_DIFF(BC_YUVA8888, unsigned char, int64_t, 1, 4); + ABS_DIFF(BC_YUV161616, uint16_t, int64_t, 1, 3); + ABS_DIFF(BC_YUVA16161616, uint16_t, int64_t, 1, 4); } return result; } - - -#define ABS_DIFF_SUB(type, temp_type, multiplier, components) \ -{ \ +#define ABS_DIFF_SUB(model, type, temp_type, multiplier, components) case model: { \ temp_type result_temp = 0; \ temp_type y2_fraction = sub_y * 0x100 / OVERSAMPLE; \ temp_type y1_fraction = 0x100 - y2_fraction; \ temp_type x2_fraction = sub_x * 0x100 / OVERSAMPLE; \ temp_type x1_fraction = 0x100 - x2_fraction; \ - for(int i = 0; i < h_sub; i++) \ - { \ + for( int i = 0; i < h_sub; i++ ) { \ type *prev_row1 = (type*)prev_ptr; \ type *prev_row2 = (type*)prev_ptr + components; \ type *prev_row3 = (type*)(prev_ptr + row_bytes); \ type *prev_row4 = (type*)(prev_ptr + row_bytes) + components; \ type *current_row = (type*)current_ptr; \ - for(int j = 0; j < w_sub; j++) \ - { \ + for( int j = 0; j < w_sub; j++ ) { \ /* Scan each component */ \ - for(int k = 0; k < 3; k++) \ - { \ + for( int k = 0; k < 3; k++ ) { \ temp_type difference; \ temp_type prev_value = \ (*prev_row1++ * x1_fraction * y1_fraction + \ @@ -893,15 +597,14 @@ int64_t MotionScan::abs_diff(unsigned char *prev_ptr, 0x100 / 0x100; \ temp_type current_value = *current_row++; \ difference = prev_value - current_value; \ - if(difference < 0) \ + if( difference < 0 ) \ result_temp -= difference; \ else \ result_temp += difference; \ } \ \ /* skip alpha */ \ - if(components == 4) \ - { \ + if( components == 4 ) { \ prev_row1++; \ prev_row2++; \ prev_row3++; \ @@ -913,58 +616,30 @@ int64_t MotionScan::abs_diff(unsigned char *prev_ptr, current_ptr += row_bytes; \ } \ result = (int64_t)(result_temp * multiplier); \ -} - - - +} break int64_t MotionScan::abs_diff_sub(unsigned char *prev_ptr, - unsigned char *current_ptr, - int row_bytes, - int w, - int h, - int color_model, - int sub_x, - int sub_y) + unsigned char *current_ptr, int row_bytes, + int w, int h, int color_model, int sub_x, + int sub_y) { int h_sub = h - 1; int w_sub = w - 1; int64_t result = 0; - switch(color_model) - { - case BC_RGB888: - ABS_DIFF_SUB(unsigned char, int64_t, 1, 3) - break; - case BC_RGBA8888: - ABS_DIFF_SUB(unsigned char, int64_t, 1, 4) - break; - case BC_RGB_FLOAT: - ABS_DIFF_SUB(float, double, 0x10000, 3) - break; - case BC_RGBA_FLOAT: - ABS_DIFF_SUB(float, double, 0x10000, 4) - break; - case BC_YUV888: - ABS_DIFF_SUB(unsigned char, int64_t, 1, 3) - break; - case BC_YUVA8888: - ABS_DIFF_SUB(unsigned char, int64_t, 1, 4) - break; - case BC_YUV161616: - ABS_DIFF_SUB(uint16_t, int64_t, 1, 3) - break; - case BC_YUVA16161616: - ABS_DIFF_SUB(uint16_t, int64_t, 1, 4) - break; + switch( color_model ) { + ABS_DIFF_SUB(BC_RGB888, unsigned char, int64_t, 1, 3); + ABS_DIFF_SUB(BC_RGBA8888, unsigned char, int64_t, 1, 4); + ABS_DIFF_SUB(BC_RGB_FLOAT, float, double, 0x10000, 3); + ABS_DIFF_SUB(BC_RGBA_FLOAT, float, double, 0x10000, 4); + ABS_DIFF_SUB(BC_YUV888, unsigned char, int64_t, 1, 3); + ABS_DIFF_SUB(BC_YUVA8888, unsigned char, int64_t, 1, 4); + ABS_DIFF_SUB(BC_YUV161616, uint16_t, int64_t, 1, 3); + ABS_DIFF_SUB(BC_YUVA16161616, uint16_t, int64_t, 1, 4); } return result; } - - - - MotionScanCache::MotionScanCache(int x, int y, int64_t difference) { this->x = x; @@ -972,61 +647,38 @@ MotionScanCache::MotionScanCache(int x, int y, int64_t difference) this->difference = difference; } - - -void MotionScan::clamp_scan(int w, - int h, - int *block_x1, - int *block_y1, - int *block_x2, - int *block_y2, - int *scan_x1, - int *scan_y1, - int *scan_x2, - int *scan_y2, - int use_absolute) +void MotionScan::clamp_scan(int w, int h, + int *block_x1, int *block_y1, int *block_x2, + int *block_y2, int *scan_x1, int *scan_y1, + int *scan_x2, int *scan_y2, int use_absolute) { -// printf("MotionMain::clamp_scan 1 w=%d h=%d block=%d %d %d %d scan=%d %d %d %d absolute=%d\n", -// w, -// h, -// *block_x1, -// *block_y1, -// *block_x2, -// *block_y2, -// *scan_x1, -// *scan_y1, -// *scan_x2, -// *scan_y2, +//printf("MotionMain::clamp_scan 1 w=%d h=%d block=%d %d %d %d scan=%d %d %d %d absolute=%d\n", +// w, h, *block_x1, *block_y1, *block_x2, *block_y2, *scan_x1, *scan_y1, *scan_x2, *scan_y2, // use_absolute); - if(use_absolute) - { + if( use_absolute ) { // Limit size of scan area // Used for drawing vectors // scan is always out of range before block. - if(*scan_x1 < 0) - { + if( *scan_x1 < 0 ) { // int difference = -*scan_x1; // *block_x1 += difference; *scan_x1 = 0; } - if(*scan_y1 < 0) - { + if( *scan_y1 < 0 ) { // int difference = -*scan_y1; // *block_y1 += difference; *scan_y1 = 0; } - if(*scan_x2 > w) - { + if( *scan_x2 > w ) { int difference = *scan_x2 - w; // *block_x2 -= difference; *scan_x2 -= difference; } - if(*scan_y2 > h) - { + if( *scan_y2 > h ) { int difference = *scan_y2 - h; // *block_y2 -= difference; *scan_y2 -= difference; @@ -1037,44 +689,38 @@ void MotionScan::clamp_scan(int w, CLAMP(*scan_x2, 0, w); CLAMP(*scan_y2, 0, h); } - else - { + else { // Limit range of upper left block coordinates // Used for motion tracking - if(*scan_x1 < 0) - { + if( *scan_x1 < 0 ) { int difference = -*scan_x1; // *block_x1 += difference; *scan_x2 += difference; *scan_x1 = 0; } - if(*scan_y1 < 0) - { + if( *scan_y1 < 0 ) { int difference = -*scan_y1; // *block_y1 += difference; *scan_y2 += difference; *scan_y1 = 0; } - if(*scan_x2 - *block_x1 + *block_x2 > w) - { + if( *scan_x2 - *block_x1 + *block_x2 > w ) { int difference = *scan_x2 - *block_x1 + *block_x2 - w; *scan_x2 -= difference; // *block_x2 -= difference; } - if(*scan_y2 - *block_y1 + *block_y2 > h) - { + if( *scan_y2 - *block_y1 + *block_y2 > h ) { int difference = *scan_y2 - *block_y1 + *block_y2 - h; *scan_y2 -= difference; // *block_y2 -= difference; } - -// CLAMP(*scan_x1, 0, w - (*block_x2 - *block_x1)); -// CLAMP(*scan_y1, 0, h - (*block_y2 - *block_y1)); -// CLAMP(*scan_x2, 0, w - (*block_x2 - *block_x1)); -// CLAMP(*scan_y2, 0, h - (*block_y2 - *block_y1)); +// CLAMP(*scan_x1, 0, w - (*block_x2 - *block_x1)); +// CLAMP(*scan_y1, 0, h - (*block_y2 - *block_y1)); +// CLAMP(*scan_x2, 0, w - (*block_x2 - *block_x1)); +// CLAMP(*scan_y2, 0, h - (*block_y2 - *block_y1)); } // Sanity checks which break the calculation but should never happen if the @@ -1084,19 +730,7 @@ void MotionScan::clamp_scan(int w, CLAMP(*block_y1, 0, h); CLAMP(*block_y2, 0, h); -// printf("MotionMain::clamp_scan 2 w=%d h=%d block=%d %d %d %d scan=%d %d %d %d absolute=%d\n", -// w, -// h, -// *block_x1, -// *block_y1, -// *block_x2, -// *block_y2, -// *scan_x1, -// *scan_y1, -// *scan_x2, -// *scan_y2, +//printf("MotionMain::clamp_scan 2 w=%d h=%d block=%d %d %d %d scan=%d %d %d %d absolute=%d\n", +// w, h, *block_x1, *block_y1, *block_x2, *block_y2, *scan_x1, *scan_y1, *scan_x2, *scan_y2, // use_absolute); } - - -