motion draw_vectors using VFrame draw_pixel brush
[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 // 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
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
102         int horizontal_only;
103         int vertical_only;
104         int global;
105         int rotate;
106         int addtrackedframeoffset;
107         char tracking_file[BCTEXTLEN];
108 // Track or stabilize, single pixel, scan only, or nothing
109         int action_type;
110 // Recalculate, no calculate, save, or load coordinates from disk
111         int tracking_type;
112 // Track a single frame, previous frame, or previous frame same block
113         int tracking_object;
114
115 // Number of single frame to track relative to timeline start
116         int64_t track_frame;
117 // Master layer
118         int bottom_is_master;
119 };
120
121
122 class MotionMain : public PluginVClient
123 {
124 public:
125         MotionMain(PluginServer *server);
126         ~MotionMain();
127
128         int process_buffer(VFrame **frame, int64_t start_position, double frame_rate);
129         void process_global();
130         void process_rotation();
131         void draw_vectors(VFrame *frame);
132         int is_multichannel();
133         int is_realtime();
134         void save_data(KeyFrame *keyframe);
135         void read_data(KeyFrame *keyframe);
136         void update_gui();
137 // Calculate frame to copy from and frame to move
138         void calculate_pointers(VFrame **frame, VFrame **src, VFrame **dst);
139         void allocate_temp(int w, int h, int color_model);
140
141         PLUGIN_CLASS_MEMBERS2(MotionConfig)
142
143         static void draw_pixel(VFrame *frame, int x, int y);
144         static void draw_line(VFrame *frame, int x1, int y1, int x2, int y2);
145         void draw_arrow(VFrame *frame, int x1, int y1, int x2, int y2);
146
147 // Number of the previous reference frame on the timeline.
148         int64_t previous_frame_number;
149 // The frame compared with the previous frame to get the motion.
150 // It is moved to compensate for motion and copied to the previous_frame.
151         VFrame *temp_frame;
152         MotionScan *engine;
153         RotateScan *motion_rotate;
154         OverlayFrame *overlayer;
155         AffineEngine *rotate_engine;
156
157 // Accumulation of all global tracks since the plugin start.
158 // Multiplied by OVERSAMPLE.
159         int total_dx;
160         int total_dy;
161
162 // Rotation motion tracking
163         float total_angle;
164
165 // Current motion vector for drawing vectors
166         int current_dx;
167         int current_dy;
168         float current_angle;
169
170         char cache_file[BCTEXTLEN];
171         FILE *cache_fp, *active_fp;
172         void reset_cache_file();
173         int open_cache_file();
174         void close_cache_file();
175         int load_cache_line();
176         int locate_cache_line(int64_t key);
177         int get_cache_line(int64_t key);
178         int put_cache_line(const char *line);
179         char cache_line[BCSTRLEN];
180         int64_t cache_key, active_key;
181 // add constant frame offset values
182         int dx_offset, dy_offset;
183         int64_t tracking_frame;
184 // save/load result values
185         int load_ok;
186         int save_dx, load_dx;
187         int save_dy, load_dy;
188         float save_dt, load_dt;
189
190 // Oversampled current frame for motion estimation
191         int32_t *search_area;
192         int search_size;
193
194
195 // The layer to track motion in.
196         int reference_layer;
197 // The layer to apply motion in.
198         int target_layer;
199
200 // Pointer to the source and destination of each operation.
201 // These are fully allocated buffers.
202
203 // The previous reference frame for global motion tracking
204         VFrame *prev_global_ref;
205 // The current reference frame for global motion tracking
206         VFrame *current_global_ref;
207 // The input target frame for global motion tracking
208         VFrame *global_target_src;
209 // The output target frame for global motion tracking
210         VFrame *global_target_dst;
211
212 // The previous reference frame for rotation tracking
213         VFrame *prev_rotate_ref;
214 // The current reference frame for rotation tracking
215         VFrame *current_rotate_ref;
216 // The input target frame for rotation tracking.
217         VFrame *rotate_target_src;
218 // The output target frame for rotation tracking.
219         VFrame *rotate_target_dst;
220
221 // The output of process_buffer
222         VFrame *output_frame;
223         int w;
224         int h;
225 };
226
227
228 class RotateScanPackage : public LoadPackage
229 {
230 public:
231         RotateScanPackage();
232         float angle;
233         int64_t difference;
234 };
235
236 class RotateScanCache
237 {
238 public:
239         RotateScanCache(float angle, int64_t difference);
240         float angle;
241         int64_t difference;
242 };
243
244 class RotateScanUnit : public LoadClient
245 {
246 public:
247         RotateScanUnit(RotateScan *server, MotionMain *plugin);
248         ~RotateScanUnit();
249
250         void process_package(LoadPackage *package);
251
252         RotateScan *server;
253         MotionMain *plugin;
254         AffineEngine *rotater;
255         VFrame *temp;
256 };
257
258 class RotateScan : public LoadServer
259 {
260 public:
261         RotateScan(MotionMain *plugin,
262                 int total_clients,
263                 int total_packages);
264         ~RotateScan();
265
266         friend class RotateScanUnit;
267
268         void init_packages();
269         LoadClient* new_client();
270         LoadPackage* new_package();
271
272 // Invoke the motion engine for a search
273 // Frame before rotation
274         float scan_frame(VFrame *previous_frame,
275 // Frame after rotation
276                 VFrame *current_frame,
277 // Pivot
278                 int block_x,
279                 int block_y);
280         int64_t get_cache(float angle);
281         void put_cache(float angle, int64_t difference);
282
283
284 // Angle result
285         float result;
286
287 private:
288         VFrame *previous_frame;
289 // Frame after motion
290         VFrame *current_frame;
291
292         MotionMain *plugin;
293         int skip;
294
295 // Pivot
296         int block_x;
297         int block_y;
298 // Block to rotate
299         int block_x1;
300         int block_x2;
301         int block_y1;
302         int block_y2;
303 // Area to compare
304         int scan_x;
305         int scan_y;
306         int scan_w;
307         int scan_h;
308 // Range of angles to compare
309         float scan_angle1, scan_angle2;
310         int total_steps;
311
312         ArrayList<RotateScanCache*> cache;
313         Mutex *cache_lock;
314 };
315
316 class MotionVVFrame : public VFrame
317 {
318 public:
319         MotionVVFrame(VFrame *vfrm, int n);
320         int draw_pixel(int x, int y);
321         int n;
322 };
323
324 #endif