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