8f4ca53da862588728ea491d4bf1ce623160c779
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / motion-cv / motion-cv.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * Copyright (C) 2003-2016 Cinelerra CV contributors
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22
23 #ifndef MOTION_H
24 #define MOTION_H
25
26 #include <math.h>
27 #include <stdint.h>
28 #include <string.h>
29
30 #include "affine.inc"
31 #include "bchash.inc"
32 #include "filexml.inc"
33 #include "keyframe.inc"
34 #include "loadbalance.h"
35 #include "overlayframe.inc"
36 #include "pluginvclient.h"
37 #include "rotateframe.inc"
38 #include "vframe.inc"
39
40 class MotionCVMain;
41 class MotionCVWindow;
42 class MotionCVScan;
43 class RotateCVScan;
44
45
46 #define OVERSAMPLE 4
47
48
49 // Limits of global range in percent
50 #define MIN_RADIUS 1
51 #define MAX_RADIUS 50
52
53 // Limits of rotation range in degrees
54 #define MIN_ROTATION 1
55 #define MAX_ROTATION 25
56
57 // Limits of block size in percent.
58 #define MIN_BLOCK 1
59 #define MAX_BLOCK 100
60
61 // Limits of block count
62 #define MIN_BLOCKS 1
63 #define MAX_BLOCKS 200
64
65 // Precision of rotation
66 #define MIN_ANGLE 0.0001
67
68 #define TRACKING_FILE "/tmp/motion-cv"
69
70 class MotionCVConfig
71 {
72 public:
73         MotionCVConfig();
74
75         int equivalent(MotionCVConfig &that);
76         void copy_from(MotionCVConfig &that);
77         void interpolate(MotionCVConfig &prev, MotionCVConfig &next,
78                 int64_t prev_frame, int64_t next_frame, int64_t current_frame);
79         void boundaries();
80
81         int block_count;
82         int global_range_w;
83         int global_range_h;
84         int rotation_range;
85         int magnitude;
86         int return_speed;
87         int draw_vectors;
88 // Percent of image size
89         int global_block_w;
90         int global_block_h;
91         int rotation_block_w;
92         int rotation_block_h;
93 // Number of search positions in each refinement of the log search
94         int global_positions;
95         int rotate_positions;
96 // Block position in percentage 0 - 100
97         double block_x;
98         double block_y;
99
100         int horizontal_only;
101         int vertical_only;
102         int global;
103         int rotate;
104         int addtrackedframeoffset;
105         char tracking_file[BCTEXTLEN];
106 // Track or stabilize, single pixel, scan only, or nothing
107         int mode1;
108 // Recalculate, no calculate, save, or load coordinates from disk
109         int mode2;
110 // Track a single frame, previous frame, or previous frame same block
111         int mode3;
112         enum
113         {
114 // mode1
115                 TRACK,
116                 STABILIZE,
117                 TRACK_PIXEL,
118                 STABILIZE_PIXEL,
119                 NOTHING,
120 // mode2
121                 RECALCULATE,
122                 SAVE,
123                 LOAD,
124                 NO_CALCULATE,
125 // mode3
126                 TRACK_SINGLE,
127                 TRACK_PREVIOUS,
128                 PREVIOUS_SAME_BLOCK
129         };
130 // Number of single frame to track relative to timeline start
131         int64_t track_frame;
132 // Master layer
133         int bottom_is_master;
134 };
135
136
137
138
139 class MotionCVMain : public PluginVClient
140 {
141 public:
142         MotionCVMain(PluginServer *server);
143         ~MotionCVMain();
144
145         int process_buffer(VFrame **frame,
146                 int64_t start_position,
147                 double frame_rate);
148         void process_global();
149         void process_rotation();
150         void draw_vectors(VFrame *frame);
151         int is_multichannel();
152         int is_realtime();
153         void save_data(KeyFrame *keyframe);
154         void read_data(KeyFrame *keyframe);
155         void update_gui();
156 // Calculate frame to copy from and frame to move
157         void calculate_pointers(VFrame **frame, VFrame **src, VFrame **dst);
158         void allocate_temp(int w, int h, int color_model);
159
160         PLUGIN_CLASS_MEMBERS2(MotionCVConfig)
161
162
163         int64_t abs_diff(unsigned char *prev_ptr,
164                 unsigned char *current_ptr,
165                 int row_bytes,
166                 int w,
167                 int h,
168                 int color_model);
169         int64_t abs_diff_sub(unsigned char *prev_ptr,
170                 unsigned char *current_ptr,
171                 int row_bytes,
172                 int w,
173                 int h,
174                 int color_model,
175                 int sub_x,
176                 int sub_y);
177
178         static void clamp_scan(int w,
179                 int h,
180                 int *block_x1,
181                 int *block_y1,
182                 int *block_x2,
183                 int *block_y2,
184                 int *scan_x1,
185                 int *scan_y1,
186                 int *scan_x2,
187                 int *scan_y2,
188                 int use_absolute);
189         static void draw_pixel(VFrame *frame, int x, int y);
190         static void draw_line(VFrame *frame, int x1, int y1, int x2, int y2);
191         void draw_arrow(VFrame *frame, int x1, int y1, int x2, int y2);
192
193 // Number of the previous reference frame on the timeline.
194         int64_t previous_frame_number;
195 // The frame compared with the previous frame to get the motion.
196 // It is moved to compensate for motion and copied to the previous_frame.
197         VFrame *temp_frame;
198         MotionCVScan *engine;
199         RotateCVScan *motion_rotate;
200         OverlayFrame *overlayer;
201         AffineEngine *rotate_engine;
202
203 // Accumulation of all global tracks since the plugin start.
204 // Multiplied by OVERSAMPLE.
205         int total_dx;
206         int total_dy;
207
208 // Rotation motion tracking
209         float total_angle;
210
211 // Current motion vector for drawing vectors
212         int current_dx;
213         int current_dy;
214         float current_angle;
215
216         char cache_file[BCTEXTLEN];
217         FILE *cache_fp, *active_fp;
218         void reset_cache_file();
219         int open_cache_file();
220         void close_cache_file();
221         int load_cache_line();
222         int locate_cache_line(int64_t key);
223         int get_cache_line(int64_t key);
224         int put_cache_line(const char *line);
225         char cache_line[BCSTRLEN];
226         int64_t cache_key, active_key;
227 // add constant frame offset values
228         int dx_offset, dy_offset;
229         int64_t tracking_frame;
230 // save/load result values
231         int load_ok;
232         int save_dx, load_dx;
233         int save_dy, load_dy;
234         float save_dt, load_dt;
235 // Oversampled current frame for motion estimation
236         int32_t *search_area;
237         int search_size;
238
239
240 // The layer to track motion in.
241         int reference_layer;
242 // The layer to apply motion in.
243         int target_layer;
244
245 // Pointer to the source and destination of each operation.
246 // These are fully allocated buffers.
247
248 // The previous reference frame for global motion tracking
249         VFrame *prev_global_ref;
250 // The current reference frame for global motion tracking
251         VFrame *current_global_ref;
252 // The input target frame for global motion tracking
253         VFrame *global_target_src;
254 // The output target frame for global motion tracking
255         VFrame *global_target_dst;
256
257 // The previous reference frame for rotation tracking
258         VFrame *prev_rotate_ref;
259 // The current reference frame for rotation tracking
260         VFrame *current_rotate_ref;
261 // The input target frame for rotation tracking.
262         VFrame *rotate_target_src;
263 // The output target frame for rotation tracking.
264         VFrame *rotate_target_dst;
265
266 // The output of process_buffer
267         VFrame *output_frame;
268         int w;
269         int h;
270 };
271
272
273
274 class MotionCvVVFrame : public VFrame
275 {
276 public:
277         MotionCvVVFrame(VFrame *vfrm, int n);
278         int draw_pixel(int x, int y);
279         int n;
280 };
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304 class MotionCVScanPackage : public LoadPackage
305 {
306 public:
307         MotionCVScanPackage();
308
309 // For multiple blocks
310         int block_x1, block_y1, block_x2, block_y2;
311         int scan_x1, scan_y1, scan_x2, scan_y2;
312         int dx;
313         int dy;
314         int64_t max_difference;
315         int64_t min_difference;
316         int64_t min_pixel;
317         int is_border;
318         int valid;
319 // For single block
320         int pixel;
321         int64_t difference1;
322         int64_t difference2;
323 };
324
325 class MotionCVScanCache
326 {
327 public:
328         MotionCVScanCache(int x, int y, int64_t difference);
329         int x, y;
330         int64_t difference;
331 };
332
333 class MotionCVScanUnit : public LoadClient
334 {
335 public:
336         MotionCVScanUnit(MotionCVScan *server, MotionCVMain *plugin);
337         ~MotionCVScanUnit();
338
339         void process_package(LoadPackage *package);
340         int64_t get_cache(int x, int y);
341         void put_cache(int x, int y, int64_t difference);
342
343         MotionCVScan *server;
344         MotionCVMain *plugin;
345
346         ArrayList<MotionCVScanCache*> cache;
347         Mutex *cache_lock;
348 };
349
350 class MotionCVScan : public LoadServer
351 {
352 public:
353         MotionCVScan(MotionCVMain *plugin,
354                 int total_clients,
355                 int total_packages);
356         ~MotionCVScan();
357
358         friend class MotionCVScanUnit;
359
360         void init_packages();
361         LoadClient* new_client();
362         LoadPackage* new_package();
363
364 // Invoke the motion engine for a search
365 // Frame before motion
366         void scan_frame(VFrame *previous_frame,
367 // Frame after motion
368                 VFrame *current_frame);
369         int64_t get_cache(int x, int y);
370         void put_cache(int x, int y, int64_t difference);
371
372 // Change between previous frame and current frame multiplied by
373 // OVERSAMPLE
374         int dx_result;
375         int dy_result;
376
377 private:
378         VFrame *previous_frame;
379 // Frame after motion
380         VFrame *current_frame;
381         MotionCVMain *plugin;
382
383         int skip;
384 // For single block
385         int block_x1;
386         int block_x2;
387         int block_y1;
388         int block_y2;
389         int scan_x1;
390         int scan_y1;
391         int scan_x2;
392         int scan_y2;
393         int total_pixels;
394         int total_steps;
395         int subpixel;
396
397
398         ArrayList<MotionCVScanCache*> cache;
399         Mutex *cache_lock;
400 };
401
402
403
404
405
406
407
408
409
410
411
412
413
414 class RotateCVScanPackage : public LoadPackage
415 {
416 public:
417         RotateCVScanPackage();
418         float angle;
419         int64_t difference;
420 };
421
422 class RotateCVScanCache
423 {
424 public:
425         RotateCVScanCache(float angle, int64_t difference);
426         float angle;
427         int64_t difference;
428 };
429
430 class RotateCVScanUnit : public LoadClient
431 {
432 public:
433         RotateCVScanUnit(RotateCVScan *server, MotionCVMain *plugin);
434         ~RotateCVScanUnit();
435
436         void process_package(LoadPackage *package);
437
438         RotateCVScan *server;
439         MotionCVMain *plugin;
440         AffineEngine *rotater;
441         VFrame *temp;
442 };
443
444 class RotateCVScan : public LoadServer
445 {
446 public:
447         RotateCVScan(MotionCVMain *plugin,
448                 int total_clients,
449                 int total_packages);
450         ~RotateCVScan();
451
452         friend class RotateCVScanUnit;
453
454         void init_packages();
455         LoadClient* new_client();
456         LoadPackage* new_package();
457
458 // Invoke the motion engine for a search
459 // Frame before rotation
460         float scan_frame(VFrame *previous_frame,
461 // Frame after rotation
462                 VFrame *current_frame,
463 // Pivot
464                 int block_x,
465                 int block_y);
466         int64_t get_cache(float angle);
467         void put_cache(float angle, int64_t difference);
468
469
470 // Angle result
471         float result;
472
473 private:
474         VFrame *previous_frame;
475 // Frame after motion
476         VFrame *current_frame;
477
478         MotionCVMain *plugin;
479         int skip;
480
481 // Pivot
482         int block_x;
483         int block_y;
484 // Block to rotate
485         int block_x1;
486         int block_x2;
487         int block_y1;
488         int block_y2;
489 // Area to compare
490         int scan_x;
491         int scan_y;
492         int scan_w;
493         int scan_h;
494 // Range of angles to compare
495         float scan_angle1, scan_angle2;
496         int total_steps;
497
498         ArrayList<RotateCVScanCache*> cache;
499         Mutex *cache_lock;
500 };
501
502
503
504
505 #endif
506
507
508
509
510
511