4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "motionscan-hv.inc"
32 #include "filexml.inc"
33 #include "keyframe.inc"
34 #include "loadbalance.h"
35 #include "motionwindow.inc"
36 #include "overlayframe.inc"
37 #include "pluginvclient.h"
38 #include "rotateframe.inc"
47 #define TOTAL_POINTS 2
48 // Point 0 is used for determining translation
49 #define TRANSLATION_POINT 0
50 // Point 1 is used for determining rotation and scaling
51 #define ROTATION_POINT 1
53 // Limits of global range in percent
57 // Limits of global origin in percent
58 #define MIN_ORIGIN -50
61 // Limits of rotation range in degrees
62 #define MIN_ROTATION 1
63 #define MAX_ROTATION 25
65 // Limits of block size in percent.
69 // Limits of block count
71 #define MAX_BLOCKS 200
73 #define MOTION_FILE "/tmp/m"
74 #define ROTATION_FILE "/tmp/r"
81 int equivalent(MotionConfig &that);
82 void copy_from(MotionConfig &that);
83 void interpolate(MotionConfig &prev,
87 int64_t current_frame);
91 int global[TOTAL_POINTS];
93 int global_range_w[TOTAL_POINTS];
94 int global_range_h[TOTAL_POINTS];
95 // Search origin relative to block position -50-50
96 int global_origin_x[TOTAL_POINTS];
97 int global_origin_y[TOTAL_POINTS];
98 int draw_vectors[TOTAL_POINTS];
99 // Size of comparison block. Percent of image size
100 int global_block_w[TOTAL_POINTS];
101 int global_block_h[TOTAL_POINTS];
102 // Block position in percentage 0 - 100
103 double block_x[TOTAL_POINTS];
104 double block_y[TOTAL_POINTS];
106 // Number of search positions in each refinement of the log search
107 int global_positions;
108 // Maximum position offset
111 // Track single direction only
114 // Number of single frame to track relative to timeline start
117 int bottom_is_master;
118 // Track or stabilize, single pixel, scan only, or nothing
120 // Recalculate, no calculate, save, or load coordinates from disk
122 // Track a single frame, previous frame, or previous frame same block
129 class MotionMain2 : public PluginVClient
132 MotionMain2(PluginServer *server);
135 int process_buffer(VFrame **frame,
136 int64_t start_position,
138 void scan_motion(int point);
140 void draw_vectors(VFrame *frame, int point);
141 int is_multichannel();
143 void save_data(KeyFrame *keyframe);
144 void read_data(KeyFrame *keyframe);
146 // Calculate frame to copy from and frame to move
147 void calculate_pointers(VFrame **frame, VFrame **src, VFrame **dst);
148 void allocate_temp(int w, int h, int color_model);
150 PLUGIN_CLASS_MEMBERS(MotionConfig)
152 int64_t abs_diff(unsigned char *prev_ptr,
153 unsigned char *current_ptr,
158 int64_t abs_diff_sub(unsigned char *prev_ptr,
159 unsigned char *current_ptr,
167 static void draw_pixel(VFrame *frame, int x, int y);
168 static void draw_line(VFrame *frame, int x1, int y1, int x2, int y2);
169 void draw_arrow(VFrame *frame, int x1, int y1, int x2, int y2);
170 // Get start and end of current motion vector in pixels
171 void get_current_vector(float *origin_x,
179 // Number of the previous reference frame on the timeline.
180 int64_t previous_frame_number;
181 // The frame compared with the previous frame to get the motion.
182 // It is moved to compensate for motion and copied to the previous_frame.
185 OverlayFrame *overlayer;
186 AffineEngine *affine;
188 // Accumulation of all global tracks since the plugin start.
189 // Multiplied by OVERSAMPLE.
190 int total_dx[TOTAL_POINTS];
191 int total_dy[TOTAL_POINTS];
195 // Current motion vector for drawing vectors
196 int current_dx[TOTAL_POINTS];
197 int current_dy[TOTAL_POINTS];
201 // Oversampled current frame for motion estimation
202 int32_t *search_area;
206 // The layer to track motion in.
208 // The layer to apply motion in.
211 // Pointer to the source and destination of each operation.
212 // These are fully allocated buffers.
214 // The previous reference frame for global motion tracking
215 VFrame *prev_global_ref;
216 // The current reference frame for global motion tracking
217 VFrame *current_global_ref;
218 // The input target frame for global motion tracking
219 VFrame *global_target_src;
220 // The output target frame for global motion tracking
221 VFrame *global_target_dst;
223 // The output of process_buffer
224 VFrame *output_frame;
253 class MotionScanPackage : public LoadPackage
258 // For multiple blocks
259 int block_x1, block_y1, block_x2, block_y2;
260 int scan_x1, scan_y1, scan_x2, scan_y2;
263 int64_t max_difference;
264 int64_t min_difference;
274 class MotionScanCache
277 MotionScanCache(int x, int y, int64_t difference);
282 class MotionScanUnit : public LoadClient
285 MotionScanUnit(MotionScan *server, MotionMain2 *plugin);
288 void process_package(LoadPackage *package);
289 int64_t get_cache(int x, int y);
290 void put_cache(int x, int y, int64_t difference);
295 ArrayList<MotionScanCache*> cache;
299 class MotionScan : public LoadServer
302 MotionScan(MotionMain2 *plugin,
307 friend class MotionScanUnit;
309 void init_packages();
310 LoadClient* new_client();
311 LoadPackage* new_package();
313 // Invoke the motion engine for a search
314 // Frame before motion
315 void scan_frame(VFrame *previous_frame,
316 // Frame after motion
317 VFrame *current_frame,
320 int64_t get_cache(int x, int y);
321 void put_cache(int x, int y, int64_t difference);
323 // Change between previous frame and current frame multiplied by
329 VFrame *previous_frame;
330 // Frame after motion
331 VFrame *current_frame;
349 ArrayList<MotionScanCache*> cache;