e0011d751171bc8707ee32361650a65692c25a47
[goodguy/history.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
47
48 // Limits of global range in percent
49 #define MIN_RADIUS 1
50 #define MAX_RADIUS 100
51
52 // Limits of rotation range in degrees
53 #define MIN_ROTATION 1
54 #define MAX_ROTATION 25
55
56 // Limits of block size in percent.
57 #define MIN_BLOCK 1
58 #define MAX_BLOCK 100
59
60 // Limits of block count
61 #define MIN_BLOCKS 1
62 #define MAX_BLOCKS 200
63
64 // Precision of rotation
65 #define MIN_ANGLE 0.0001
66
67 #define ROTATION_FILE "/tmp/r"
68
69 class MotionConfig
70 {
71 public:
72         MotionConfig();
73
74         int equivalent(MotionConfig &that);
75         void copy_from(MotionConfig &that);
76         void interpolate(MotionConfig &prev,
77                 MotionConfig &next,
78                 int64_t prev_frame,
79                 int64_t next_frame,
80                 int64_t current_frame);
81         void boundaries();
82         void set_cpus(int cpus);
83
84         int block_count;
85         int global_range_w;
86         int global_range_h;
87 // Range of angles above and below center rotation angle to search
88         int rotation_range;
89 // Center angle of rotation search
90         int rotation_center;
91         int magnitude;
92         int rotate_magnitude;
93         int return_speed;
94         int rotate_return_speed;
95         int draw_vectors;
96 // Percent of image size
97         int global_block_w;
98         int global_block_h;
99 //      int rotation_block_w;
100 //      int rotation_block_h;
101 // Number of search positions in each refinement of the log search
102         int global_positions;
103         int rotate_positions;
104 // Block position in percentage 0 - 100
105         double block_x;
106         double block_y;
107
108         int horizontal_only;
109         int vertical_only;
110         int global;
111         int rotate;
112         int addtrackedframeoffset;
113 // Track or stabilize, single pixel, scan only, or nothing
114         int action_type;
115 // Recalculate, no calculate, save, or load coordinates from disk
116         int tracking_type;
117 // Track a single frame, previous frame, or previous frame same block
118         int tracking_object;
119
120 #if 0
121         enum
122         {
123 // action_type
124                 TRACK,
125                 STABILIZE,
126                 TRACK_PIXEL,
127                 STABILIZE_PIXEL,
128                 NOTHING,
129 // mode2
130                 RECALCULATE,
131                 SAVE,
132                 LOAD,
133                 NO_CALCULATE,
134 // tracking_object
135                 TRACK_SINGLE,
136                 TRACK_PREVIOUS,
137                 PREVIOUS_SAME_BLOCK
138         };
139 #endif
140
141
142 // Number of single frame to track relative to timeline start
143         int64_t track_frame;
144 // Master layer
145         int bottom_is_master;
146 };
147
148
149
150
151 class MotionMain : public PluginVClient
152 {
153 public:
154         MotionMain(PluginServer *server);
155         ~MotionMain();
156
157         int process_buffer(VFrame **frame,
158                 int64_t start_position,
159                 double frame_rate);
160         void process_global();
161         void process_rotation();
162         void draw_vectors(VFrame *frame);
163         int is_multichannel();
164         int is_realtime();
165         void save_data(KeyFrame *keyframe);
166         void read_data(KeyFrame *keyframe);
167         void update_gui();
168 // Calculate frame to copy from and frame to move
169         void calculate_pointers(VFrame **frame, VFrame **src, VFrame **dst);
170         void allocate_temp(int w, int h, int color_model);
171
172         PLUGIN_CLASS_MEMBERS2(MotionConfig)
173
174
175         static void draw_pixel(VFrame *frame, int x, int y);
176         static void draw_line(VFrame *frame, int x1, int y1, int x2, int y2);
177         void draw_arrow(VFrame *frame, int x1, int y1, int x2, int y2);
178
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.
183         VFrame *temp_frame;
184         MotionScan *engine;
185         RotateScan *motion_rotate;
186         OverlayFrame *overlayer;
187         AffineEngine *rotate_engine;
188
189 // Accumulation of all global tracks since the plugin start.
190 // Multiplied by OVERSAMPLE.
191         int total_dx;
192         int total_dy;
193
194 // Rotation motion tracking
195         float total_angle;
196
197 // Current motion vector for drawing vectors
198         int current_dx;
199         int current_dy;
200         float current_angle;
201
202
203
204 // Oversampled current frame for motion estimation
205         int32_t *search_area;
206         int search_size;
207
208
209 // The layer to track motion in.
210         int reference_layer;
211 // The layer to apply motion in.
212         int target_layer;
213
214 // Pointer to the source and destination of each operation.
215 // These are fully allocated buffers.
216
217 // The previous reference frame for global motion tracking
218         VFrame *prev_global_ref;
219 // The current reference frame for global motion tracking
220         VFrame *current_global_ref;
221 // The input target frame for global motion tracking
222         VFrame *global_target_src;
223 // The output target frame for global motion tracking
224         VFrame *global_target_dst;
225
226 // The previous reference frame for rotation tracking
227         VFrame *prev_rotate_ref;
228 // The current reference frame for rotation tracking
229         VFrame *current_rotate_ref;
230 // The input target frame for rotation tracking.
231         VFrame *rotate_target_src;
232 // The output target frame for rotation tracking.
233         VFrame *rotate_target_dst;
234
235 // The output of process_buffer
236         VFrame *output_frame;
237         int w;
238         int h;
239 };
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264 class RotateScanPackage : public LoadPackage
265 {
266 public:
267         RotateScanPackage();
268         float angle;
269         int64_t difference;
270 };
271
272 class RotateScanCache
273 {
274 public:
275         RotateScanCache(float angle, int64_t difference);
276         float angle;
277         int64_t difference;
278 };
279
280 class RotateScanUnit : public LoadClient
281 {
282 public:
283         RotateScanUnit(RotateScan *server, MotionMain *plugin);
284         ~RotateScanUnit();
285
286         void process_package(LoadPackage *package);
287
288         RotateScan *server;
289         MotionMain *plugin;
290         AffineEngine *rotater;
291         VFrame *temp;
292 };
293
294 class RotateScan : public LoadServer
295 {
296 public:
297         RotateScan(MotionMain *plugin,
298                 int total_clients,
299                 int total_packages);
300         ~RotateScan();
301
302         friend class RotateScanUnit;
303
304         void init_packages();
305         LoadClient* new_client();
306         LoadPackage* new_package();
307
308 // Invoke the motion engine for a search
309 // Frame before rotation
310         float scan_frame(VFrame *previous_frame,
311 // Frame after rotation
312                 VFrame *current_frame,
313 // Pivot
314                 int block_x,
315                 int block_y);
316         int64_t get_cache(float angle);
317         void put_cache(float angle, int64_t difference);
318
319
320 // Angle result
321         float result;
322
323 private:
324         VFrame *previous_frame;
325 // Frame after motion
326         VFrame *current_frame;
327
328         MotionMain *plugin;
329         int skip;
330
331 // Pivot
332         int block_x;
333         int block_y;
334 // Block to rotate
335         int block_x1;
336         int block_x2;
337         int block_y1;
338         int block_y2;
339 // Area to compare
340         int scan_x;
341         int scan_y;
342         int scan_w;
343         int scan_h;
344 // Range of angles to compare
345         float scan_angle1, scan_angle2;
346         int total_steps;
347
348         ArrayList<RotateScanCache*> cache;
349         Mutex *cache_lock;
350 };
351
352
353
354
355 #endif
356
357
358
359
360
361