add xvid/flv formats, add motion plugin varients + save file, fix build bug
[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"
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         FILE *active_fp;
216         char active_file[BCTEXTLEN];
217         int get_line_key(const char *filename, int64_t key, char *line, int len);
218 // add constant frame offset values
219         int dx_offset, dy_offset;
220         int64_t tracking_frame;
221 // save/load result values
222         int save_dx, load_dx;
223         int save_dy, load_dy;
224         float save_dt, load_dt;
225
226 // Oversampled current frame for motion estimation
227         int32_t *search_area;
228         int search_size;
229
230
231 // The layer to track motion in.
232         int reference_layer;
233 // The layer to apply motion in.
234         int target_layer;
235
236 // Pointer to the source and destination of each operation.
237 // These are fully allocated buffers.
238
239 // The previous reference frame for global motion tracking
240         VFrame *prev_global_ref;
241 // The current reference frame for global motion tracking
242         VFrame *current_global_ref;
243 // The input target frame for global motion tracking
244         VFrame *global_target_src;
245 // The output target frame for global motion tracking
246         VFrame *global_target_dst;
247
248 // The previous reference frame for rotation tracking
249         VFrame *prev_rotate_ref;
250 // The current reference frame for rotation tracking
251         VFrame *current_rotate_ref;
252 // The input target frame for rotation tracking.
253         VFrame *rotate_target_src;
254 // The output target frame for rotation tracking.
255         VFrame *rotate_target_dst;
256
257 // The output of process_buffer
258         VFrame *output_frame;
259         int w;
260         int h;
261 };
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 class MotionCVScanPackage : public LoadPackage
288 {
289 public:
290         MotionCVScanPackage();
291
292 // For multiple blocks
293         int block_x1, block_y1, block_x2, block_y2;
294         int scan_x1, scan_y1, scan_x2, scan_y2;
295         int dx;
296         int dy;
297         int64_t max_difference;
298         int64_t min_difference;
299         int64_t min_pixel;
300         int is_border;
301         int valid;
302 // For single block
303         int pixel;
304         int64_t difference1;
305         int64_t difference2;
306 };
307
308 class MotionCVScanCache
309 {
310 public:
311         MotionCVScanCache(int x, int y, int64_t difference);
312         int x, y;
313         int64_t difference;
314 };
315
316 class MotionCVScanUnit : public LoadClient
317 {
318 public:
319         MotionCVScanUnit(MotionCVScan *server, MotionCVMain *plugin);
320         ~MotionCVScanUnit();
321
322         void process_package(LoadPackage *package);
323         int64_t get_cache(int x, int y);
324         void put_cache(int x, int y, int64_t difference);
325
326         MotionCVScan *server;
327         MotionCVMain *plugin;
328
329         ArrayList<MotionCVScanCache*> cache;
330         Mutex *cache_lock;
331 };
332
333 class MotionCVScan : public LoadServer
334 {
335 public:
336         MotionCVScan(MotionCVMain *plugin, 
337                 int total_clients, 
338                 int total_packages);
339         ~MotionCVScan();
340
341         friend class MotionCVScanUnit;
342
343         void init_packages();
344         LoadClient* new_client();
345         LoadPackage* new_package();
346
347 // Invoke the motion engine for a search
348 // Frame before motion
349         void scan_frame(VFrame *previous_frame,
350 // Frame after motion
351                 VFrame *current_frame);
352         int64_t get_cache(int x, int y);
353         void put_cache(int x, int y, int64_t difference);
354
355 // Change between previous frame and current frame multiplied by 
356 // OVERSAMPLE
357         int dx_result;
358         int dy_result;
359
360 private:
361         VFrame *previous_frame;
362 // Frame after motion
363         VFrame *current_frame;
364         MotionCVMain *plugin;
365
366         int skip;
367 // For single block
368         int block_x1;
369         int block_x2;
370         int block_y1;
371         int block_y2;
372         int scan_x1;
373         int scan_y1;
374         int scan_x2;
375         int scan_y2;
376         int total_pixels;
377         int total_steps;
378         int subpixel;
379
380
381         ArrayList<MotionCVScanCache*> cache;
382         Mutex *cache_lock;
383 };
384
385
386
387
388
389
390
391
392
393
394
395
396
397 class RotateCVScanPackage : public LoadPackage
398 {
399 public:
400         RotateCVScanPackage();
401         float angle;
402         int64_t difference;
403 };
404
405 class RotateCVScanCache
406 {
407 public:
408         RotateCVScanCache(float angle, int64_t difference);
409         float angle;
410         int64_t difference;
411 };
412
413 class RotateCVScanUnit : public LoadClient
414 {
415 public:
416         RotateCVScanUnit(RotateCVScan *server, MotionCVMain *plugin);
417         ~RotateCVScanUnit();
418
419         void process_package(LoadPackage *package);
420
421         RotateCVScan *server;
422         MotionCVMain *plugin;
423         AffineEngine *rotater;
424         VFrame *temp;
425 };
426
427 class RotateCVScan : public LoadServer
428 {
429 public:
430         RotateCVScan(MotionCVMain *plugin, 
431                 int total_clients, 
432                 int total_packages);
433         ~RotateCVScan();
434
435         friend class RotateCVScanUnit;
436
437         void init_packages();
438         LoadClient* new_client();
439         LoadPackage* new_package();
440
441 // Invoke the motion engine for a search
442 // Frame before rotation
443         float scan_frame(VFrame *previous_frame,
444 // Frame after rotation
445                 VFrame *current_frame,
446 // Pivot
447                 int block_x,
448                 int block_y);
449         int64_t get_cache(float angle);
450         void put_cache(float angle, int64_t difference);
451
452
453 // Angle result
454         float result;
455
456 private:
457         VFrame *previous_frame;
458 // Frame after motion
459         VFrame *current_frame;
460
461         MotionCVMain *plugin;
462         int skip;
463
464 // Pivot
465         int block_x;
466         int block_y;
467 // Block to rotate
468         int block_x1;
469         int block_x2;
470         int block_y1;
471         int block_y2;
472 // Area to compare
473         int scan_x;
474         int scan_y;
475         int scan_w;
476         int scan_h;
477 // Range of angles to compare
478         float scan_angle1, scan_angle2;
479         int total_steps;
480
481         ArrayList<RotateCVScanCache*> cache;
482         Mutex *cache_lock;
483 };
484
485
486
487
488 #endif
489
490
491
492
493
494