igor ru.po
[goodguy/history.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
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295 class MotionCVScanPackage : public LoadPackage
296 {
297 public:
298         MotionCVScanPackage();
299
300 // For multiple blocks
301         int block_x1, block_y1, block_x2, block_y2;
302         int scan_x1, scan_y1, scan_x2, scan_y2;
303         int dx;
304         int dy;
305         int64_t max_difference;
306         int64_t min_difference;
307         int64_t min_pixel;
308         int is_border;
309         int valid;
310 // For single block
311         int pixel;
312         int64_t difference1;
313         int64_t difference2;
314 };
315
316 class MotionCVScanCache
317 {
318 public:
319         MotionCVScanCache(int x, int y, int64_t difference);
320         int x, y;
321         int64_t difference;
322 };
323
324 class MotionCVScanUnit : public LoadClient
325 {
326 public:
327         MotionCVScanUnit(MotionCVScan *server, MotionCVMain *plugin);
328         ~MotionCVScanUnit();
329
330         void process_package(LoadPackage *package);
331         int64_t get_cache(int x, int y);
332         void put_cache(int x, int y, int64_t difference);
333
334         MotionCVScan *server;
335         MotionCVMain *plugin;
336
337         ArrayList<MotionCVScanCache*> cache;
338         Mutex *cache_lock;
339 };
340
341 class MotionCVScan : public LoadServer
342 {
343 public:
344         MotionCVScan(MotionCVMain *plugin,
345                 int total_clients,
346                 int total_packages);
347         ~MotionCVScan();
348
349         friend class MotionCVScanUnit;
350
351         void init_packages();
352         LoadClient* new_client();
353         LoadPackage* new_package();
354
355 // Invoke the motion engine for a search
356 // Frame before motion
357         void scan_frame(VFrame *previous_frame,
358 // Frame after motion
359                 VFrame *current_frame);
360         int64_t get_cache(int x, int y);
361         void put_cache(int x, int y, int64_t difference);
362
363 // Change between previous frame and current frame multiplied by
364 // OVERSAMPLE
365         int dx_result;
366         int dy_result;
367
368 private:
369         VFrame *previous_frame;
370 // Frame after motion
371         VFrame *current_frame;
372         MotionCVMain *plugin;
373
374         int skip;
375 // For single block
376         int block_x1;
377         int block_x2;
378         int block_y1;
379         int block_y2;
380         int scan_x1;
381         int scan_y1;
382         int scan_x2;
383         int scan_y2;
384         int total_pixels;
385         int total_steps;
386         int subpixel;
387
388
389         ArrayList<MotionCVScanCache*> cache;
390         Mutex *cache_lock;
391 };
392
393
394
395
396
397
398
399
400
401
402
403
404
405 class RotateCVScanPackage : public LoadPackage
406 {
407 public:
408         RotateCVScanPackage();
409         float angle;
410         int64_t difference;
411 };
412
413 class RotateCVScanCache
414 {
415 public:
416         RotateCVScanCache(float angle, int64_t difference);
417         float angle;
418         int64_t difference;
419 };
420
421 class RotateCVScanUnit : public LoadClient
422 {
423 public:
424         RotateCVScanUnit(RotateCVScan *server, MotionCVMain *plugin);
425         ~RotateCVScanUnit();
426
427         void process_package(LoadPackage *package);
428
429         RotateCVScan *server;
430         MotionCVMain *plugin;
431         AffineEngine *rotater;
432         VFrame *temp;
433 };
434
435 class RotateCVScan : public LoadServer
436 {
437 public:
438         RotateCVScan(MotionCVMain *plugin,
439                 int total_clients,
440                 int total_packages);
441         ~RotateCVScan();
442
443         friend class RotateCVScanUnit;
444
445         void init_packages();
446         LoadClient* new_client();
447         LoadPackage* new_package();
448
449 // Invoke the motion engine for a search
450 // Frame before rotation
451         float scan_frame(VFrame *previous_frame,
452 // Frame after rotation
453                 VFrame *current_frame,
454 // Pivot
455                 int block_x,
456                 int block_y);
457         int64_t get_cache(float angle);
458         void put_cache(float angle, int64_t difference);
459
460
461 // Angle result
462         float result;
463
464 private:
465         VFrame *previous_frame;
466 // Frame after motion
467         VFrame *current_frame;
468
469         MotionCVMain *plugin;
470         int skip;
471
472 // Pivot
473         int block_x;
474         int block_y;
475 // Block to rotate
476         int block_x1;
477         int block_x2;
478         int block_y1;
479         int block_y2;
480 // Area to compare
481         int scan_x;
482         int scan_y;
483         int scan_w;
484         int scan_h;
485 // Range of angles to compare
486         float scan_angle1, scan_angle2;
487         int total_steps;
488
489         ArrayList<RotateCVScanCache*> cache;
490         Mutex *cache_lock;
491 };
492
493
494
495
496 #endif
497
498
499
500
501
502