/*
* CINELERRA
- * Copyright (C) 2016 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008 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
#define MOTIONSCAN_H
-#include "affine.inc"
+#include "arraylist.h"
+//#include "../downsample/downsampleengine.inc"
#include "loadbalance.h"
#include "vframe.inc"
#include <stdint.h>
class MotionScan;
#define OVERSAMPLE 4
-#define MOTION_FILE "/tmp/m"
-#define ROTATION_FILE "/tmp/r"
class MotionScanPackage : public LoadPackage
{
MotionScanPackage();
// For multiple blocks
-// Position of stationary block after downsampling
+// Position of stationary block
int block_x1, block_y1, block_x2, block_y2;
-// index of rotated frame
- int angle_step;
-
+// Range of positions to scan
+ int scan_x1, scan_y1, scan_x2, scan_y2;
int dx;
int dy;
int64_t max_difference;
int64_t min_pixel;
int is_border;
int valid;
+// For single block
+ int step;
int64_t difference1;
int64_t difference2;
-// Search position of current package to nearest pixel with downsampling
+// Search position to nearest pixel
int search_x;
int search_y;
// Subpixel of search position
int sub_y;
};
+class MotionScanCache
+{
+public:
+ MotionScanCache(int x, int y, int64_t difference);
+ int x, y;
+ int64_t difference;
+};
+
class MotionScanUnit : public LoadClient
{
public:
~MotionScanUnit();
void process_package(LoadPackage *package);
- void subpixel(MotionScanPackage *pkg);
- void single_pixel(MotionScanPackage *pkg);
+ int64_t get_cache(int x, int y);
+ void put_cache(int x, int y, int64_t difference);
MotionScan *server;
+
+ ArrayList<MotionScanCache*> cache;
+ Mutex *cache_lock;
};
class MotionScan : public LoadServer
void set_test_match(int value);
// Invoke the motion engine for a search
-// Frame before motion
- void scan_frame(VFrame *previous_frame,
- VFrame *current_frame,
- int global_range_w, // in pixels
- int global_range_h,
- int global_block_w, // in pixels
- int global_block_h,
- int block_x, // in pixels
- int block_y,
- int frame_type,
- int tracking_type,
- int action_type,
- int horizontal_only,
- int vertical_only,
- int source_position,
- int total_dx, // in pixels * OVERSAMPLE
- int total_dy,
- int global_origin_x, // in pixels
- int global_origin_y,
- int do_motion,
- int do_rotate,
- double rotation_center, // in deg
- double rotation_range);
-
- static int64_t abs_diff(unsigned char *prev_ptr,
- unsigned char *current_ptr,
- int row_bytes,
- int w,
- int h,
- int color_model);
- static int64_t 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);
-
-
- static void 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,
+ void scan_frame(VFrame *previous_frame, // Frame before motion
+ VFrame *current_frame, // Frame after motion
+ 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=0, int load_dx=0, int load_dy=0);
+ int64_t get_cache(int x, int y);
+ void put_cache(int x, int y, int64_t difference);
+
+ static int64_t abs_diff(unsigned char *prev_ptr, unsigned char *current_ptr,
+ int row_bytes, int w, int h, int color_model);
+ static int64_t 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);
+
+ static void 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);
// Change between previous frame and current frame multiplied by
// OVERSAMPLE
- int dx_result;
- int dy_result;
- float dr_result;
+ int dx_result, dy_result;
- enum
- {
-// action_type
+ enum { // action_type
TRACK,
STABILIZE,
TRACK_PIXEL,
NOTHING
};
- enum
- {
-// tracking_type
+ enum { // tracking_type
CALCULATE,
SAVE,
LOAD,
NO_CALCULATE
};
- enum
- {
-// frame_type
+ enum { // frame_type
TRACK_SINGLE,
TRACK_PREVIOUS,
PREVIOUS_SAME_BLOCK
};
private:
- void downsample_frame(VFrame *dst,
- VFrame *src,
- int downsample);
- void pixel_search(int &x_result, int &y_result, double &r_result);
- void subpixel_search(int &x_result, int &y_result);
- double step_to_angle(int step, double center);
-
-// double calculate_variance(unsigned char *current_ptr,
-// int row_bytes,
-// int w,
-// int h,
-// int color_model);
- double calculate_range(unsigned char *current_ptr,
- int row_bytes,
- int w,
- int h,
- int color_model);
-
-
-
- AffineEngine *rotater;
// Pointer to downsampled frame before motion
VFrame *previous_frame;
// Pointer to downsampled frame after motion
// Downsampled frames
VFrame *downsampled_previous;
VFrame *downsampled_current;
-// rotated versions of current_frame
- VFrame **rotated_current;
-// allocation of rotated_current array, a copy of angle_steps
- int total_rotated;
// Test for identical frames before processing
// Faster to skip it if the frames are usually different
int test_match;
int skip;
-// macroblocks didn't have enough data
- int failed;
// For single block
int block_x1;
int block_x2;
int block_y1;
int block_y2;
- int scan_w;
- int scan_h;
int scan_x1;
int scan_y1;
int scan_x2;
int scan_y2;
- double scan_angle1, scan_angle2;
+ int total_pixels;
+ int total_steps;
+ int edge_steps;
int y_steps;
int x_steps;
- int angle_steps;
-// in deg
- double angle_step;
int subpixel;
int horizontal_only;
int vertical_only;
int global_origin_x;
int global_origin_y;
- int action_type;
- int current_downsample;
- int downsampled_w;
- int downsampled_h;
- int total_steps;
- int do_motion;
- int do_rotate;
- int rotation_pass;
-// in deg
- double rotation_center;
- double rotation_range;
+
+ ArrayList<MotionScanCache*> cache;
+ Mutex *cache_lock;
+// DownSampleServer *downsample;
};