apply sge motion plugin mods
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / motion / motion.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifndef MOTION_H
23 #define MOTION_H
24
25 #include <math.h>
26 #include <stdint.h>
27 #include <string.h>
28
29 #include "affine.inc"
30 #include "bchash.inc"
31 #include "filexml.inc"
32 #include "keyframe.inc"
33 #include "loadbalance.h"
34 #include "motionscan.inc"
35 #include "motionwindow.inc"
36 #include "overlayframe.inc"
37 #include "pluginvclient.h"
38 #include "rotateframe.inc"
39 #include "vframe.inc"
40
41 class MotionMain;
42 class MotionWindow;
43 class RotateScan;
44
45
46 // Limits of global range in percent
47 #define MIN_RADIUS 1
48 #define MAX_RADIUS 100
49
50 // Limits of rotation range in degrees
51 #define MIN_ROTATION 1
52 #define MAX_ROTATION 25
53
54 // Limits of block size in percent.
55 #define MIN_BLOCK 1
56 #define MAX_BLOCK 100
57
58 // Limits of block count
59 #define MIN_BLOCKS 1
60 #define MAX_BLOCKS 200
61
62 // Precision of rotation (in radian!)
63 #define MIN_ANGLE 0.0001
64
65 #define TRACKING_FILE "/tmp/motion"
66
67 class MotionConfig
68 {
69 public:
70         MotionConfig();
71
72         int equivalent(MotionConfig &that);
73         void copy_from(MotionConfig &that);
74         void interpolate(MotionConfig &prev, MotionConfig &next,
75                 int64_t prev_frame, int64_t next_frame, int64_t current_frame);
76         void boundaries();
77
78         int block_count;
79         int global_range_w;
80         int global_range_h;
81 // Range of angles above and below center rotation angle to search
82         int rotation_range;
83 // Center angle of rotation search
84         int rotation_center;
85         int magnitude;
86         int rotate_magnitude;
87         int return_speed;
88         int rotate_return_speed;
89         int draw_vectors;
90 // Percent of image size
91         int global_block_w;
92         int global_block_h;
93 //      int rotation_block_w;
94 //      int rotation_block_h;
95 // Number of search positions in each refinement of the log search
96         int global_positions;
97         int rotate_positions;
98 // Block position in percentage 0 - 100
99         double block_x;
100         double block_y;
101 // Noise levels to ignore frame differences as 0-100% of (maxdiff-mindiff)
102         double noise_level;
103         double noise_rotation;
104
105         int horizontal_only;
106         int vertical_only;
107         int global;
108         int rotate;
109         int addtrackedframeoffset;
110         char tracking_file[BCTEXTLEN];
111 // Track or stabilize, single pixel, scan only, or nothing
112         int action_type;
113 // Recalculate, no calculate, save, or load coordinates from disk
114         int tracking_type;
115 // Track a single frame, previous frame, or previous frame same block
116         int tracking_object;
117 // 1 == two pass tracking
118         int twopass;
119
120 // Number of single frame to track relative to timeline start
121         int64_t track_frame;
122 // Master layer
123         int bottom_is_master;
124 };
125
126
127 class MotionMain : public PluginVClient
128 {
129 public:
130         MotionMain(PluginServer *server);
131         ~MotionMain();
132
133         int process_buffer(VFrame **frame, int64_t start_position, double frame_rate);
134         void process_global();
135         void process_rotation();
136         void refine_global();
137         void refine_rotation();
138         void draw_vectors(VFrame *frame);
139         int is_multichannel();
140         int is_realtime();
141         void save_data(KeyFrame *keyframe);
142         void read_data(KeyFrame *keyframe);
143         void update_gui();
144 // Calculate frame to copy from and frame to move
145         void calculate_pointers(VFrame **frame, VFrame **src, VFrame **dst);
146         void allocate_temp(int w, int h, int color_model);
147
148         PLUGIN_CLASS_MEMBERS2(MotionConfig)
149
150         static void draw_pixel(VFrame *frame, int x, int y);
151         static void draw_line(VFrame *frame, int x1, int y1, int x2, int y2);
152         void draw_arrow(VFrame *frame, int x1, int y1, int x2, int y2);
153
154 // Number of the previous reference frame on the timeline.
155         int64_t previous_frame_number;
156 // The frame compared with the previous frame to get the motion.
157 // It is moved to compensate for motion and copied to the previous_frame.
158         VFrame *temp_frame;
159         MotionScan *engine;
160         RotateScan *motion_rotate;
161         OverlayFrame *overlayer;
162         AffineEngine *rotate_engine;
163
164 // Accumulation of all global tracks since the plugin start.
165 // Multiplied by OVERSAMPLE.
166         int total_dx;
167         int total_dy;
168
169 // Rotation motion tracking
170         float total_angle;
171
172 // Current motion vector for drawing vectors
173         int current_dx;
174         int current_dy;
175         float current_angle;
176
177         char cache_file[BCTEXTLEN];
178         FILE *cache_fp, *active_fp;
179         void reset_cache_file();
180         int open_cache_file();
181         void close_cache_file();
182         int load_cache_line();
183         int locate_cache_line(int64_t key);
184         int get_cache_line(int64_t key);
185         int put_cache_line(const char *line);
186         char cache_line[BCSTRLEN];
187         int64_t cache_key, active_key;
188 // add constant frame offset values
189         int dx_offset, dy_offset;
190         float dt_offset;
191         int64_t tracking_frame;
192 // save/load result values
193         int load_ok;
194         int save_dx, load_dx;
195         int save_dy, load_dy;
196         float save_dt, load_dt;
197
198 // Oversampled current frame for motion estimation
199         int32_t *search_area;
200         int search_size;
201
202
203 // The layer to track motion in.
204         int reference_layer;
205 // The layer to apply motion in.
206         int target_layer;
207
208 // Pointer to the source and destination of each operation.
209 // These are fully allocated buffers.
210
211 // The previous reference frame for global motion tracking
212         VFrame *prev_global_ref;
213 // The current reference frame for global motion tracking
214         VFrame *current_global_ref;
215 // The input target frame for global motion tracking
216         VFrame *global_target_src;
217 // The output target frame for global motion tracking
218         VFrame *global_target_dst;
219
220 // The previous reference frame for rotation tracking
221         VFrame *prev_rotate_ref;
222 // The current reference frame for rotation tracking
223         VFrame *current_rotate_ref;
224 // The input target frame for rotation tracking.
225         VFrame *rotate_target_src;
226 // The output target frame for rotation tracking.
227         VFrame *rotate_target_dst;
228
229 // The output of process_buffer
230         VFrame *output_frame;
231         int w;
232         int h;
233 };
234
235
236 class RotateScanPackage : public LoadPackage
237 {
238 public:
239         RotateScanPackage();
240         float angle;
241         int64_t difference;
242 };
243
244 class RotateScanCache
245 {
246 public:
247         RotateScanCache(float angle, int64_t difference);
248         float angle;
249         int64_t difference;
250 };
251
252 class RotateScanUnit : public LoadClient
253 {
254 public:
255         RotateScanUnit(RotateScan *server, MotionMain *plugin);
256         ~RotateScanUnit();
257
258         void process_package(LoadPackage *package);
259
260         RotateScan *server;
261         MotionMain *plugin;
262         AffineEngine *rotater;
263         VFrame *temp;
264 };
265
266 class RotateScan : public LoadServer
267 {
268 public:
269         RotateScan(MotionMain *plugin,
270                 int total_clients,
271                 int total_packages);
272         ~RotateScan();
273
274         friend class RotateScanUnit;
275
276         void init_packages();
277         LoadClient* new_client();
278         LoadPackage* new_package();
279
280 // Invoke the motion engine for a search
281 // Frame before rotation
282         float scan_frame(VFrame *previous_frame,
283 // Frame after rotation
284                 VFrame *current_frame,
285 // Pivot
286                 int block_x,
287                 int block_y,
288                 int passno);
289         int64_t get_cache(float angle);
290         void put_cache(float angle, int64_t difference);
291
292
293 // Angle result
294         float result;
295
296 private:
297         VFrame *previous_frame;
298 // Frame after motion
299         VFrame *current_frame;
300
301         MotionMain *plugin;
302         int skip;
303
304 // Pivot
305         int block_x;
306         int block_y;
307 // Block to rotate
308         int block_x1;
309         int block_x2;
310         int block_y1;
311         int block_y2;
312 // Area to compare
313         int scan_x;
314         int scan_y;
315         int scan_w;
316         int scan_h;
317 // Range of angles to compare
318         float scan_angle1, scan_angle2;
319         int total_steps;
320
321         ArrayList<RotateScanCache*> cache;
322         Mutex *cache_lock;
323 };
324
325 class MotionVVFrame : public VFrame
326 {
327 public:
328         MotionVVFrame(VFrame *vfrm, int n);
329         int draw_pixel(int x, int y);
330         int n;
331 };
332
333 #endif