/*
* CINELERRA
* Copyright (C) 2012 Adam Williams <broadcast at earthling dot net>
- *
+ *
* 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"
// The module which does the actual scanning
-
-
-
-
MotionScanPackage::MotionScanPackage()
: LoadPackage()
{
valid = 1;
}
-
-
-
-
-
MotionScanUnit::MotionScanUnit(MotionScan *server)
: LoadClient(server)
{
delete cache_lock;
}
-
-
void MotionScanUnit::process_package(LoadPackage *package)
{
MotionScanPackage *pkg = (MotionScanPackage*)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",
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;
}
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");
// 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);
}
}
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;
// 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;
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;
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();
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
// 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;
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,
// 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;
}
}
}
-
- 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;
}
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++; \
} \
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 + \
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++; \
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;
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;
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
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);
}
-
-
-